|
| 1 | +import { useRef, useState, FunctionComponent } from 'react'; |
| 2 | +import { |
| 3 | + AlertGroup, |
| 4 | + Alert, |
| 5 | + Button, |
| 6 | + Form, |
| 7 | + FormGroup, |
| 8 | + FormHelperText, |
| 9 | + FormAlert, |
| 10 | + FormGroupLabelHelp, |
| 11 | + FormSelect, |
| 12 | + FormSelectOption, |
| 13 | + HelperText, |
| 14 | + HelperTextItem, |
| 15 | + List, |
| 16 | + ListItem, |
| 17 | + TextInput, |
| 18 | + Popover, |
| 19 | + ActionGroup |
| 20 | +} from '../..'; |
| 21 | + |
| 22 | +interface Props { |
| 23 | + onClose: () => void; |
| 24 | +} |
| 25 | + |
| 26 | +export const AnimationsCreateDatabaseForm: FunctionComponent<Props> = ({ onClose }) => { |
| 27 | + // State variables |
| 28 | + const [name, setName] = useState(''); |
| 29 | + const [email, setEmail] = useState(''); |
| 30 | + const [version, setVersion] = useState(''); |
| 31 | + const [selectedTimeZone, setSelectedTimeZone] = useState(''); |
| 32 | + const [password, setPassword] = useState(''); |
| 33 | + // Submit state variables |
| 34 | + const [isSuccess, setIsSuccess] = useState(false); |
| 35 | + const [actionCompleted, setActionCompleted] = useState(false); |
| 36 | + |
| 37 | + const labelHelpRef = useRef(null); |
| 38 | + |
| 39 | + // Re-introducing the type alias for validation status |
| 40 | + type validationStatus = 'success' | 'warning' | 'error' | 'default'; |
| 41 | + |
| 42 | + // Reverting useState to infer the type as a generic string |
| 43 | + const [isNameValid, setIsNameValid] = useState('default'); |
| 44 | + const [isPasswordValid, setIsPasswordValid] = useState('default'); |
| 45 | + const [isEmailValid, setIsEmailValid] = useState('default'); |
| 46 | + const [isTimeZoneValid, setIsTimeZoneValid] = useState('default'); |
| 47 | + const [errorMessages, setErrorMessages] = useState([]); |
| 48 | + |
| 49 | + const handleNameChange = (_event: React.FormEvent<HTMLInputElement>, name: string) => { |
| 50 | + setName(name); |
| 51 | + }; |
| 52 | + |
| 53 | + const handleEmailChange = (_event: React.FormEvent<HTMLInputElement>, email: string) => { |
| 54 | + setEmail(email); |
| 55 | + }; |
| 56 | + |
| 57 | + const handleVersionChange = (_event: React.FormEvent<HTMLInputElement>, version: string) => { |
| 58 | + setVersion(version); |
| 59 | + }; |
| 60 | + |
| 61 | + const handlePasswordChange = (_event: React.FormEvent<HTMLInputElement>, password: string) => { |
| 62 | + setPassword(password); |
| 63 | + }; |
| 64 | + |
| 65 | + const handleTimeZoneChange = (event: React.FormEvent<HTMLSelectElement>, value: string) => { |
| 66 | + setSelectedTimeZone(value); |
| 67 | + }; |
| 68 | + |
| 69 | + const validateName = (value: string) => /^[a-z0-9-]+$/.test(value) && value.length > 0; |
| 70 | + const validatePassword = (value: string) => value.length >= 12 && /[0-9]/.test(value) && /[A-Z]/.test(value); |
| 71 | + const validateEmail = (value: string) => value.includes('@'); |
| 72 | + const validateTimeZone = (value: string) => value !== ''; |
| 73 | + |
| 74 | + const handleNameBlur = () => { |
| 75 | + setIsNameValid(validateName(name) ? 'success' : 'error'); |
| 76 | + }; |
| 77 | + |
| 78 | + const handlePasswordBlur = () => { |
| 79 | + setIsPasswordValid(validatePassword(password) ? 'success' : 'error'); |
| 80 | + }; |
| 81 | + |
| 82 | + const handleEmailBlur = () => { |
| 83 | + setIsEmailValid(validateEmail(email) ? 'success' : 'error'); |
| 84 | + }; |
| 85 | + |
| 86 | + const handleTimeZoneBlur = () => { |
| 87 | + setIsTimeZoneValid(validateTimeZone(selectedTimeZone) ? 'success' : 'error'); |
| 88 | + }; |
| 89 | + |
| 90 | + const handleSubmit = () => { |
| 91 | + const isNameCurrentValid = validateName(name); |
| 92 | + const isPasswordCurrentValid = validatePassword(password); |
| 93 | + const isEmailCurrentValid = validateEmail(email); |
| 94 | + const isTimeZoneCurrentValid = validateTimeZone(selectedTimeZone); |
| 95 | + |
| 96 | + setIsNameValid(isNameCurrentValid ? 'success' : 'error'); |
| 97 | + setIsPasswordValid(isPasswordCurrentValid ? 'success' : 'error'); |
| 98 | + setIsEmailValid(isEmailCurrentValid ? 'success' : 'error'); |
| 99 | + setIsTimeZoneValid(isTimeZoneCurrentValid ? 'success' : 'error'); |
| 100 | + |
| 101 | + const allFieldsValid = |
| 102 | + isNameCurrentValid && isPasswordCurrentValid && isEmailCurrentValid && isTimeZoneCurrentValid; |
| 103 | + |
| 104 | + setActionCompleted(true); |
| 105 | + setIsSuccess(allFieldsValid); |
| 106 | + if (allFieldsValid) { |
| 107 | + setErrorMessages([]); |
| 108 | + setTimeout(() => { |
| 109 | + setActionCompleted(false); |
| 110 | + setIsSuccess(false); |
| 111 | + }, 5000); |
| 112 | + } else { |
| 113 | + const errors: string[] = []; |
| 114 | + if (!isNameCurrentValid) { |
| 115 | + errors.push('Database instance name'); |
| 116 | + } |
| 117 | + if (!isPasswordCurrentValid) { |
| 118 | + errors.push('Admin password'); |
| 119 | + } |
| 120 | + if (!isEmailCurrentValid) { |
| 121 | + errors.push('Admin email'); |
| 122 | + } |
| 123 | + if (!isTimeZoneCurrentValid) { |
| 124 | + errors.push('Time zone'); |
| 125 | + } |
| 126 | + setErrorMessages(errors); |
| 127 | + setTimeout(() => { |
| 128 | + setActionCompleted(false); |
| 129 | + setIsSuccess(false); |
| 130 | + }, 5000); |
| 131 | + } |
| 132 | + }; |
| 133 | + |
| 134 | + return ( |
| 135 | + <Form isWidthLimited> |
| 136 | + {actionCompleted && |
| 137 | + (isSuccess ? ( |
| 138 | + <FormAlert> |
| 139 | + <AlertGroup hasAnimations isLiveRegion> |
| 140 | + <Alert |
| 141 | + variant="success" |
| 142 | + title="Successfully created database" |
| 143 | + isInline |
| 144 | + timeout={4000} |
| 145 | + timeoutAnimation={4000} |
| 146 | + /> |
| 147 | + </AlertGroup> |
| 148 | + </FormAlert> |
| 149 | + ) : ( |
| 150 | + <FormAlert> |
| 151 | + <AlertGroup hasAnimations isLiveRegion> |
| 152 | + <Alert |
| 153 | + variant="danger" |
| 154 | + title="Failed to create database. Please ensure all fields are filled out correctly." |
| 155 | + isInline |
| 156 | + timeout={3000} |
| 157 | + timeoutAnimation={3000} |
| 158 | + > |
| 159 | + <List isPlain> |
| 160 | + {errorMessages.map((error) => ( |
| 161 | + <ListItem key={error}>{error}</ListItem> |
| 162 | + ))} |
| 163 | + </List> |
| 164 | + </Alert> |
| 165 | + </AlertGroup> |
| 166 | + </FormAlert> |
| 167 | + ))} |
| 168 | + <FormGroup |
| 169 | + label="Database instance name" |
| 170 | + labelHelp={ |
| 171 | + <Popover |
| 172 | + triggerRef={labelHelpRef} |
| 173 | + headerContent={<div>The name of your database</div>} |
| 174 | + bodyContent={ |
| 175 | + <div> |
| 176 | + <p> |
| 177 | + The name of your database is used to identify it in the system. It must be unique and cannot be |
| 178 | + changed later. |
| 179 | + </p> |
| 180 | + </div> |
| 181 | + } |
| 182 | + > |
| 183 | + <FormGroupLabelHelp ref={labelHelpRef} aria-label="More info for name field" /> |
| 184 | + </Popover> |
| 185 | + } |
| 186 | + isRequired |
| 187 | + fieldId="simple-form-name-01" |
| 188 | + > |
| 189 | + <TextInput |
| 190 | + isRequired |
| 191 | + type="text" |
| 192 | + id="simple-form-name-01" |
| 193 | + name="simple-form-name-01" |
| 194 | + aria-describedby="simple-form-name-01-helper" |
| 195 | + value={name} |
| 196 | + onChange={handleNameChange} |
| 197 | + onBlur={handleNameBlur} |
| 198 | + validated={isNameValid as validationStatus} |
| 199 | + /> |
| 200 | + {isNameValid === 'error' && ( |
| 201 | + <FormHelperText> |
| 202 | + <HelperText> |
| 203 | + <HelperTextItem variant={isNameValid as validationStatus}> |
| 204 | + Must contain only lowercase letters, numbers, and hyphens. |
| 205 | + </HelperTextItem> |
| 206 | + </HelperText> |
| 207 | + </FormHelperText> |
| 208 | + )} |
| 209 | + </FormGroup> |
| 210 | + <FormGroup label="Admin email" isRequired fieldId="simple-form-email-01"> |
| 211 | + <TextInput |
| 212 | + isRequired |
| 213 | + type="email" |
| 214 | + id="simple-form-email-01" |
| 215 | + name="simple-form-email-01" |
| 216 | + value={email} |
| 217 | + onChange={handleEmailChange} |
| 218 | + onBlur={handleEmailBlur} |
| 219 | + validated={isEmailValid as validationStatus} |
| 220 | + /> |
| 221 | + {isEmailValid === 'error' && ( |
| 222 | + <FormHelperText> |
| 223 | + <HelperText> |
| 224 | + <HelperTextItem variant={isEmailValid as validationStatus}> |
| 225 | + Must be a valid email address containing an @ symbol. |
| 226 | + </HelperTextItem> |
| 227 | + </HelperText> |
| 228 | + </FormHelperText> |
| 229 | + )} |
| 230 | + </FormGroup> |
| 231 | + <FormGroup label="Database version" fieldId="simple-form-version-01"> |
| 232 | + <TextInput |
| 233 | + type="text" |
| 234 | + id="simple-form-version-01" |
| 235 | + name="simple-form-version-01" |
| 236 | + placeholder="e.g. 12c" |
| 237 | + value={version} |
| 238 | + onChange={handleVersionChange} |
| 239 | + /> |
| 240 | + </FormGroup> |
| 241 | + <FormGroup isRequired label="Time zone" fieldId="timezone-select"> |
| 242 | + <FormSelect |
| 243 | + id="timezone-select" |
| 244 | + value={selectedTimeZone} |
| 245 | + onChange={handleTimeZoneChange} |
| 246 | + aria-label="Select time zone" |
| 247 | + onBlur={handleTimeZoneBlur} |
| 248 | + validated={isTimeZoneValid as validationStatus} |
| 249 | + > |
| 250 | + <FormSelectOption isPlaceholder value="" label="Select a time zone" /> |
| 251 | + <FormSelectOption value="Eastern" label="Eastern" /> |
| 252 | + <FormSelectOption value="Central" label="Central" /> |
| 253 | + <FormSelectOption value="Pacific" label="Pacific" /> |
| 254 | + </FormSelect> |
| 255 | + {isTimeZoneValid === 'error' && ( |
| 256 | + <FormHelperText> |
| 257 | + <HelperText> |
| 258 | + <HelperTextItem variant={isTimeZoneValid as validationStatus}>Please select a time zone</HelperTextItem> |
| 259 | + </HelperText> |
| 260 | + </FormHelperText> |
| 261 | + )} |
| 262 | + </FormGroup> |
| 263 | + <FormGroup label="Admin password" isRequired fieldId="simple-form-password-01"> |
| 264 | + <TextInput |
| 265 | + isRequired |
| 266 | + type="password" |
| 267 | + id="simple-form-password-01" |
| 268 | + name="simple-form-password-01" |
| 269 | + value={password} |
| 270 | + onChange={handlePasswordChange} |
| 271 | + onBlur={handlePasswordBlur} |
| 272 | + validated={isPasswordValid as validationStatus} |
| 273 | + /> |
| 274 | + {isPasswordValid === 'error' && ( |
| 275 | + <FormHelperText> |
| 276 | + <HelperText> |
| 277 | + <HelperTextItem variant={isPasswordValid as validationStatus}> |
| 278 | + Password must be at least 12 characters and include one uppercase letter and one number. |
| 279 | + </HelperTextItem> |
| 280 | + </HelperText> |
| 281 | + </FormHelperText> |
| 282 | + )} |
| 283 | + </FormGroup> |
| 284 | + <ActionGroup> |
| 285 | + <Button variant="primary" onClick={handleSubmit}> |
| 286 | + Submit |
| 287 | + </Button> |
| 288 | + <Button variant="link" onClick={onClose}> |
| 289 | + Cancel |
| 290 | + </Button> |
| 291 | + </ActionGroup> |
| 292 | + </Form> |
| 293 | + ); |
| 294 | +}; |
0 commit comments