|
1 | | -import PropTypes from 'prop-types'; |
2 | | -import React from 'react'; |
| 1 | +import React, { useMemo, useState } from 'react'; |
3 | 2 | import { Helmet } from 'react-helmet'; |
4 | | -import { withTranslation } from 'react-i18next'; |
5 | | -import { connect } from 'react-redux'; |
6 | | -import { bindActionCreators } from 'redux'; |
7 | | -import * as CollectionsActions from '../../IDE/actions/collections'; |
| 3 | +import { useTranslation } from 'react-i18next'; |
| 4 | +import { useDispatch } from 'react-redux'; |
8 | 5 |
|
9 | 6 | import { generateCollectionName } from '../../../utils/generateRandomName'; |
10 | 7 | import Button from '../../../common/Button'; |
| 8 | +import { createCollection } from '../../IDE/actions/collections'; |
11 | 9 |
|
12 | | -class CollectionCreate extends React.Component { |
13 | | - constructor() { |
14 | | - super(); |
| 10 | +const CollectionCreate = () => { |
| 11 | + const generatedCollectionName = useMemo(() => generateCollectionName(), []); |
15 | 12 |
|
16 | | - const name = generateCollectionName(); |
| 13 | + const [name, setName] = useState(generatedCollectionName); |
| 14 | + const [description, setDescription] = useState(''); |
17 | 15 |
|
18 | | - this.state = { |
19 | | - generatedCollectionName: name, |
20 | | - collection: { |
21 | | - name, |
22 | | - description: '' |
23 | | - } |
24 | | - }; |
25 | | - } |
| 16 | + // TODO: error is never set! |
| 17 | + // eslint-disable-next-line no-unused-vars |
| 18 | + const [creationError, setCreationError] = useState(); |
26 | 19 |
|
27 | | - getTitle() { |
28 | | - return this.props.t('CollectionCreate.Title'); |
29 | | - } |
| 20 | + const { t } = useTranslation(); |
30 | 21 |
|
31 | | - handleTextChange = (field) => (evt) => { |
32 | | - this.setState({ |
33 | | - collection: { |
34 | | - ...this.state.collection, |
35 | | - [field]: evt.target.value |
36 | | - } |
37 | | - }); |
38 | | - }; |
| 22 | + const dispatch = useDispatch(); |
39 | 23 |
|
40 | | - handleCreateCollection = (event) => { |
| 24 | + const handleCreateCollection = (event) => { |
41 | 25 | event.preventDefault(); |
42 | 26 |
|
43 | | - this.props.createCollection(this.state.collection); |
| 27 | + dispatch(createCollection({ name, description })); |
44 | 28 | }; |
45 | 29 |
|
46 | | - render() { |
47 | | - const { generatedCollectionName, creationError } = this.state; |
48 | | - const { name, description } = this.state.collection; |
49 | | - |
50 | | - const invalid = name === '' || name == null; |
| 30 | + const invalid = name === '' || name == null; |
51 | 31 |
|
52 | | - return ( |
53 | | - <div className="collection-create"> |
54 | | - <Helmet> |
55 | | - <title>{this.getTitle()}</title> |
56 | | - </Helmet> |
57 | | - <div className="sketches-table-container"> |
58 | | - <form className="form" onSubmit={this.handleCreateCollection}> |
59 | | - {creationError && ( |
| 32 | + return ( |
| 33 | + <div className="collection-create"> |
| 34 | + <Helmet> |
| 35 | + <title>{t('CollectionCreate.Title')}</title> |
| 36 | + </Helmet> |
| 37 | + <div className="sketches-table-container"> |
| 38 | + <form className="form" onSubmit={handleCreateCollection}> |
| 39 | + {creationError && ( |
| 40 | + <span className="form-error"> |
| 41 | + {t('CollectionCreate.FormError')} |
| 42 | + </span> |
| 43 | + )} |
| 44 | + <p className="form__field"> |
| 45 | + <label htmlFor="name" className="form__label"> |
| 46 | + {t('CollectionCreate.FormLabel')} |
| 47 | + </label> |
| 48 | + <input |
| 49 | + className="form__input" |
| 50 | + aria-label={t('CollectionCreate.FormLabelARIA')} |
| 51 | + type="text" |
| 52 | + id="name" |
| 53 | + value={name} |
| 54 | + placeholder={generatedCollectionName} |
| 55 | + onChange={(e) => setName(e.target.value)} |
| 56 | + /> |
| 57 | + {invalid && ( |
60 | 58 | <span className="form-error"> |
61 | | - {this.props.t('CollectionCreate.FormError')} |
| 59 | + {t('CollectionCreate.NameRequired')} |
62 | 60 | </span> |
63 | 61 | )} |
64 | | - <p className="form__field"> |
65 | | - <label htmlFor="name" className="form__label"> |
66 | | - {this.props.t('CollectionCreate.FormLabel')} |
67 | | - </label> |
68 | | - <input |
69 | | - className="form__input" |
70 | | - aria-label={this.props.t('CollectionCreate.FormLabelARIA')} |
71 | | - type="text" |
72 | | - id="name" |
73 | | - value={name} |
74 | | - placeholder={generatedCollectionName} |
75 | | - onChange={this.handleTextChange('name')} |
76 | | - /> |
77 | | - {invalid && ( |
78 | | - <span className="form-error"> |
79 | | - {this.props.t('CollectionCreate.NameRequired')} |
80 | | - </span> |
81 | | - )} |
82 | | - </p> |
83 | | - <p className="form__field"> |
84 | | - <label htmlFor="description" className="form__label"> |
85 | | - {this.props.t('CollectionCreate.Description')} |
86 | | - </label> |
87 | | - <textarea |
88 | | - className="form__input form__input-flexible-height" |
89 | | - aria-label={this.props.t('CollectionCreate.DescriptionARIA')} |
90 | | - type="text" |
91 | | - id="description" |
92 | | - value={description} |
93 | | - onChange={this.handleTextChange('description')} |
94 | | - placeholder={this.props.t( |
95 | | - 'CollectionCreate.DescriptionPlaceholder' |
96 | | - )} |
97 | | - rows="4" |
98 | | - /> |
99 | | - </p> |
100 | | - <Button type="submit" disabled={invalid}> |
101 | | - {this.props.t('CollectionCreate.SubmitCollectionCreate')} |
102 | | - </Button> |
103 | | - </form> |
104 | | - </div> |
| 62 | + </p> |
| 63 | + <p className="form__field"> |
| 64 | + <label htmlFor="description" className="form__label"> |
| 65 | + {t('CollectionCreate.Description')} |
| 66 | + </label> |
| 67 | + <textarea |
| 68 | + className="form__input form__input-flexible-height" |
| 69 | + aria-label={t('CollectionCreate.DescriptionARIA')} |
| 70 | + id="description" |
| 71 | + value={description} |
| 72 | + onChange={(e) => setDescription(e.target.value)} |
| 73 | + placeholder={t('CollectionCreate.DescriptionPlaceholder')} |
| 74 | + rows="4" |
| 75 | + /> |
| 76 | + </p> |
| 77 | + <Button type="submit" disabled={invalid}> |
| 78 | + {t('CollectionCreate.SubmitCollectionCreate')} |
| 79 | + </Button> |
| 80 | + </form> |
105 | 81 | </div> |
106 | | - ); |
107 | | - } |
108 | | -} |
109 | | - |
110 | | -CollectionCreate.propTypes = { |
111 | | - user: PropTypes.shape({ |
112 | | - username: PropTypes.string, |
113 | | - authenticated: PropTypes.bool.isRequired |
114 | | - }).isRequired, |
115 | | - createCollection: PropTypes.func.isRequired, |
116 | | - t: PropTypes.func.isRequired |
| 82 | + </div> |
| 83 | + ); |
117 | 84 | }; |
118 | 85 |
|
119 | | -function mapStateToProps(state, ownProps) { |
120 | | - return { |
121 | | - user: state.user |
122 | | - }; |
123 | | -} |
124 | | - |
125 | | -function mapDispatchToProps(dispatch) { |
126 | | - return bindActionCreators(Object.assign({}, CollectionsActions), dispatch); |
127 | | -} |
128 | | - |
129 | | -export default withTranslation()( |
130 | | - connect(mapStateToProps, mapDispatchToProps)(CollectionCreate) |
131 | | -); |
| 86 | +export default CollectionCreate; |
0 commit comments