1
|
|
|
import React, { useState } from 'react'; |
2
|
|
|
import PropTypes from 'prop-types'; |
3
|
|
|
import { Modal, ModalBody, ModalFooter, ModalHeader, FormGroup, Input, UncontrolledTooltip } from 'reactstrap'; |
4
|
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; |
5
|
|
|
import { faInfoCircle as infoIcon } from '@fortawesome/free-solid-svg-icons'; |
6
|
|
|
import { ExternalLink } from 'react-external-link'; |
7
|
|
|
import moment from 'moment'; |
8
|
|
|
import { isEmpty, pipe } from 'ramda'; |
9
|
|
|
import { shortUrlType } from '../reducers/shortUrlsList'; |
10
|
|
|
import { shortUrlEditMetaType } from '../reducers/shortUrlMeta'; |
11
|
|
|
import DateInput from '../../utils/DateInput'; |
12
|
|
|
import { formatIsoDate } from '../../utils/helpers/date'; |
13
|
|
|
|
14
|
1 |
|
const propTypes = { |
15
|
|
|
isOpen: PropTypes.bool.isRequired, |
16
|
|
|
toggle: PropTypes.func.isRequired, |
17
|
|
|
shortUrl: shortUrlType.isRequired, |
18
|
|
|
shortUrlMeta: shortUrlEditMetaType, |
19
|
|
|
editShortUrlMeta: PropTypes.func, |
20
|
|
|
resetShortUrlMeta: PropTypes.func, |
21
|
|
|
}; |
22
|
|
|
|
23
|
1 |
|
const dateOrUndefined = (shortUrl, dateName) => { |
24
|
16 |
|
const date = shortUrl && shortUrl.meta && shortUrl.meta[dateName]; |
25
|
|
|
|
26
|
16 |
|
return date && moment(date); |
27
|
|
|
}; |
28
|
|
|
|
29
|
1 |
|
const EditMetaModal = ({ isOpen, toggle, shortUrl, shortUrlMeta, editShortUrlMeta, resetShortUrlMeta }) => { |
30
|
8 |
|
const { saving, error } = shortUrlMeta; |
31
|
8 |
|
const url = shortUrl && (shortUrl.shortUrl || ''); |
32
|
8 |
|
const [ validSince, setValidSince ] = useState(dateOrUndefined(shortUrl, 'validSince')); |
33
|
8 |
|
const [ validUntil, setValidUntil ] = useState(dateOrUndefined(shortUrl, 'validUntil')); |
34
|
8 |
|
const [ maxVisits, setMaxVisits ] = useState(shortUrl && shortUrl.meta && shortUrl.meta.maxVisits); |
35
|
|
|
|
36
|
8 |
|
const close = pipe(resetShortUrlMeta, toggle); |
37
|
8 |
|
const doEdit = () => editShortUrlMeta(shortUrl.shortCode, shortUrl.domain, { |
38
|
|
|
maxVisits: maxVisits && !isEmpty(maxVisits) ? parseInt(maxVisits) : null, |
39
|
|
|
validSince: validSince && formatIsoDate(validSince), |
40
|
|
|
validUntil: validUntil && formatIsoDate(validUntil), |
41
|
|
|
}).then(close); |
42
|
|
|
|
43
|
8 |
|
return ( |
44
|
|
|
<Modal isOpen={isOpen} toggle={close} centered> |
45
|
|
|
<ModalHeader toggle={close}> |
46
|
|
|
<FontAwesomeIcon icon={infoIcon} id="metaTitleInfo" /> Edit metadata for <ExternalLink href={url} /> |
47
|
|
|
<UncontrolledTooltip target="metaTitleInfo" placement="bottom"> |
48
|
|
|
<p>Using these metadata properties, you can limit when and how many times your short URL can be visited.</p> |
49
|
|
|
<p>If any of the params is not met, the URL will behave as if it was an invalid short URL.</p> |
50
|
|
|
</UncontrolledTooltip> |
51
|
|
|
</ModalHeader> |
52
|
2 |
|
<form onSubmit={(e) => e.preventDefault() || doEdit()}> |
53
|
|
|
<ModalBody> |
54
|
|
|
<FormGroup> |
55
|
|
|
<DateInput |
56
|
|
|
placeholderText="Enabled since..." |
57
|
|
|
selected={validSince} |
58
|
|
|
maxDate={validUntil} |
59
|
|
|
isClearable |
60
|
|
|
onChange={setValidSince} |
61
|
|
|
/> |
62
|
|
|
</FormGroup> |
63
|
|
|
<FormGroup> |
64
|
|
|
<DateInput |
65
|
|
|
placeholderText="Enabled until..." |
66
|
|
|
selected={validUntil} |
67
|
|
|
minDate={validSince} |
68
|
|
|
isClearable |
69
|
|
|
onChange={setValidUntil} |
70
|
|
|
/> |
71
|
|
|
</FormGroup> |
72
|
|
|
<FormGroup className="mb-0"> |
73
|
|
|
<Input |
74
|
|
|
type="number" |
75
|
|
|
placeholder="Maximum number of visits allowed" |
76
|
|
|
min={1} |
77
|
|
|
value={maxVisits || ''} |
78
|
|
|
onChange={(e) => setMaxVisits(e.target.value)} |
79
|
|
|
/> |
80
|
|
|
</FormGroup> |
81
|
|
|
{error && ( |
82
|
|
|
<div className="p-2 mt-2 bg-danger text-white text-center"> |
83
|
|
|
Something went wrong while saving the metadata :( |
84
|
|
|
</div> |
85
|
|
|
)} |
86
|
|
|
</ModalBody> |
87
|
|
|
<ModalFooter> |
88
|
|
|
<button className="btn btn-link" type="button" onClick={close}>Cancel</button> |
89
|
|
|
<button className="btn btn-primary" type="submit" disabled={saving}>{saving ? 'Saving...' : 'Save'}</button> |
90
|
|
|
</ModalFooter> |
91
|
|
|
</form> |
92
|
|
|
</Modal> |
93
|
|
|
); |
94
|
|
|
}; |
95
|
|
|
|
96
|
1 |
|
EditMetaModal.propTypes = propTypes; |
97
|
|
|
|
98
|
|
|
export default EditMetaModal; |
99
|
|
|
|