Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SRCT
go
Commits
4e8fff95
Commit
4e8fff95
authored
Feb 18, 2019
by
David Haynes
🙆
Browse files
Full lifecycle of submitting Go Links complete
- add expirations - client + server side validation - AirBNB date picker
parent
99a56fb7
Pipeline
#3946
passed with stage
in 1 minute and 13 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
go/go_ahead/src/Components/Molecules/NewGoLinkValidator.js
View file @
4e8fff95
import
*
as
Yup
from
"
yup
"
;
var
today
=
new
Date
();
var
tomorrow
=
new
Date
();
tomorrow
.
setDate
(
today
.
getDate
()
+
1
);
import
moment
from
"
moment
"
;
const
NewGoLinkValidator
=
Yup
.
object
().
shape
({
targetURL
:
Yup
.
string
()
...
...
@@ -11,7 +8,15 @@ const NewGoLinkValidator = Yup.object().shape({
.
max
(
1000
,
"
URL is too long!
"
),
shortcode
:
Yup
.
string
()
.
required
(
"
You must submit a shortcode!
"
)
.
max
(
20
,
"
Your shortcode is too long!
"
)
.
max
(
20
,
"
Your shortcode is too long!
"
),
expires
:
Yup
.
date
()
.
nullable
()
.
min
(
moment
(
new
Date
())
.
add
(
1
,
"
days
"
)
.
format
(),
"
You cannot expire your Go link on that day.
"
)
});
export
default
NewGoLinkValidator
;
go/go_ahead/src/Components/Organisms/NewGoLinkForm.jsx
View file @
4e8fff95
import
React
,
{
useState
}
from
"
react
"
;
import
React
,
{
useState
,
useEffect
}
from
"
react
"
;
import
NewGoLinkValidator
from
"
../Molecules/NewGoLinkValidator
"
;
import
{
Formik
,
Field
,
Form
}
from
"
formik
"
;
import
{
GetCSRFToken
}
from
"
../../Utils/GetCSRFToken
"
;
import
GetCSRFToken
from
"
../../Utils/GetCSRFToken
"
;
import
{
SingleDatePicker
}
from
"
react-dates
"
;
import
ParseAPIErrors
from
"
../../Utils/ParseAPIErrors
"
;
import
moment
from
"
moment
"
;
import
{
FormGroup
,
...
...
@@ -27,38 +28,64 @@ const style2 = {
const
NewGoLinkForm
=
props
=>
{
const
[
focused
,
setFocused
]
=
useState
(
false
);
const
[
expiresFieldDisabled
,
setexpiresFieldDisabled
]
=
useState
(
true
);
var
today
=
new
Date
();
var
tomorrow
=
new
Date
();
tomorrow
.
setDate
(
today
.
getDate
()
+
1
);
const
toggleExpiresField
=
()
=>
{
setexpiresFieldDisabled
(
!
expiresFieldDisabled
);
};
return
(
<
Formik
//
//
Init our form with some blank values
initialValues
=
{
{
shortcode
:
""
,
targetURL
:
""
// willExpire: false,
// expires="Never"
// expires: moment(tomorrow)
targetURL
:
""
,
expires
:
moment
(
tomorrow
)
// You must set a default date to start with
}
}
//
//
Yup client side validation
validationSchema
=
{
NewGoLinkValidator
}
//
onSubmit
=
{
({
targetURL
},
{
setSubmitting
,
setFieldError
})
=>
{
console
.
log
(
"
submitting..
"
);
console
.
log
(
targetURL
);
// Handle form submission
onSubmit
=
{
(
{
targetURL
,
shortcode
,
expires
},
{
setSubmitting
,
setErrors
}
)
=>
{
if
(
expiresFieldDisabled
)
{
expires
=
null
;
}
else
{
expires
=
expires
.
format
();
}
const
APISubmission
=
{
destination
:
targetURL
,
short
:
shortcode
,
date_expires
:
expires
};
fetch
(
"
/api/golinks/
"
,
{
method
:
"
post
"
,
headers
:
{
"
Content-Type
"
:
"
application/json
"
,
"
X-CSRFToken
"
:
GetCSRFToken
()
},
body
:
JSON
.
stringify
(
APISubmission
)
}).
then
(
response
=>
{
response
.
json
().
then
(
body
=>
{
if
(
!
response
.
ok
)
{
console
.
log
(
body
);
const
parsedAPIErrors
=
ParseAPIErrors
(
body
);
setErrors
(
parsedAPIErrors
);
}
else
{
props
.
history
.
push
(
"
/debug
"
);
}
});
});
setSubmitting
(
false
);
}
}
//
render
=
{
({
values
,
isSubmitting
,
setFieldValue
,
errors
,
touched
,
handleBlur
,
handleChange
})
=>
(
// Render out our form
render
=
{
({
values
,
isSubmitting
,
setFieldValue
,
errors
})
=>
(
<
Form
>
<
Row
>
<
Col
md
=
"12"
>
...
...
@@ -125,14 +152,42 @@ const NewGoLinkForm = props => {
type
=
"checkbox"
className
=
"custom-control-input"
id
=
"customCheck1"
onChange
=
{
toggleExpiresField
}
/>
<
label
className
=
"custom-control-label"
f
or
=
"customCheck1"
>
<
label
className
=
"custom-control-label"
htmlF
or
=
"customCheck1"
>
Expire my Go link.
</
label
>
</
div
>
</
Col
>
</
Row
>
<
Row
>
<
Col
>
<
FormGroup
>
<
Label
className
=
"mt-3"
htmlFor
=
"expires"
>
Date of Expiration
</
Label
>
{
"
"
}
<
br
/>
<
SingleDatePicker
date
=
{
values
[
"
expires
"
]
}
// momentPropTypes.momentObj or null
onDateChange
=
{
date
=>
setFieldValue
(
"
expires
"
,
date
)
}
// PropTypes.func.isRequired
focused
=
{
focused
}
// PropTypes.bool
onFocusChange
=
{
({
focused
})
=>
setFocused
(
focused
)
}
// PropTypes.func.isRequired
id
=
"expires"
// PropTypes.string.isRequired,
disabled
=
{
expiresFieldDisabled
}
readOnly
=
{
true
}
showDefaultInputIcon
=
{
true
}
numberOfMonths
=
{
1
}
/>
<
FormText
>
You cannot expire Go links on the same day (or before) they
are created.
</
FormText
>
{
errors
.
expires
?
<
div
>
{
errors
.
expires
}
</
div
>
:
null
}
</
FormGroup
>
</
Col
>
</
Row
>
<
legend
/>
<
Row
>
...
...
@@ -158,10 +213,10 @@ const NewGoLinkForm = props => {
<
div
className
=
"custom-control custom-checkbox"
>
<
input
type
=
"checkbox"
class
=
"custom-control-input"
id
=
"customCheck1"
class
Name
=
"custom-control-input"
disabled
=
{
true
}
/>
<
label
className
=
"custom-control-label"
for
=
"customCheck1"
>
<
label
className
=
"custom-control-label"
>
Require GMU login.
</
label
>
</
div
>
...
...
@@ -196,10 +251,10 @@ const NewGoLinkForm = props => {
<
div
className
=
"custom-control custom-checkbox"
>
<
input
type
=
"checkbox"
class
=
"custom-control-input"
id
=
"customCheck1"
class
Name
=
"custom-control-input"
disabled
=
{
true
}
/>
<
label
className
=
"custom-control-label"
for
=
"customCheck1"
>
<
label
className
=
"custom-control-label"
>
Self destruct my Go link.
</
label
>
</
div
>
...
...
go/go_ahead/src/Components/Pages/NewGoLinkPage.jsx
View file @
4e8fff95
...
...
@@ -5,7 +5,7 @@ import { Row, Col } from "reactstrap";
const
NewGoLinkPage
=
props
=>
{
return
(
<
AuthedPageTemplate
>
<
AuthedPageTemplate
{
...
props
}
>
<
Row
>
<
Col
>
<
h2
className
=
"mt-4 font-weight-light"
>
Create a new Go link
</
h2
>
...
...
@@ -20,7 +20,7 @@ const NewGoLinkPage = props => {
<
legend
/>
</
Col
>
</
Row
>
<
NewGolinkForm
/>
<
NewGolinkForm
{
...
props
}
/>
</
AuthedPageTemplate
>
);
};
...
...
go/go_ahead/src/Utils/ParseAPIErrors.js
0 → 100644
View file @
4e8fff95
/**
*
* const APISubmission = {
destination: targetURL,
short: shortcode,
date_expires: expires
};
* Bind API errors on field submissions to local Formik fields.
* @param {object} apiResponse
*/
const
ParseAPIErrors
=
apiResponse
=>
{
const
parsedAPIErrors
=
{};
if
(
apiResponse
.
short
)
{
if
(
apiResponse
.
short
.
length
>
0
)
{
parsedAPIErrors
.
shortcode
=
apiResponse
.
short
[
0
];
}
else
{
parsedAPIErrors
.
shortcode
=
apiResponse
.
short
;
}
}
if
(
apiResponse
.
destination
)
{
parsedAPIErrors
.
targetURL
=
apiResponse
.
targetURL
;
}
if
(
apiResponse
.
date_expires
)
{
parsedAPIErrors
.
expires
=
apiResponse
.
date_expires
;
}
return
parsedAPIErrors
;
};
export
default
ParseAPIErrors
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment