react-hook-form#Controller JavaScript Examples

The following examples show how to use react-hook-form#Controller. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TagSelector.jsx    From tinkerun with MIT License 6 votes vote down vote up
TagSelector = () => {
  const {control} = useFormContext()

  return (
    <Controller
      name='tag'
      control={control}
      defaultValue='local'
      render={({
        field: {value, onChange},
      }) =>
        <Select
          height={majorScale(3)}
          value={value}
          onChange={e => onChange(e.target.value)}
        >
          <option value="local">local</option>
          <option value="testing">testing</option>
          <option value="development">development</option>
          <option value="staging">staging</option>
          <option value="production">production</option>
        </Select>
      }
    />
  )
}
Example #2
Source File: DocumentForm.jsx    From saasgear with MIT License 6 votes vote down vote up
DocumentForm = ({
  editorContent,
  onSubmit,
  register,
  control,
  formErrors,
  apiError,
  isSubmitting,
}) => (
  <form onSubmit={onSubmit}>
    <FormGroup>
      <FormGroupLabel>Name</FormGroupLabel>
      <Input name="name" ref={register} />
      {formErrors?.name && <ErrorText message={formErrors.name.message} />}
    </FormGroup>
    <FormGroup>
      <FormGroupLabel>Body</FormGroupLabel>
      <Controller
        name="body"
        control={control}
        defaultValue=""
        render={({ onChange }) => (
          <WYSIWYGEditor editorContent={editorContent} onChange={onChange} />
        )}
      />
      {formErrors?.body && <ErrorText message={formErrors.body.message} />}
    </FormGroup>
    {apiError && <ErrorText message={apiError} />}

    <ButtonGroup>
      <SaveBtn color="primary" type="submit" disabled={isSubmitting}>
        {isSubmitting ? 'Please wait' : 'Save'}
      </SaveBtn>
    </ButtonGroup>
  </form>
)
Example #3
Source File: index.js    From hook-form-mui with MIT License 6 votes vote down vote up
function FormCheckBox(props) {
  const { control } = useFormContext();
  const { name, label } = props;
  return (
    <React.Fragment>
      <Controller
        as={MuiCheckbox}
        name={name}
        control={control}
        defaultValue={false}
        label={label}
        {...props}
      />
    </React.Fragment>
  );
}
Example #4
Source File: OverSSHButton.jsx    From tinkerun with MIT License 6 votes vote down vote up
OverSSHButton = props => {
  const {control} = useFormContext()

  return (
    <Controller
      name='is_over_ssh'
      control={control}
      defaultValue={false}
      render={({
        field: {value, onChange},
      }) => (
        <Button
          height={majorScale(3)}
          onClick={() => onChange(!value)}
          isActive={value}
          {...props}
        >
          <FormattedMessage id='connections.over_ssh'/>
        </Button>
      )}
    />
  )
}
Example #5
Source File: FileInput.js    From ultimate-react-hook-form-form with MIT License 6 votes vote down vote up
FileInput = ({ control, name }) => {
  const styles = useStyles();

  return (
    <Controller
      control={control}
      name={name}
      defaultValue={[]}
      render={({ onChange, onBlur, value }) => (
        <>
          <Dropzone onDrop={onChange}>
            {({ getRootProps, getInputProps }) => (
              <Paper
                variant="outlined"
                className={styles.root}
                {...getRootProps()}
              >
                <CloudUpload className={styles.icon} />
                <input {...getInputProps()} name={name} onBlur={onBlur} />
                <p>Drag 'n' drop files here, or click to select files</p>
              </Paper>
            )}
          </Dropzone>
          <List>
            {value.map((f, index) => (
              <ListItem key={index}>
                <ListItemIcon>
                  <InsertDriveFile />
                </ListItemIcon>
                <ListItemText primary={f.name} secondary={f.size} />
              </ListItem>
            ))}
          </List>
        </>
      )}
    />
  );
}
Example #6
Source File: CreateTopicEditor.js    From remotebond-remote-jobs with Creative Commons Zero v1.0 Universal 6 votes vote down vote up
CreateTopicEditor = ({
  control,
  inputError,
  modules,
  formats,
  inputName,
}) => {
  return (
    <Controller
      name={inputName}
      control={control}
      render={(props) => {
        return (
          <QuillNoSSRWrapper
            modules={modules}
            value={props.value}
            onChange={props.onChange}
            formats={formats}
            theme="snow"
            className={`mt-1 form-input border ${
              !inputError.description
                ? "border-gray-300 focus:border-blue-300"
                : "border-red-300 focus:border-red-300"
            }  rounded-md shadow-sm`}
          />
        )
      }}
    />
  )
}
Example #7
Source File: index.js    From plataforma-sabia with MIT License 5 votes vote down vote up
Editor = ({ config, form, name, disabled, onChange, defaultValue, renderWithController }) => {
	const { control, setValue } = form;

	if (renderWithController) {
		return (
			<Controller
				name={name}
				render={({ field }) => (
					<CKEditor
						// eslint-disable-next-line react/jsx-props-no-spreading
						{...field}
						editor={ClassicEditor}
						config={config}
						onChange={(_, editor) => {
							const editorData = editor.getData();

							if (onChange) {
								onChange(editorData);
							}

							return field.onChange(editorData);
						}}
						data={defaultValue}
					/>
				)}
				control={control}
				disabled={disabled}
			/>
		);
	}

	let timerOnChange = null;

	const handleChangeDebounced = (_, editor) => {
		clearTimeout(timerOnChange);
		timerOnChange = setTimeout(() => {
			const editorData = editor.getData();

			setValue(name, editorData, { shouldDirty: true });

			if (onChange) {
				onChange(editorData);
			}
		}, 500);
	};

	return (
		<CKEditor
			editor={ClassicEditor}
			config={config}
			name={name}
			onChange={handleChangeDebounced}
			data={defaultValue}
		/>
	);
}
Example #8
Source File: Input.js    From ponce-tournois-mario-kart with MIT License 5 votes vote down vote up
Input = React.forwardRef(
    (
        {
            children,
            name,
            validationSchema,
            label,
            type,
            defaultValue,
            ...rest
        },
        ref
    ) => {
        const { register, errors, control } = useFormContext();

        return (
            <div className="inputWrapper">
                {label && <label className="inputLabel">{label}</label>}
                {type === 'checkbox' ? (
                    <Checkbox
                        name={name}
                        validationSchema={validationSchema}
                        ref={ref}
                        {...rest}
                    />
                ) : (
                    <Controller
                        name={name}
                        control={control}
                        defaultValue={defaultValue}
                        render={(field) => (
                            <input
                                name={name}
                                ref={mergeRefs([
                                    register(validationSchema),
                                    ref,
                                ])}
                                className={errors[name] ? 'inputInvalid' : ''}
                                type={type}
                                defaultValue={defaultValue}
                                min={validationSchema?.min?.value}
                                max={validationSchema?.max?.value}
                                onChange={(e) => {
                                    let { value, min, max } = e.target;

                                    if (type === 'number' && value) {
                                        value = Math.max(
                                            Number(min),
                                            Math.min(Number(max), Number(value))
                                        );
                                    }

                                    field.onChange(value);
                                }}
                                {...rest}
                            />
                        )}
                    />
                )}

                {children}
                {errors[name] && errors[name].message && (
                    <div className="inputErrorMessage">
                        {errors[name].message}
                    </div>
                )}
            </div>
        );
    }
)
Example #9
Source File: DeploymentNameModal.js    From akashlytics-deploy with GNU General Public License v3.0 5 votes vote down vote up
DeploymentNameModal = ({ dseq, onClose, onSaved, getDeploymentName }) => {
  const classes = useStyles();
  const formRef = useRef();
  const { enqueueSnackbar } = useSnackbar();
  const { handleSubmit, control, setValue } = useForm({
    defaultValues: {
      name: ""
    }
  });

  useEffect(() => {
    if (dseq) {
      const name = getDeploymentName(dseq);
      setValue("name", name || "");
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [dseq, getDeploymentName]);

  const onSaveClick = (event) => {
    event.preventDefault();
    formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
  };

  function onSubmit({ name }) {
    updateDeploymentLocalData(dseq, { name: name });

    enqueueSnackbar(<Snackbar title="Success!" iconVariant="success" />, { variant: "success", autoHideDuration: 1000 });

    onSaved();
  }

  return (
    <Dialog open={!!dseq} onClose={onClose} maxWidth="xs" fullWidth>
      <DialogTitle>Change Deployment Name {dseq ? `(${dseq})` : ""}</DialogTitle>
      <DialogContent dividers className={classes.dialogContent}>
        <form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
          <FormControl fullWidth>
            <Controller
              control={control}
              name="name"
              render={({ field }) => {
                return <TextField {...field} autoFocus type="text" variant="outlined" label="Name" />;
              }}
            />
          </FormControl>
        </form>
      </DialogContent>
      <DialogActions className={classes.dialogActions}>
        <Button onClick={onClose}>Close</Button>
        <Button variant="contained" color="primary" onClick={onSaveClick}>
          Save
        </Button>
      </DialogActions>
    </Dialog>
  );
}
Example #10
Source File: reactHookForm.jsx    From intergalactic with MIT License 4 votes vote down vote up
export default function App() {
  const { register, handleSubmit, control, errors } = useForm({
    mode: 'onBlur',
    shouldFocusError: false,
  });

  const inputMaskRef = useRef(null);
  const [filter, updateFilterValue] = useState('');
  const [option, updateOption] = useState(listActuallyCountryCodes['Russia']);
  const [value, updateValue] = useState(option.dial_code);
  const [valueMask, updateValueMask] = useState(`${option.dial_code} (___)___-____`);
  const [valueInput, setValueInput] = useState('');
  const [valueBigInput, setValueBigInput] = useState('');
  const [valueDate, setValueDate] = useState('');
  const [valueTime, setValueTime] = useState('');
  const [tags, updateTags] = useState(['vk', 'fk', 'twitter', 'instagram']);
  const [valueTag, updateValueTag] = useState('');
  const [valueSelect, setValueSelect] = useState(null);
  const [valueRadio, setValueRadio] = useState('');
  const [checked, setChecked] = useState(false);

  let country;

  const options = selectOptions.map((option) => ({
    value: option,
    children: option,
  }));

  useEffect(() => {
    updateValueMask(`${option.dial_code} (___)___-____`);
  }, [option]);

  useEffect(() => {
    if (value === valueMask) {
      const position = getAfterPositionValue(value);
      inputMaskRef?.current.setSelectionRange(position, position);
    }
  }, [value, valueMask]);

  const handleAppendTags = (newTags) => {
    updateTags((tags) => [...tags, ...newTags]);
    updateValueTag('');
  };
  const handleRemoveTag = () => {
    if (tags.length === 0) return;
    updateTags(tags.slice(0, -1));
    updateValueTag(tags.slice(-1)[0] + ` ${valueTag}`);
  };
  const handleCloseTag = (e) => {
    const { dataset } = e.currentTarget;
    updateTags(tags.filter((tag, ind) => ind !== Number(dataset.id)));
  };

  const isDateInvalid = useCallback(
    (date) => {
      return dayjs(date).isValid();
    },
    [valueTime],
  );

  const onSubmit = (data) => {
    confirm(`Will be send ${JSON.stringify(data)}`);
  };

  return (
    <div>
      {/* "handleSubmit" will validate your inputs before invoking "onSubmit"*/}
      <Box tag="form" w={390} onSubmit={handleSubmit(onSubmit)}>
        {/* register your input into the hook by invoking the "register" function */}
        <Flex direction="column" mb={4}>
          <Text size={100}>Label</Text>
          <Tooltip
            interaction={errors['inputControl'] ? 'focus' : 'none'}
            placement="right"
            theme="warning"
            title="You need to feel this useless field"
          >
            <Controller
              as={
                <Input mr={4} mt={1} w={390} state={errors['inputControl'] ? 'invalid' : 'normal'}>
                  <Input.Value
                    value={valueInput}
                    onChange={setValueInput}
                    placeholder="placeholder"
                  />
                </Input>
              }
              control={control}
              rules={{ required: true, validate: (value) => value !== '' }}
              name="inputControl"
              defaultValue=""
            />
          </Tooltip>
        </Flex>

        <Flex direction="column" mb={4}>
          <Text size={100}>Label</Text>
          <Tooltip
            interaction={errors['inputBig'] ? 'focus' : 'none'}
            placement="right"
            theme="warning"
            title="You need to feel this useless field"
          >
            <Textarea
              w={390}
              minRows={4}
              maxRows={10}
              ref={register({ required: true, validate: (value) => value !== '' })}
              placeholder="placeholder"
              value={valueBigInput}
              onChange={setValueBigInput}
              name="inputBig"
              state={errors['inputBig'] ? 'invalid' : 'normal'}
            />
          </Tooltip>
        </Flex>

        <Flex direction="column" mb={4}>
          <Text size={100}>Date</Text>
          <Tooltip
            interaction={errors['inputDate'] ? 'focus' : 'none'}
            placement="right"
            theme="warning"
            title="You need to feel this useless field"
          >
            <InputMask mr={4} mt={1} w={390} state={errors['inputDate'] ? 'invalid' : 'normal'}>
              <Input.Addon>
                <CalendarM />
              </Input.Addon>
              <InputMask.Value
                name="inputDate"
                ref={register({ required: true, validate: (value) => isDateInvalid(value) })}
                mask="99.99.9999"
                value={valueDate}
                onChange={setValueDate}
                placeholder="dd.mm.yyyy"
                onSuccess={isDateInvalid}
              />
            </InputMask>
          </Tooltip>
        </Flex>

        <Tooltip
          interaction={errors['timepicker'] ? 'focus' : 'none'}
          placement="right"
          theme="warning"
          title="You need to choose the time"
        >
          <Controller
            as={
              <TimePicker
                value={valueTime}
                onChange={setValueTime}
                state={errors['timepicker'] ? 'invalid' : 'normal'}
                w={120}
                mb={4}
              >
                <TimePicker.Hours />
                <TimePicker.Separator />
                <TimePicker.Minutes />
                <TimePicker.Format
                  style={
                    errors['timepicker'] ? { borderColor: '#ff7f00' } : { borderColor: '#a6b0b3' }
                  }
                />
              </TimePicker>
            }
            control={control}
            rules={{ required: true, validate: (value) => value !== '' }}
            name="timepicker"
            defaultValue=""
          />
        </Tooltip>
        <br />

        <Tooltip
          interaction={errors['inputPhone'] ? 'focus' : 'none'}
          placement="right"
          theme="warning"
          title="You need to enter the phone number"
        >
          <NeighborLocation controlsLength={2}>
            <Select
              value={option}
              state={errors['inputPhone'] ? 'invalid' : 'normal'}
              onChange={(value) => {
                country = listActuallyCountryCodes[value];
                updateOption(country);
                updateValue(country.dial_code);
                inputMaskRef?.current.focus();
              }}
            >
              <Select.Trigger>
                <Flag iso2={option.code} />
              </Select.Trigger>
              <Select.Popper>
                <>
                  <Select.InputSearch
                    cleared
                    placeholder="Search"
                    value={filter}
                    onChange={updateFilterValue}
                  />
                  <Select.List hMax="240px" w="232px">
                    {Object.keys(listActuallyCountryCodes)
                      .filter((countryName) => countryName.toLowerCase().includes(filter))
                      .map((countryName) => (
                        <Select.Option key={countryName} value={countryName}>
                          <Text size={200} mr={2} style={{ flexShrink: 0 }}>
                            <Flag iso2={listActuallyCountryCodes[countryName].code} />
                          </Text>
                          <Text size={200} mr={2}>
                            {countryName}
                          </Text>
                          <Text size={200} color="gray60">
                            {listActuallyCountryCodes[countryName].dial_code}
                          </Text>
                        </Select.Option>
                      ))}
                  </Select.List>
                </>
              </Select.Popper>
            </Select>
            <Controller
              as={
                <InputMask w={180} state={errors['inputPhone'] ? 'invalid' : 'normal'}>
                  <InputMask.Value
                    ref={inputMaskRef}
                    value={value}
                    onChange={updateValue}
                    mask={valueMask.replace(/_/g, '9')}
                  />
                  {value !== valueMask && (
                    <Input.Addon>
                      <CloseXS
                        interactive
                        onClick={() => {
                          updateValue(valueMask);
                        }}
                      />
                    </Input.Addon>
                  )}
                </InputMask>
              }
              control={control}
              rules={{ required: true, validate: (value) => !/_/i.test(value) }}
              name="inputPhone"
              defaultValue={null}
            />
          </NeighborLocation>
        </Tooltip>
        <br />

        <Tooltip
          interaction={errors['inputTag'] ? 'focus' : 'none'}
          placement="right"
          theme="warning"
          title="You need to feel this useless field"
        >
          <Controller
            as={
              <InputTags
                my={4}
                h={80}
                w={390}
                size="l"
                state={errors['inputTag'] ? 'invalid' : 'normal'}
                onAppend={handleAppendTags}
                onRemove={handleRemoveTag}
              >
                {tags.map((tag, idx) => (
                  <Tooltip key={idx}>
                    <Tooltip.Trigger tag={InputTags.Tag} use="primary" theme="asphalt" editable>
                      <InputTags.Tag.Text>{tag}</InputTags.Tag.Text>
                      <InputTags.Tag.Close data-id={idx} onClick={handleCloseTag} />
                    </Tooltip.Trigger>
                    <Tooltip.Popper>tag</Tooltip.Popper>
                  </Tooltip>
                ))}
                <InputTags.Value value={valueTag} onChange={updateValueTag} />
              </InputTags>
            }
            control={control}
            name="inputTag"
            rules={{ required: true, validate: (value) => value?.length > 0 }}
            defaultValue={tags?.length === 0 ? null : tags}
          />
        </Tooltip>

        <Flex direction="column" mb={4}>
          <Text size={100}>Label</Text>
          <Tooltip
            interaction={errors['select'] ? 'focus' : 'none'}
            placement="right"
            theme="warning"
            title="You need to choose something"
          >
            <Controller
              as={
                <Select
                  mr={4}
                  mt={1}
                  w={390}
                  value={valueSelect}
                  onChange={setValueSelect}
                  state={errors['select'] ? 'invalid' : 'normal'}
                  options={options}
                  placeholder="Select"
                />
              }
              control={control}
              rules={{ required: true, validate: (value) => value !== '' }}
              name="select"
              defaultValue={null}
            />
          </Tooltip>
        </Flex>

        <Tooltip
          interaction={errors['radioButton'] ? 'focus' : 'none'}
          placement="right"
          theme="warning"
          title="Please choose something from the list"
        >
          <Controller
            as={
              <RadioGroup
                mb={4}
                name="radio"
                state={errors['radioButton'] ? 'invalid' : 'normal'}
                value={valueRadio}
                onChange={setValueRadio}
              >
                <Radio mr={2}>
                  <Radio.Value value="1" />
                  <Radio.Text>Option 1</Radio.Text>
                </Radio>
                <Radio mr={2} mt={2}>
                  <Radio.Value value="2" />
                  <Radio.Text>Option 2</Radio.Text>
                </Radio>
              </RadioGroup>
            }
            control={control}
            name="radioButton"
            rules={{ required: true }}
            defaultValue={null}
          />
        </Tooltip>
        <br />

        <Tooltip
          interaction={errors['checkbox'] ? 'focus' : 'none'}
          placement="right"
          theme="warning"
          title="Please check this field"
        >
          <Checkbox mb={4} mt={4} state={errors['checkbox'] ? 'invalid' : 'normal'}>
            <Checkbox.Value
              checked={checked}
              name="checkbox"
              ref={register({ required: true })}
              onChange={setChecked}
            />
            <Checkbox.Text>label</Checkbox.Text>
          </Checkbox>
        </Tooltip>
        <br />

        <Button type="submit">Submit</Button>
      </Box>
    </div>
  );
}
Example #11
Source File: index.jsx    From product-collector with MIT License 4 votes vote down vote up
export default function Filters() {
  const { filter, setFilter, countries, setCountries } = useContext(
    TrendContext
  );
  const { control, errors, setValue } = useForm();

  const query = `
    {
      countries
    }
  `;

  const requestData = useRequestData(query);

  useEffect(() => {
    if (requestData.countries) {
      const values = ['Todos', ...requestData.countries];
      setCountries(values);
    }
  }, [JSON.stringify(requestData)]);

  useEffect(() => {
    Object.entries(filter).map(([key, value]) => {
      setValue(key, value);
    });
  }, [filter.toString()]);

  const handleChange = ([event]) => {
    const {
      target: { name, value },
    } = event;
    const currentFilter = { [name]: value };
    setFilter({ ...filter, ...currentFilter });
    return value;
  };

  return (
    <section className={styles.filters}>
      <FormControl
        className={styles.formControl}
        error={Boolean(errors.country)}
      >
        <InputLabel>Por país</InputLabel>
        <Controller
          as={
            <Select>
              {countries.map((item, index) => (
                <MenuItem key={index} value={index}>
                  {item}
                </MenuItem>
              ))}
            </Select>
          }
          name='country'
          rules={{ required: 'Valor requerido' }}
          control={control}
          defaultValue={0}
          onChange={handleChange}
        />
        <FormHelperText>
          {errors.country && errors.country.message}
        </FormHelperText>
      </FormControl>
      <FormControl className={styles.formControl} error={Boolean(errors.date)}>
        <InputLabel>Por fecha</InputLabel>
        <Controller
          as={
            <Select>
              {dateFilters.map(({ label }, index) => (
                <MenuItem key={index} value={index}>
                  {label}
                </MenuItem>
              ))}
            </Select>
          }
          name='date'
          rules={{ required: 'Valor requerido' }}
          control={control}
          defaultValue={0}
          onChange={handleChange}
        />
        <FormHelperText>{errors.date && errors.date.message}</FormHelperText>{' '}
      </FormControl>
    </section>
  );
}
Example #12
Source File: checkbox&radio.jsx    From intergalactic with MIT License 4 votes vote down vote up
Demo = () => {
  const [selected, updateSelected] = React.useState(false);
  const [selectedValue, updateSelectedValue] = React.useState([]);
  const [selectedFirst, updateSelectedFirst] = React.useState(0);
  const defaultValues = {
    export: 'all',
  };
  const { handleSubmit, control, reset, errors, setError } = useForm({
    defaultValues,
  });

  const onSubmit = (data) => {
    if (data.export === 'first') {
      if (!selectedFirst) {
        setError('export', { message: 'Require enter value' });
        return;
      } else {
        data.export = 'first ' + selectedFirst;
      }
    }
    if (data.export === 'selected') {
      if (!selectedValue.length) {
        setError('export', { message: 'Require chouse value' });
        return;
      } else {
        data.export = 'selected [' + selectedValue.join(',') + ']';
      }
    }
    reset(defaultValues);
    updateSelected(false);
    updateSelectedValue([]);
    updateSelectedFirst(0);
    alert(JSON.stringify(data));
  };

  const optionsFirst = [100, 500].map((value) => ({ value, children: value }));
  const onChangeSelect = (value) => {
    reset({ export: 'first' });
    updateSelectedFirst(value);
  };
  const onChangCheckbox = (checked, e) => {
    const { value } = e.target;
    const tmpArray = checked ? [...selectedValue, value] : selectedValue.filter((v) => v !== value);
    tmpArray.length && reset({ export: 'selected' });
    updateSelectedValue(tmpArray);
  };
  const onSelectedRadio = () => {
    updateSelected(!selected);
  };

  return (
    <Flex tag="form" onSubmit={handleSubmit(onSubmit)} direction="column" alignItems="flex-start">
      <Flex direction="column" mb={4}>
        <Text size={200} tag="label" mb={4}>
          Export data
        </Text>
        <Controller
          render={({ value, ...props }) => (
            <RadioGroup {...props} value={value} size="l">
              <Radio mb={3}>
                <Radio.Value value="all" />
                <Radio.Text>All</Radio.Text>
              </Radio>
              <Radio mb={3}>
                <Radio.Value value="selected" onChange={onSelectedRadio} />
                <Radio.Text>Selected</Radio.Text>
                {selected &&
                  [100, 500].map((v) => (
                    <Checkbox
                      size="l"
                      ml={2}
                      key={v}
                      state={value.includes('selected') && errors['export'] ? 'invalid' : 'normal'}
                    >
                      <Checkbox.Value value={v} onChange={onChangCheckbox} />
                      <Checkbox.Text children={v} />
                    </Checkbox>
                  ))}
              </Radio>
              <Radio style={{ alignItems: 'center' }}>
                <Radio.Value value="first" />
                <Radio.Text>First</Radio.Text>
                <Select
                  size="l"
                  ml={2}
                  state={value.includes('first') && errors['export'] ? 'invalid' : 'normal'}
                  tag={ButtonTrigger}
                  options={optionsFirst}
                  onChange={onChangeSelect}
                />
              </Radio>
            </RadioGroup>
          )}
          control={control}
          name="export"
        />
      </Flex>

      <Button type="submit" use="primary" theme="info" size="l">
        Excel
      </Button>
    </Flex>
  );
}
Example #13
Source File: ReportForm.js    From pandoa with GNU General Public License v3.0 4 votes vote down vote up
function ReportForm({ reportCaseTrigger, positions }) {
  const { control, handleSubmit, errors } = useForm();
  const onSubmit = data => {
    Alert.alert("Data submitted");
    reportCaseTrigger(positions);

    // Alert.alert("Form Data", JSON.stringify(data), positions.length);
  };

  return (
    <View>
      <Form>
        <Text style={styles.hintText}>
          On this page you can report if you have got an infection. Please enter
          your details below
        </Text>
        <View style={styles.inputWrapper}>
          <Item>
            <Text>Picker</Text>
            <Controller
              as={e => {
                console.log(e);
                return (
                  <Picker
                    note
                    mode="dropdown"
                    style={{ width: 120 }}
                    selectedValue={"key3"}
                    onValueChange={() => {}}
                  >
                    <Picker.Item label="Wallet" value="key0" />
                    <Picker.Item label="ATM Card" value="key1" />
                    <Picker.Item label="Debit Card" value="key2" />
                    <Picker.Item label="Credit Card" value="key3" />
                    <Picker.Item label="Net Banking" value="key4" />
                  </Picker>
                );
              }}
              control={control}
              name="firstName"
              onChange={args => args[0].nativeEvent.text}
              onChange={e => {
                return "key1";
                // Place your logic here
                return selected;
              }}
              rules={{ required: true }}
              defaultValue=""
              placeholder="Username"
            />
          </Item>
          {errors.firstName && <Text>This is required.</Text>}
          <Item>
            <Controller
              as={Input}
              control={control}
              name="lastName"
              onChange={args => args[0].nativeEvent.text}
              defaultValue=""
              placeholder="Password"
            />
          </Item>
        </View>

        <Text style={styles.hintText}>
          Enter a contact phone number. This can be yours or a doctors phone
          number.
        </Text>
        <View style={styles.inputWrapper}>
          <Item>
            <Label>Contact phone number</Label>
            <Controller
              as={Input}
              control={control}
              name="contact_phone"
              onChange={args => args[0].nativeEvent.text}
              defaultValue=""
            />
          </Item>
        </View>
        <Text style={styles.hintText}>Enter information for you contact.</Text>
        <View style={styles.inputWrapper}>
          <Item style={styles.input}>
            <Label>Contact information</Label>
            <Controller
              as={Input}
              control={control}
              name="contact_information"
              onChange={args => args[0].nativeEvent.text}
              defaultValue=""
              placeholder="Contact information"
            />
          </Item>
        </View>
      </Form>
      {/*
      <Form>
        <Item>
          <Input placeholder="Username" />
        </Item>
        <Item last>
          <Input placeholder="Password" />
        </Item>
        <Button primary onPress={reportButton}>
          <Text>Submit data</Text>
        </Button>
</Form>*/}
      <View style={styles.submitWrapper}>
        <Button primary onPress={handleSubmit(onSubmit)}>
          <Text>Submit</Text>
        </Button>
      </View>
    </View>
  );
}
Example #14
Source File: react_hook_form.js    From react-multi-date-picker with MIT License 4 votes vote down vote up
export default function Doc({ translate, language, otherProps }) {
  const { control, handleSubmit } = useForm();
  const [submittedDate, setSubmittedDate] = useState();

  const onSubmit = ({ date }) => {
    setSubmittedDate(date);
  };

  const example = {
    title: "Example Of Using React Hook Form",
    code: `import React, { useState } from "react";
import DatePicker from "react-multi-date-picker";
import { useForm, Controller } from "react-hook-form";

export default function Example() {
  const { control, handleSubmit } = useForm();
  const [submittedDate, setSubmittedDate] = useState();

  const onSubmit = ({ date }) => {
    setSubmittedDate(date);
  };

  return (
    <>
      <form onSubmit={handleSubmit(onSubmit)}>
        <Controller
          control={control}
          name="date"
          rules={{ required: true }} //optional
          render={({
            field: { onChange, name, value },
            fieldState: { invalid, isDirty }, //optional
            formState: { errors }, //optional, but necessary if you want to show an error message
          }) => (
            <>
              <DatePicker
                value={value || ""}
                onChange={(date) => {
                  onChange(date?.isValid ? date : "");
                }}
                format={language === "en" ? "MM/DD/YYYY" : "YYYY/MM/DD"}
              ${
                language === "en"
                  ? "/>"
                  : `  calendar="persian"
                locale="fa"
                calendarPosition="bottom-right"
              />`
              }
              {errors && errors[name] && errors[name].type === "required" && (
                //if you want to show an error message
                <span>your error message !</span>
              )}
            </>
          )}
        />
        <input type="submit" />
      </form>
      <p>${translate("Submitted Date: ")} {submittedDate?.format?.("${
      language === "en" ? "MMMM D YYYY" : "D MMMM YYYY"
    }")}</p>
    </>
  )
}`,
    jsx: (
      <>
        <form onSubmit={handleSubmit(onSubmit)}>
          <Controller
            control={control}
            name="date"
            rules={{ required: true }} //optional
            render={({
              field: { onChange, name, value },
              fieldState: { invalid, isDirty }, // optional
              formState: { errors }, //optional, but necessary if you want to show an error message
            }) => (
              <>
                <DatePicker
                  //react hook form needs this
                  value={value || ""}
                  onChange={(date) => {
                    onChange(date?.isValid ? date : "");
                  }}
                  format={language === "en" ? "MM/DD/YYYY" : "YYYY/MM/DD"}
                  {...otherProps}
                />
                {errors && errors[name] && errors[name].type === "required" && (
                  //if you want to show an error message
                  <span>your error message !</span>
                )}
              </>
            )}
          />
          <input type="submit" />
        </form>
        <p>
          {translate("Submitted Date: ")}
          {submittedDate?.format?.(
            language === "en" ? "MMMM D YYYY" : "D MMMM YYYY"
          )}
        </p>
      </>
    ),
  };

  return [example];
}
Example #15
Source File: Login.jsx    From fluentui-starter with MIT License 4 votes vote down vote up
function LoginForm({ theme, styles }) {
  const { isAuthenticated, principal, login, logout } = useAuthentication();
  const {
    handleSubmit,
    control,
    formState: { errors },
  } = useForm();
  const [error, setError] = React.useState();
  const history = useHistory();
  const location = useLocation();

  const from = location.state?.from || { pathname: "/" };

  function onSubmit(values) {
    setError(null);
    remoteAuthService(values)
      .then((identity) => {
        login(identity);
        history.replace(from);
      })
      .catch(setError);
  }

  function getErrorMessage(name) {
    return get(errors, name + ".message");
  }

  const classNames = getClassNames(styles, { theme });
  return (
    <Stack className={classNames.root}>
      {isAuthenticated && (
        <Stack tokens={{ childrenGap: "1em" }}>
          <h3 className={classNames.title}>
            {principal.username}, you are already signed in.
          </h3>
          <Stack horizontal tokens={{ childrenGap: "1em" }}>
            <PrimaryButton
              onClick={() => history.push("/")}
              iconProps={{ iconName: "Home" }}
            >
              Go to Home
            </PrimaryButton>
            <DefaultButton onClick={logout} iconProps={{ iconName: "SignOut" }}>
              Logout
            </DefaultButton>
          </Stack>
        </Stack>
      )}

      {!isAuthenticated && (
        <form onSubmit={handleSubmit(onSubmit)}>
          <Stack horizontal horizontalAlign="end" verticalAlign="center">
            <ThemeToggle as={DefaultButton} />
          </Stack>
          <h3 className={classNames.title}>Login</h3>
          <Stack
            tokens={{
              childrenGap: "1em",
            }}
          >
            <Controller
              as={TextField}
              control={control}
              autoComplete="username"
              autoFocus
              minLength={3}
              maxLength={32}
              defaultValue=""
              name="username"
              rules={{
                required: "Please enter your username",
                minLength: {
                  value: 3,
                  message: "Please enter your username",
                },
                maxLength: { value: 32, message: "Username is too long" },
              }}
              render={({ field }) => (
                <TextField
                  {...field}
                  label="Username"
                  errorMessage={getErrorMessage("username")}
                />
              )}
            />

            <Controller
              name="password"
              control={control}
              defaultValue=""
              minLength={4}
              maxLength={64}
              rules={{
                required: "Please enter your password",
                minLength: {
                  value: 4,
                  message: "Please enter your password",
                },
                maxLength: { value: 64, message: "Password is too long" },
              }}
              render={({ field }) => (
                <TextField
                  {...field}
                  label="Password"
                  type="password"
                  autoComplete="current-password"
                  errorMessage={getErrorMessage("password")}
                />
              )}
            />

            <Stack
              horizontal
              horizontalAlign="end"
              tokens={{ childrenGap: "1em" }}
            >
              <Link>Find my password</Link>
              <PrimaryButton type="submit">Login</PrimaryButton>
            </Stack>
            <Stack>
              <h3>Demo users</h3>
              <ul>
                <li>demo/demo</li>
                <li>admin/admin</li>
              </ul>
            </Stack>
            {error && (
              <MessageBar
                messageBarType={MessageBarType.error}
                onDismiss={() => setError(null)}
              >
                {error}
              </MessageBar>
            )}
          </Stack>
        </form>
      )}
    </Stack>
  );
}
Example #16
Source File: SelectField.js    From plataforma-sabia with MIT License 4 votes vote down vote up
SelectField = ({
	name,
	form,
	label,
	help,
	options,
	defaultOptions,
	validation,
	creatable,
	onCreate,
	isMulti,
	callback,
	wrapperCss,
	variant,
	isHidden,
	isLoading,
	instanceId,
	isAsync,
	onChange,
	...selectProps
}) => {
	const { t } = useTranslation(['error']);
	const [needsUpdate, setNeedsUpdate] = useState(true);
	const [internalIsLoading, setInternalIsLoading] = useState(false);
	const [selectOptions, setSelectOptions] = useState(options);

	const { formState: { errors } = {}, control, watch, setValue, getValues } = form;
	const errorObject = get(errors, name);
	const hasError = typeof errorObject !== 'undefined';

	let selectedValue = watch(name);
	if (selectedValue) {
		selectedValue = Array.isArray(selectedValue)
			? selectedValue.map((value) => `${value}`)
			: selectedValue;
		selectedValue = Array.isArray(selectedValue) && !isMulti ? selectedValue[0] : selectedValue;
		selectedValue =
			!Array.isArray(selectedValue) && typeof selectedValue !== 'object'
				? `${selectedValue}`
				: selectedValue;
	}

	/**
	 * Compares each option's label with each other in order to sort them later.
	 *
	 * @param {object} firstOption The first option
	 * @param {object} secondOption The second option
	 * @returns {number}
	 */
	function compareOptions(firstOption, secondOption) {
		const { label: firstLabel } = firstOption;
		const { label: secondLabel } = secondOption;

		return firstLabel.localeCompare(secondLabel);
	}

	// update the select options whenever options prop changes
	useEffect(() => {
		const useOptionsFrom = isAsync ? defaultOptions : options;
		setSelectOptions(useOptionsFrom.sort(compareOptions));
	}, [options, defaultOptions, isAsync]);

	/**
	 * React-select expects value to be in { value: '', label: '' } shape so we run a useEffect
	 * to ensure it's in the right format. This allows this component to be intialized just with the value.
	 */
	useEffect(() => {
		if (!needsUpdate) {
			return;
		}

		if (
			(!options || options.length === 0) &&
			(!defaultOptions || defaultOptions.length === 0)
		) {
			return;
		}

		const useOptionsFrom = isAsync ? defaultOptions : options;

		if (!selectedValue) {
			setNeedsUpdate(false);
			return;
		}

		if (isMulti) {
			setValue(
				name,
				selectedValue.map((value) =>
					useOptionsFrom.find((option) => `${option.value}` === `${value}`),
				),
				{ shouldDirty: true },
			);
		} else if (typeof selectedValue === 'object') {
			setValue(
				name,
				useOptionsFrom.find((option) => `${option.value}` === `${selectedValue.value}`),
				{ shouldDirty: true },
			);
		} else {
			setValue(
				name,
				useOptionsFrom.find((option) => `${option.value}` === `${selectedValue}`),
				{ shouldDirty: true },
			);
		}

		setNeedsUpdate(false);
	}, [selectedValue, options, defaultOptions, name, setValue, isMulti, isAsync, needsUpdate]);

	/**
	 * Handles creating a new element in the select field.
	 *
	 * Only called if `creatable` is true.
	 *
	 * @param {string} inputValue The inserted input value.
	 *
	 */
	const onCreateOption = async (inputValue) => {
		setInternalIsLoading(true);
		const newOption = await onCreate(inputValue);
		setInternalIsLoading(false);
		setSelectOptions([...options, newOption]);

		const currentValue = getValues(name) || [];

		if (isMulti) {
			setValue(name, [...currentValue, newOption], { shouldDirty: true });
		} else {
			setValue(name, newOption, { shouldDirty: true });
		}

		return newOption;
	};

	// eslint-disable-next-line no-nested-ternary
	const Component = creatable ? StyledCreatable : isAsync ? StyledAsync : StyledSelect;

	return (
		<InputFieldWrapper hasError={hasError} customCss={wrapperCss} isHidden={isHidden}>
			{label && (
				<InputLabel htmlFor={name}>
					{label}
					{validation.required && <RequiredIndicator />}
				</InputLabel>
			)}

			<Row>
				<Controller
					control={control}
					rules={validation}
					name={name}
					render={({ field }) => (
						<Component
							id={name}
							className="react-select-container"
							classNamePrefix="react-select"
							aria-label={label}
							aria-required={validation.required}
							options={selectOptions}
							defaultOptions={selectOptions}
							isMulti={isMulti}
							onCreateOption={creatable ? onCreateOption : null}
							isDisabled={internalIsLoading || isLoading || isHidden}
							isLoading={internalIsLoading || isLoading}
							styles={reactSelectStyles[variant]}
							instanceId={instanceId}
							{...selectProps}
							{...field}
							onChange={(selectedValues) => {
								if (typeof callback === 'function') callback(selectedValues);

								if (typeof onChange === 'function')
									return field.onChange(onChange(selectedValues));

								return field.onChange(selectedValues);
							}}
						/>
					)}
				/>
				{help && <Help id={name} label={label} HelpComponent={help} />}
			</Row>
			{creatable && (
				<Hint>
					É possível adicionar novas opções neste campo. Basta digitar a opção e
					pressionar a tecla Enter.
				</Hint>
			)}
			{hasError && Object.keys(errors).length ? (
				<InputError>{validationErrorMessage(errors, name, t)}</InputError>
			) : null}
		</InputFieldWrapper>
	);
}
Example #17
Source File: GrantModal.js    From akashlytics-deploy with GNU General Public License v3.0 4 votes vote down vote up
GrantModal = ({ address, onClose }) => {
  const formRef = useRef();
  const [error, setError] = useState("");

  const classes = useStyles();
  const { sendTransaction } = useTransactionModal();
  const {
    handleSubmit,
    control,
    formState: { errors },
    watch,
    clearErrors
  } = useForm({
    defaultValues: {
      amount: "",
      expiration: format(addYears(new Date(), 1), "yyyy-MM-dd'T'HH:mm"),
      useDepositor: false,
      granteeAddress: ""
    }
  });
  const { amount, granteeAddress, expiration } = watch();

  const onDepositClick = (event) => {
    event.preventDefault();
    formRef.current.dispatchEvent(new Event("submit", { cancelable: true, bubbles: true }));
  };

  const onSubmit = async ({ amount }) => {
    setError("");
    clearErrors();
    const spendLimit = aktToUakt(amount);

    const expirationDate = new Date(expiration);
    const message = TransactionMessageData.getGrantMsg(address, granteeAddress, spendLimit, expirationDate);
    const response = await sendTransaction([message]);

    if (response) {
      await analytics.event("deploy", "authorize spend");

      onClose();
    }
  };

  function handleDocClick(ev, url) {
    ev.preventDefault();

    window.electron.openUrl(url);
  }

  return (
    <Dialog maxWidth="xs" aria-labelledby="deposit-dialog-title" open={true} onClose={onClose}>
      <DialogTitle id="deposit-dialog-title">Authorize Spending</DialogTitle>
      <DialogContent dividers className={classes.dialogContent}>
        <form onSubmit={handleSubmit(onSubmit)} ref={formRef}>
          <Alert severity="info">
            <Typography variant="caption">
              <LinkTo onClick={(ev) => handleDocClick(ev, "https://docs.akash.network/testnet-technical-docs/authorized-spend")}>Authorized Spend</LinkTo>{" "}
              allows users to authorize spend of a set number of tokens from a source wallet to a destination, funded wallet. The authorized spend is restricted
              to Akash deployment activities and the recipient of the tokens would not have access to those tokens for other operations.
            </Typography>
          </Alert>

          <FormControl error={!errors.amount} className={classes.formControl} fullWidth>
            <Controller
              control={control}
              name="amount"
              rules={{
                required: true
              }}
              render={({ fieldState, field }) => {
                const helperText = fieldState.error?.type === "validate" ? "Invalid amount." : "Amount is required.";

                return (
                  <TextField
                    {...field}
                    type="number"
                    variant="outlined"
                    label="Spending Limit"
                    autoFocus
                    error={!!fieldState.invalid}
                    helperText={fieldState.invalid && helperText}
                    className={classes.formValue}
                    inputProps={{ min: 0, step: 0.000001 }}
                    InputProps={{
                      startAdornment: <InputAdornment position="start">AKT</InputAdornment>
                    }}
                  />
                );
              }}
            />
          </FormControl>

          <FormControl className={classes.formControl} fullWidth>
            <Controller
              control={control}
              name="granteeAddress"
              defaultValue=""
              rules={{
                required: true
              }}
              render={({ fieldState, field }) => {
                return (
                  <TextField
                    {...field}
                    type="text"
                    variant="outlined"
                    label="Grantee Address"
                    error={!!fieldState.invalid}
                    helperText={fieldState.invalid && "Grantee address is required."}
                    className={classes.formValue}
                  />
                );
              }}
            />
          </FormControl>

          <FormControl className={classes.formControl} fullWidth>
            <Controller
              control={control}
              name="expiration"
              rules={{
                required: true
              }}
              render={({ fieldState, field }) => {
                return (
                  <TextField
                    {...field}
                    type="datetime-local"
                    variant="outlined"
                    label="Expiration"
                    error={!!fieldState.invalid}
                    helperText={fieldState.invalid && "Expiration is required."}
                    className={classes.formValue}
                  />
                );
              }}
            />
          </FormControl>

          {!!amount && granteeAddress && (
            <Box marginTop={1} textAlign={"left"}>
              This address will be able to spend up to {amount}AKT on your behalf.
            </Box>
          )}

          {error && (
            <Alert severity="warning" className={classes.alert}>
              {error}
            </Alert>
          )}
        </form>
      </DialogContent>
      <DialogActions className={classes.dialogActions}>
        <Button autoFocus onClick={onClose}>
          Cancel
        </Button>
        <Button onClick={onDepositClick} disabled={!amount} variant="contained" color="primary">
          Grant
        </Button>
      </DialogActions>
    </Dialog>
  );
}
Example #18
Source File: BadgeForm.js    From carbon-badges with Apache License 2.0 4 votes vote down vote up
BadgeForm = () => {
  const [emails, setEmails] = useState([]);
  const [steps, setSteps] = useState([]);
  const [stepsLoading, setStepsLoading] = useState(false);
  const [submitLoading, setSubmitLoading] = useState(false);
  const [acceptUrl, setAcceptUrl] = useState("");
  const { token } = useAuth();
  const {
    handleSubmit,
    watch,
    errors,
    control,
    formState,
    setError,
    clearErrors,
    register,
    reset,
  } = useForm({
    mode: "onChange",
  });
  const selectedTutorial = watch("badge", {});

  useEffect(() => {
    if (!token) return;

    fetch(`/api/github/user-emails?access_token=${token}`)
      .then((response) => response.json())
      .then((data) => {
        setEmails(data || []);
      });
  }, [token]);

  useEffect(() => {
    if (!selectedTutorial.id) {
      return;
    }

    const preSetSteps = (prs) => {
      // filter PRs by "step x" title and sort by step then status (approved
      // first, then needs correction, then not reviewed)
      const items = cleanPRs(prs)
        .filter((item) => item.step)
        .sort((a, b) => {
          if (a.step < b.step) return -1;
          if (a.step > b.step) return 1;
          if (a.status < b.status) return -1;
          if (a.status > b.status) return 1;
          return 0;
        });

      // grab the first PR for each step and backfill missing steps
      const uniqueItems = [];
      for (let i = 1; i <= 5; i++) {
        const foundItem = items.find((item) => item.step.includes(i));
        if (foundItem) {
          uniqueItems.push(foundItem);
        } else {
          uniqueItems.push({
            status: "not-found",
            step: "Step " + i,
          });
        }
      }

      const hasError = uniqueItems.reduce((error, item) => {
        return error ? true : item.status !== "approved";
      }, false);

      if (hasError) {
        setError("badge", {
          type: "manual",
          message: "A pull request for each step 1 - 5 must be approved.",
        });
      } else {
        clearErrors("badge");
      }

      setSteps(uniqueItems);
    };

    setSteps([]);
    setStepsLoading(true);

    fetch(
      `/api/github/pull-requests?access_token=${token}&tutorial=${selectedTutorial.id}`
    )
      .then((response) => response.json())
      .then((data) => {
        preSetSteps(data.items || []);
        setStepsLoading(false);
      });
  }, [clearErrors, selectedTutorial, setError, token]);

  const onSubmit = (values) => {
    setSubmitLoading(true);
    setAcceptUrl("");

    fetch(`/api/github/badge-issue?access_token=${token}`, {
      method: "POST",
      headers: {
        "Content-type": "application/json",
      },
      body: JSON.stringify(values),
    })
      .then((response) => response.json())
      .then((data) => {
        console.log(data);
        setSubmitLoading(false);

        const acclaimError = getAcclaimError(data.data);

        if (data.error) {
          setError("email", {
            type: "submit",
            message: data.error,
          });
        } else if (acclaimError) {
          setError("email", {
            type: "submit",
            message: acclaimError,
          });
        } else if (data.data && data.data["accept_badge_url"]) {
          reset({
            badge: "",
            email: "",
          });
          setSteps([]);
          setAcceptUrl(data.data["accept_badge_url"]);
        }
      });
  };

  if (!token) return null;

  return (
    <>
      <Row>
        <Column colLg={8}>
          <H2>Badge application</H2>
        </Column>
      </Row>
      <Row>
        <Column colLg={8}>
          {emails.length === 0 ? (
            <SkeletonText paragraph={true} width="320px" />
          ) : (
            <form method="post" onSubmit={handleSubmit(onSubmit)}>
              <div>
                <Controller
                  control={control}
                  name="badge"
                  rules={{ required: true }}
                  render={({ onChange, value }) => (
                    <Dropdown
                      id="badge"
                      invalid={!!errors.badge && !stepsLoading}
                      selectedItem={value}
                      onChange={(item) => onChange(item.selectedItem)}
                      invalidText={
                        (errors.badge && errors.badge.message) ||
                        "A value is required."
                      }
                      ariaLabel="Badge dropdown"
                      titleText="Carbon tutorial"
                      label="Choose a badge"
                      items={Object.keys(badgeConfig.badges).map((name) => {
                        return {
                          id: name,
                          text: badgeConfig.badges[name].label,
                        };
                      })}
                      itemToString={(item) => (item ? item.text : "")}
                      light={true}
                    />
                  )}
                />
              </div>

              <div className={style.field}>
                {stepsLoading && (
                  <InlineLoading
                    description="Searching GitHub..."
                    iconDescription="Searching GitHub"
                    status="active"
                  />
                )}
                {steps.map((step, i) => (
                  <InlineNotification
                    key={i}
                    hideCloseButton={true}
                    kind={
                      step.status === "approved"
                        ? "success"
                        : step.status === "correction"
                        ? "error"
                        : "warning"
                    }
                    lowContrast={true}
                    title={
                      step.step.charAt(0).toUpperCase() + step.step.slice(1)
                    }
                    subtitle={
                      <span>
                        {step.number && (
                          <>
                            <a href={step.url} rel="noreferrer" target="_blank">
                              PR #{step.number}
                            </a>{" "}
                          </>
                        )}
                        {step.status === "approved"
                          ? "approved."
                          : step.status === "correction"
                          ? "needs correction."
                          : step.status === "not-reviewed"
                          ? "not reviewed."
                          : "not found."}
                      </span>
                    }
                  ></InlineNotification>
                ))}
              </div>

              <div className={style.field}>
                <Controller
                  control={control}
                  name="email"
                  rules={{ required: true }}
                  render={({ onChange, value }) => (
                    <Dropdown
                      id="email"
                      invalid={!!errors.email}
                      selectedItem={value}
                      onChange={(item) => onChange(item.selectedItem)}
                      invalidText={
                        (errors.email && errors.email.message) ||
                        "A value is required."
                      }
                      ariaLabel="Email dropdown"
                      titleText="Email address"
                      label="Choose an email address"
                      helperText="Don't see your work email address? Verify it in GitHub email settings to use here."
                      items={emails
                        .filter((email) => email.verified)
                        .map((email) => email.email)}
                      light={true}
                    />
                  )}
                />
              </div>

              {Object.keys(badgeConfig.questions).map((question) => (
                <div className={style.field}>
                  <TextArea
                    id={question}
                    name={question}
                    invalid={!!errors[question]}
                    invalidText="A value is required."
                    labelText={`${badgeConfig.questions[question]} (Optional)`}
                    rows={3}
                    light={true}
                    ref={register}
                  />
                </div>
              ))}

              {formState.isSubmitted && errors.email && (
                <div className={style.field}>
                  <InlineNotification
                    hideCloseButton={true}
                    kind="error"
                    lowContrast={true}
                    title="Error"
                    subtitle={errors.email.message}
                  />
                </div>
              )}

              {acceptUrl && (
                <div className={style.field}>
                  <InlineNotification
                    actions={
                      <NotificationActionButton
                        onClick={() => (window.location.href = acceptUrl)}
                      >
                        Accept badge
                      </NotificationActionButton>
                    }
                    kind="success"
                    lowContrast={true}
                    title="Success"
                    subtitle="Your badge has been issued. You'll receive an email to accept the badge."
                  />
                </div>
              )}

              <div className={style.actions}>
                <Button
                  disabled={!formState.isValid || submitLoading}
                  size="field"
                  type="submit"
                >
                  Apply for badge
                </Button>
                {submitLoading && (
                  <InlineLoading
                    description="Applying..."
                    iconDescription="Applying"
                    status="active"
                  />
                )}
              </div>
            </form>
          )}
        </Column>
      </Row>
    </>
  );
}
Example #19
Source File: ProfileForm.js    From AdaptivApps-fe with MIT License 4 votes vote down vote up
ProfileForm = ({ loading, profile, user, updateProfile }) => {
  const [updated, setUpdated] = useState(false);
  const [userProfile, setUserProfile] = useState(null);
  const classes = useStyles();

  const { refetch: refetchProfile } = useQuery(GET_USER_PROFILE, { variables: { email: user.email } });

  const { handleSubmit, register, setValue, control } = useForm({
    mode: "onSubmit",
    validationSchema: ProfileSchema,
    defaultValues: {
      email: user && user.email,
      firstName: userProfile && userProfile.firstName,
      lastName: userProfile && userProfile.lastName,
      displayName: userProfile && userProfile.displayName,
      birthday: userProfile && userProfile.birthday,
      bio: userProfile && userProfile.bio,
      disability: userProfile && userProfile.disability,
    },
  });

  // updates profile in the backend and frontend
  const onSubmit = (formValues, e) => {
    e.preventDefault();

    // backend update
    updateProfile({
      variables: {
        email: user.email,
        firstName:
          formValues.firstName === ""
            ? userProfile.firstName
            : formValues.firstName,
        lastName:
          formValues.lastName === ""
            ? userProfile.lastName
            : formValues.lastName,
        displayName:
          formValues.displayName === ""
            ? userProfile.displayName
            : formValues.displayName,
        birthday:
          formValues.birthday === ""
            ? userProfile.birthday
            : formValues.birthday,
        bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
        disability:
          formValues.disability === ""
            ? userProfile.disability
            : formValues.disability,
        legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
      },
    });

    // frontend update
    setUserProfile({
      email: user.email,
      firstName:
        formValues.firstName === ""
          ? userProfile.firstName
          : formValues.firstName,
      lastName:
        formValues.lastName === "" ? userProfile.lastName : formValues.lastName,
      displayName:
        formValues.displayName === ""
          ? userProfile.displayName
          : formValues.displayName,
      birthday:
        formValues.birthday === "" ? userProfile.birthday : formValues.birthday,
      bio: formValues.bio === "" ? userProfile.bio : formValues.bio,
      disability:
        formValues.disability === ""
          ? userProfile.disability
          : formValues.disability,
      legal: formValues.legal === "" ? userProfile.legal : formValues.legal,
    });

    refetchProfile();
  };

  // updates form fields with new values
  useEffect(() => {
    if (!loading && !userProfile) setUserProfile(profile);
    if (!loading && userProfile) {
      setValue([
        { firstName: userProfile && userProfile.firstName },
        { lastName: userProfile && userProfile.lastName },
        { displayName: userProfile && userProfile.displayName },
        { birthday: userProfile && userProfile.birthday },
        { bio: userProfile && userProfile.bio },
        { disability: userProfile && userProfile.disability },
        { legal: userProfile && userProfile.legal },
      ]);
    }
  }, [loading, userProfile, setValue, profile]);

  // alerts user to successful update, handy for screen readers
  const handleUpdated = () => {
    refetchProfile();
    alert("Profile updated successfully!");
    setUpdated(false);
  };

  const userPicture = user && user.picture;

  return (
    <main className={classes.root}>
      <Box className={classes.headingBox} borderBottom={2}>
        <Typography variant="h1" gutterBottom>
          Account Information
        </Typography>
      </Box>
      <Container className={classes.profileContainer}>
        <Box className={classes.profileInfo}>
          <img className={classes.profileImg} src={userPicture} alt="Profile" />
          <Box className={classes.profileText}>
            <Typography>
              {userProfile && userProfile.firstName !== null
                ? `${userProfile && userProfile.firstName} ${userProfile &&
                    userProfile.lastName}`
                : user && user.name}{" "}
            </Typography>
            <Typography>{user && user.email}</Typography>
          </Box>
        </Box>

        <Typography className={classes.personalInfo} variant="h2" gutterBottom>
          Personal Information
        </Typography>
        <form className={classes.form} onSubmit={handleSubmit(onSubmit)}>
          <Box component="div" className={classes.formBox}>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="firstName">
                First Name
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.input}
                id="firstName"
                variant="outlined"
                type="text"
                placeholder={userProfile ? userProfile.firstName : ""}
                name="firstName"
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="lastName">
                Last Name
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.input}
                id="lastName"
                type="text"
                variant="outlined"
                placeholder={userProfile ? userProfile.lastName : ""}
                name="lastName"
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
          </Box>
          <Box className={classes.formBox}>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="displayName">
                Display Name
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.input}
                id="displayName"
                type="text"
                variant="outlined"
                placeholder={userProfile ? userProfile.displayName : ""}
                name="displayName"
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="birthday">
                Date of Birth
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.input}
                id="birthday"
                type="text"
                variant="outlined"
                name="birthday"
                placeholder={userProfile ? userProfile.birthday : "mm/dd/yyyy"}
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
          </Box>

          <Box className={classes.formBox}>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="bio">
                Bio
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.bio}
                id="bio"
                name="bio"
                variant="outlined"
                multiline={true}
                rows="8"
                placeholder={userProfile ? userProfile.bio : null}
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
          </Box>

          <Box className={classes.formBox}>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="disability">
                Disability Status
              </InputLabel>
              <Controller
                as={<TextField />}
                className={classes.input}
                id="disability"
                type="select"
                variant="outlined"
                name="disability"
                ref={register}
                placeholder={userProfile ? userProfile.disability : null}
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
            <Box className={classes.box}>
              <InputLabel className={classes.inputLabel} htmlFor="legal">
                Are you over 18 years old?
              </InputLabel>
              <Controller
                as={
                  <Select value={userProfile?.legal}>
                    <MenuItem value="">
                      {userProfile ? userProfile.legal : ""}
                    </MenuItem>
                    <MenuItem value={`Adult`}>Yes</MenuItem>
                    <MenuItem value={`Minor`}>No</MenuItem>
                  </Select>
                }
                className={classes.input}
                id="legal"
                name="legal"
                variant="outlined"
                control={control}
                inputProps={{
                  classes: {
                    input: classes.resize,
                  },
                }}
              />
            </Box>
          </Box>
          <Box className={classes.formBox}>
            <Button
              className={classes.button}
              variant="outlined"
              color="primary"
              type="submit"
              aria-label="save changes to user profile"
              onClick={() => {
                setUpdated(true);
              }}
            >
              Save
            </Button>
            {updated === true ? handleUpdated() : null}
          </Box>
        </form>
      </Container>
    </main>
  );
}
Example #20
Source File: NewRequestPage.js    From app with MIT License 4 votes vote down vote up
function NewRequestPage() {
  const classes = useStyles();
  const location = useLocation();
  const qs = queryString.parse(location.search);
  const defaultValues = {
    needs: {},
    immediacy: '1',
    needFinancialAssistance: 'false',
  };

  // Append needs from query string type
  if (qs && qs.type) {
    defaultValues.needs = { [qs.type]: true };
  }

  const {
    register,
    handleSubmit,
    errors,
    watch,
    control,
    formState: { isValid, isSubmitting, dirty },
  } = useForm({
    validationSchema: requestValidationSchema,
    defaultValues,
  });

  const {
    submitRequest,
    handleLocationChange,
    requestLocation,
    requestLocationLoading,
  } = useNewRequestPage();
  const currentNeeds = watch('needs');
  const groceryPickup = currentNeeds && currentNeeds['grocery-pickup'];

  return (
    <Container maxWidth="md">
      <Helmet>
        <title>Request Assistance</title>
      </Helmet>
      <Typography variant="h5" color="textPrimary" gutterBottom>
        Request Help
      </Typography>
      <Paper className={classes.paper} data-test="request-form">
        <div className={classes.heroContent}>
          <Container maxWidth="md">
            <form onSubmit={handleSubmit(submitRequest)}>
              <Container>
                <FormGroup>
                  <Typography
                    variant="h5"
                    gutterBottom
                    className={classes.otherComments}>
                    What do you need help with?
                  </Typography>
                  {Object.keys(activeCategoryMap).map((optionKey) => (
                    <FormControlLabel
                      key={optionKey}
                      control={
                        <Checkbox
                          inputRef={register}
                          name={`needs.${optionKey}`}
                          data-test={`need-${optionKey}`}
                          defaultChecked={defaultValues.needs[optionKey]}
                        />
                      }
                      label={
                        activeCategoryMap[optionKey].inputCaption
                          ? activeCategoryMap[optionKey].inputCaption
                          : activeCategoryMap[optionKey].description
                      }
                    />
                  ))}
                </FormGroup>
                {!!errors.needs && (
                  <FormHelperText error>{errors.needs.message}</FormHelperText>
                )}

                <Typography
                  variant="h5"
                  className={classes.otherComments}
                  gutterBottom={!groceryPickup}>
                  Details
                </Typography>
                <Zoom in={groceryPickup} unmountOnExit>
                  <Typography variant="subtitle1" gutterBottom>
                    For grocery pickup, please provide the list of groceries
                    that you would like the volunteer to get. Please be as
                    specific as possible.
                  </Typography>
                </Zoom>
                <Grid container spacing={3}>
                  <Grid item xs={12}>
                    <TextField
                      name="otherDetails"
                      data-test="otherDetails"
                      multiline
                      placeholder="Please be as specific as possible."
                      fullWidth
                      rows="4"
                      variant="outlined"
                      inputRef={register}
                    />
                  </Grid>
                </Grid>

                {/* <Zoom in={hasFinancialComponent} unmountOnExit> */}
                <div>
                  <Divider className={classes.optionalDivider} />
                  <Typography variant="h5" gutterBottom>
                    Will you be able to pay for your items?
                  </Typography>
                  <Typography variant="body1" gutterBottom>
                    This service is free, but the items still cost money. Are
                    you able to pay for your items? If not, we will do our best
                    to match you with organizations and volunteers who can also
                    provide financial assistance.
                  </Typography>
                  <Controller
                    as={
                      <RadioGroup
                        aria-label="Need Financial Assistance"
                        component="fieldset">
                        <FormControlLabel
                          value="false"
                          control={<Radio />}
                          label="Yes, I can pay and only need help with the delivery."
                        />
                        <FormControlLabel
                          value="true"
                          control={<Radio />}
                          label="No, I need help paying for the items."
                        />
                      </RadioGroup>
                    }
                    control={control}
                    onChange={([event]) => event.target.value}
                    name="needFinancialAssistance"
                  />
                  {!!errors.needFinancialAssistance && (
                    <FormHelperText error>
                      {errors.needFinancialAssistance}
                    </FormHelperText>
                  )}
                </div>
                {/* </Zoom> */}

                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Immediacy of Need
                </Typography>
                <Typography variant="body1" gutterBottom>
                  Please let us know how urgently you need us to fulfill the
                  request. We will do our best to connect you with a volunteer
                  as soon as possible, however, we cannot guarantee anything
                  because we are dependent on volunteer availability.
                </Typography>
                <Controller
                  as={
                    <RadioGroup>
                      <FormControlLabel
                        value="1"
                        control={<Radio />}
                        label="Low"
                      />
                      <FormControlLabel
                        value="5"
                        control={<Radio />}
                        label="Medium - Not very urgent"
                      />
                      <FormControlLabel
                        value="10"
                        control={<Radio />}
                        label="High - Urgent"
                      />
                    </RadioGroup>
                  }
                  control={control}
                  name="immediacy"
                />

                {!!errors.immediacy && (
                  <FormHelperText error>
                    {errors.immediacy.message}
                  </FormHelperText>
                )}

                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Your Location
                </Typography>
                <Typography className={classes.intro}>
                  A rough location is needed to allow us to efficiently and
                  quickly find a match for your need. You can do this in three
                  ways: by entering your address in the address field, by
                  clicking the &quot;Detect Location&quot; button, or by
                  clicking on the map. If you decide to enter the address, we
                  will not save the actual address and instead use it to get the
                  location.
                </Typography>
                <Grid container spacing={3}>
                  <Grid item xs={12}>
                    <Card>
                      {requestLocationLoading ? (
                        <LoadingSpinner />
                      ) : (
                        <ClickableMap
                          locationInfo={requestLocation}
                          onLocationChange={handleLocationChange}
                        />
                      )}
                    </Card>
                  </Grid>
                </Grid>
                <Divider className={classes.optionalDivider} />
                <Typography variant="h5" gutterBottom>
                  Contact Information
                </Typography>
                <Typography gutterBottom>
                  To minimize exposing your contact information, we do not
                  display it unless a volunteer specifically requests to see it.
                  To further discourage any abuse, we do not display your last
                  name and also keep track of all the volunteers who have looked
                  up your contact information.
                </Typography>

                <Grid container spacing={2}>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="firstName"
                      data-test="firstName"
                      type="text"
                      label="First Name"
                      variant="outlined"
                      inputRef={register}
                      error={!!errors.firstName}
                      fullWidth
                      helperText={errors?.firstName?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="lastName"
                      data-test="lastName"
                      type="text"
                      label="Last Name"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.lastName}
                      helperText={errors?.firstName?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="phone"
                      data-test="phone"
                      type="text"
                      label="Phone Number"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.phone}
                      helperText={errors?.phone?.message}
                    />
                  </Grid>
                  <Grid item xs={12} sm={6}>
                    <TextField
                      name="email"
                      type="text"
                      data-test="email"
                      label="Email"
                      variant="outlined"
                      fullWidth
                      inputRef={register}
                      error={!!errors.email}
                      helperText={errors?.email?.message}
                    />
                  </Grid>
                </Grid>

                <Typography className={classes.warrantyInfo}>
                  Note: This website and all related work products are provided
                  &quot;AS IS&quot;. The provider of this service makes no other
                  warranties, express or implied, and hereby disclaims all
                  implied warranties, including any warranty of merchantability
                  and warranty of fitness for a particular purpose.
                </Typography>

                {dirty && !!Object.keys(errors).length && !isValid && (
                  <Typography variant="body2" className={classes.errorText}>
                    Please fix the errors above.
                  </Typography>
                )}

                <div className={classes.buttons}>
                  <Button
                    type="submit"
                    variant="contained"
                    color="primary"
                    data-test="submit-request"
                    disabled={isSubmitting}>
                    Submit Request
                  </Button>
                </div>
              </Container>
            </form>
          </Container>
        </div>
      </Paper>
    </Container>
  );
}
Example #21
Source File: NewNeedDialog.js    From e-Pola with MIT License 4 votes vote down vote up
function NewNeedDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()
  const [category, setCategory] = React.useState('')
  const [product, setProduct] = React.useState('')
  const {
    control,
    register,
    handleSubmit,
    formState: { isSubmitting, isValid }
  } = useForm({ mode: 'onChange' })

  useFirestoreConnect({
    collection: 'products',
    where: ['category', '==', category]
  })

  const products = useSelector(({ firestore: { ordered } }) => ordered.products)

  const handleChange = (event) => {
    setCategory(event.target.value)
    setProduct('')
  }

  const handleChangeProduct = ([event]) => {
    const selectedProduct = products.find(
      (product) => product.id === event.target.value
    )
    setProduct(selectedProduct)
    return event.target.value
  }

  const handleChangeUnit = ([event]) => {
    return event.target.value
  }

  return (
    <Dialog open={open} onClose={onRequestClose}>
      <DialogTitle id="new-need-dialog-title" color="secondary">
        <Trans>What do you want?</Trans>
      </DialogTitle>
      <form className={classes.root} onSubmit={handleSubmit(onSubmit)}>
        <DialogContent>
          <FormControl className={classes.selection}>
            <InputLabel id="catagories">
              <Trans>Category</Trans>
            </InputLabel>
            <Select
              labelId="catagories"
              id="catagories-list"
              value={category}
              onChange={handleChange}
              inputRef={register({
                required: true
              })}
              name="category"
              defaultValue="">
              <MenuItem value="dairy">
                <Trans>Dairy</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  alt="Dairy"
                  aria-label="emoji">
                  ??
                </span>
              </MenuItem>
              <MenuItem value="meat">
                <Trans>Meat, Seafood & Poultry</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  aria-label="emoji"
                  alt="Meat, Seafood & Poultry">
                  ???
                </span>
              </MenuItem>
              <MenuItem value="vegetables">
                <Trans>Vegetables</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  alt="Vegetables"
                  aria-label="emoji">
                  ???
                </span>
              </MenuItem>
              <MenuItem value="grains">
                <Trans>Grains</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  alt="Grains"
                  aria-label="emoji">
                  ??
                </span>
              </MenuItem>
              <MenuItem value="grocery">
                <Trans>Grocery Items</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  alt="Grocery Items"
                  aria-label="emoji">
                  ?
                </span>
              </MenuItem>
              <MenuItem value="pharmaceuticals">
                <Trans>Pharmacy Items</Trans>{' '}
                <span
                  className={classes.emojis}
                  role="img"
                  alt="Grocery Items"
                  aria-label="emoji">
                  ?
                </span>
              </MenuItem>
            </Select>
          </FormControl>
          <br />
          <br />
          <FormControl className={classes.selection}>
            <InputLabel id="product">
              <Trans>Products</Trans>
            </InputLabel>
            <Controller
              as={
                <Select
                  disabled={isEmpty(products)}
                  labelId="product"
                  name="products_id">
                  {!isEmpty(products) &&
                    products.map((product) => (
                      <MenuItem value={product.id} key={product.id}>
                        {product.name}
                      </MenuItem>
                    ))}
                </Select>
              }
              name="products_id"
              onChange={handleChangeProduct}
              rules={{ required: 'Product is required' }}
              control={control}
              defaultValue=""
            />
          </FormControl>
          <br />
          <br />
          <FormControl className={classes.selection}>
            <InputLabel id="amount">
              <Trans>How much?</Trans>
            </InputLabel>
            <Controller
              as={
                <Select disabled={!product} labelId="amount" name="amount">
                  {!!product &&
                    product.units.map((unit, i) => (
                      <MenuItem value={unit} key={i}>
                        {unit}
                      </MenuItem>
                    ))}
                </Select>
              }
              name="amount"
              onChange={handleChangeUnit}
              rules={{ required: 'How much is required' }}
              control={control}
              defaultValue=""
            />
          </FormControl>
          <TextField
            type="hidden"
            name="name"
            value={product && product.name}
            inputRef={register()}
          />
        </DialogContent>
        <DialogActions>
          <Button onClick={onRequestClose} color="secondary">
            <Trans>Cancel</Trans>
          </Button>
          <Button
            type="submit"
            color="primary"
            disabled={isSubmitting || !isValid}>
            {isSubmitting ? (
              <Trans>Requesting...</Trans>
            ) : (
              <Trans>Request</Trans>
            )}
          </Button>
        </DialogActions>
      </form>
    </Dialog>
  )
}
Example #22
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
UserForm = ({ isEditing, isProfile, user, onSubmitHandler, schema }) => {
  const { loading, success } = useSelector(
    (state) => ({
      loading: state.users.loading,
      success: state.users.success,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const { register, handleSubmit, errors, control, watch, setValue } = useForm({
    defaultValues: { ...user },
    resolver: yupResolver(schema),
  });

  useEffect(() => {
    if (success) {
      setValue('file', null);
    }
    return () => dispatch(usersCleanUp());
  }, [dispatch, success, setValue]);

  const invalidEmailMessage = useFormatMessage('UserForm.invalidEmail');

  const imagePreviewUrl =
    watch('file') && watch('file')[0]
      ? URL.createObjectURL(watch('file')[0])
      : user.logoUrl;

  const goBackMessage = useFormatMessage('UserForm.goBack');

  const pickAnotherFileMessage = useFormatMessage('UserForm.pickAnotherFile');
  const pickFileMessage = useFormatMessage('UserForm.pickFile');

  const emailMessage = useFormatMessage('UserForm.email');

  const adminMessage = useFormatMessage('UserForm.admin');

  return (
    <>
      <div className="tile is-ancestor">
        <div className="tile is-parent">
          <div className="card tile is-child">
            <header className="card-header">
              <p className="card-header-title">
                <span className="icon">
                  <i className="mdi mdi-account-edit default" />
                </span>
                {useFormatMessage('UserForm.userInfo')}
              </p>
            </header>
            <div className="card-content">
              <form onSubmit={handleSubmit(onSubmitHandler)}>
                {isEditing ? (
                  <div className="field is-horizontal">
                    <div className="field-label is-normal">
                      <label className="label">{emailMessage}</label>
                    </div>
                    <div className="field-body">
                      <div className="field">
                        <div className="control">
                          <input
                            type="text"
                            readOnly="readOnly"
                            className="input is-static"
                            name="email"
                            ref={register}
                          />
                        </div>
                      </div>
                    </div>
                  </div>
                ) : (
                  <>
                    <div className="field is-horizontal">
                      <div className="field-label is-normal">
                        <label className="label">{emailMessage}</label>
                      </div>
                      <div className="field-body">
                        <div className="field">
                          <div className="control">
                            <input
                              className={classNames(`input`, {
                                'is-danger': errors.email,
                              })}
                              ref={register}
                              name="email"
                            />
                          </div>
                        </div>
                      </div>
                    </div>
                    {errors.email && (
                      <div className="field is-horizontal">
                        <div className="field-label is-normal" />
                        <div className="field-body">
                          <ErrorMessage text={invalidEmailMessage} />
                        </div>
                      </div>
                    )}
                  </>
                )}

                <div className="field is-horizontal">
                  <div className="field-label is-normal">
                    <label className="label">
                      {useFormatMessage('UserForm.name')}
                    </label>
                  </div>
                  <div className="field-body">
                    <div className="field">
                      <div className="control">
                        <input
                          name="name"
                          id="name"
                          className={classNames('input', {
                            'is-danger': errors.name,
                          })}
                          ref={register}
                          type="text"
                        />
                      </div>
                    </div>
                  </div>
                </div>
                {errors.name && (
                  <div className="field is-horizontal">
                    <div className="field-label is-normal" />
                    <div className="field-body">
                      <ErrorMessage />
                    </div>
                  </div>
                )}
                <div className="field is-horizontal">
                  <div className="field-label is-normal">
                    <label className="label">
                      {useFormatMessage('UserForm.location')}
                    </label>
                  </div>
                  <div className="field-body">
                    <div className="field">
                      <div className="control">
                        <input
                          className="input"
                          type="text"
                          ref={register}
                          name="location"
                        />
                      </div>
                    </div>
                  </div>
                </div>
                {!isProfile && (
                  <div className="field has-check is-horizontal">
                    <div className="field-label">
                      <label className="label">{adminMessage}</label>
                    </div>
                    <div className="field-body">
                      <div className="field">
                        <div className="field">
                          <div className="control">
                            <label className="b-checkbox checkbox">
                              <input
                                type="checkbox"
                                name="isAdmin"
                                ref={register}
                              />
                              <span className="check is-primary" />
                            </label>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                )}

                <div className="field is-horizontal">
                  <div className="field-label is-normal">
                    <label className="label">
                      {useFormatMessage('UserForm.created')}
                    </label>
                  </div>
                  <div className="field-body">
                    <div className="field">
                      <Controller
                        control={control}
                        name="createdAt"
                        render={({ onChange, name, value }) => (
                          <DatePicker
                            name={name}
                            onChange={onChange}
                            date={new Date(value)}
                          />
                        )}
                      />
                    </div>
                  </div>
                </div>

                <hr />

                <div className="field is-horizontal">
                  <div className="field-label is-normal">
                    <label className="label">
                      {useFormatMessage('UserForm.logo')}
                    </label>
                  </div>
                  <div className="field-body">
                    <div className="field">
                      <div className="file has-name">
                        <label className="file-label">
                          <input
                            className="file-input"
                            type="file"
                            name="file"
                            ref={register}
                            accept="image/*"
                          />
                          <span className="file-cta">
                            <span className="file-icon">
                              <i className="mdi mdi-upload" />
                            </span>
                            <span className="file-label">
                              {watch('file') && watch('file').file
                                ? pickAnotherFileMessage
                                : pickFileMessage}
                            </span>
                          </span>
                          <span className="file-name">
                            {watch('file') && watch('file')[0]?.name}
                          </span>
                        </label>
                      </div>
                    </div>
                  </div>
                </div>

                <hr />
                <div className="field is-horizontal">
                  <div className="field-label" />
                  <div className="field-body">
                    <div className="field">
                      <div className="field is-grouped">
                        <div className="control">
                          <button
                            type="submit"
                            className={`button is-primary ${
                              loading && 'is-loading'
                            }`}
                          >
                            <span>{useFormatMessage('UserForm.submit')}</span>
                          </button>
                        </div>
                        {!isProfile && (
                          <Link to={paths.USERS} className="button">
                            {goBackMessage}
                          </Link>
                        )}
                      </div>
                    </div>
                  </div>
                </div>
              </form>
            </div>
          </div>
        </div>
        <div className="tile is-parent preview">
          <div className="card tile is-child">
            <header className="card-header">
              <p className="card-header-title">
                <span className="icon">
                  <i className="mdi mdi-account default" />
                </span>
                {useFormatMessage('UserForm.userPreview')}
              </p>
            </header>
            <div className="card-content">
              {imagePreviewUrl && (
                <>
                  <div className="is-user-avatar image has-max-width is-aligned-center">
                    <img
                      className="user-avatar"
                      src={imagePreviewUrl}
                      alt="User profile logo preview"
                    />
                  </div>
                  <hr />
                </>
              )}

              {!isEditing && (
                <div className="field">
                  <label className="label">{emailMessage}</label>
                  <div className="control is-clearfix">
                    <input
                      data-testid="email"
                      type="text"
                      readOnly="readOnly"
                      className="input is-static"
                      value={watch('email')}
                    />
                  </div>
                </div>
              )}

              <div className="field">
                <label className="label">
                  {useFormatMessage('UserForm.name')}
                </label>
                <div className="control is-clearfix">
                  <input
                    data-testid="name"
                    type="text"
                    readOnly="readOnly"
                    className="input is-static"
                    value={watch('name')}
                  />
                </div>
              </div>

              <div className="field">
                <label className="label">
                  {useFormatMessage('UserForm.location')}
                </label>
                <div className="control is-clearfix">
                  <input
                    data-testid="location"
                    type="text"
                    readOnly="readOnly"
                    className="input is-static"
                    value={watch('location')}
                  />
                </div>
              </div>

              {!isProfile && (
                <div className="field">
                  <label className="label">{adminMessage}</label>
                  <div className="control is-clearfix" data-testid="admin">
                    {watch('isAdmin') ? (
                      <span className="icon">
                        <i className="mdi mdi-check" />
                      </span>
                    ) : (
                      <span className="icon">
                        <i className="mdi mdi-close" />
                      </span>
                    )}
                  </div>
                </div>
              )}

              <div className="field">
                <label className="label">
                  {useFormatMessage('UserForm.created')}
                </label>
                <div className="control is-clearfix" data-testid="date">
                  <p className="date">
                    {useFormatDate(watch('createdAt'), {
                      weekday: 'short',
                      year: 'numeric',
                      month: 'short',
                      day: 'numeric',
                    })}
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}
Example #23
Source File: ProfileDetails.js    From flame-coach-web with MIT License 4 votes vote down vote up
ProfileDetails = ({
  userDetails,
  enablePersonalData,
  saveContactInformationHandler,
  savePersonalInformationHandler,
  updateUserDetailsHandler,
  className
}) => {
  const classes = useStyles();

  logDebug("ProfileDetails", "render", "userDetails", userDetails);

  const formContactInformation = useForm();
  const formPersonalInformation = useForm();

  return (
    <Box component="div">
      <Card>
        <CardContent>
          <CardHeader
            title="Profile"
            subheader="Use this section to update information related with you"
          />
          <form
            autoComplete="off"
            onSubmit={(event) => {
              event.preventDefault();
              formContactInformation.handleSubmit(
                saveContactInformationHandler
              )(event);
            }}
            className={clsx(classes.root, className)}
          >
            <Accordion defaultExpanded>
              <AccordionSummary
                expandIcon={<ExpandMoreIcon />}
                aria-controls="contactInfo-content"
                id="contactInfo-header"
              >
                <Typography component="h2">Contact information</Typography>
              </AccordionSummary>
              <AccordionDetails>
                <Grid
                  container
                  spacing={3}
                >
                  <Grid
                    item
                    md={6}
                    xs={12}
                  >
                    <TextField
                      fullWidth
                      label="First name"
                      name="firstName"
                      helperText="First name is required"
                      error={Boolean(formContactInformation.errors.firstName)}
                      onChange={updateUserDetailsHandler}
                      inputRef={formContactInformation.register({ required: true })}
                      value={userDetails.firstName}
                      variant="outlined"
                    />
                  </Grid>
                  <Grid
                    item
                    md={6}
                    xs={12}
                  >
                    <TextField
                      fullWidth
                      label="Last name"
                      name="lastName"
                      onChange={updateUserDetailsHandler}
                      error={Boolean(formContactInformation.errors.lastName)}
                      inputRef={formContactInformation.register({ required: true })}
                      value={userDetails.lastName}
                      variant="outlined"
                    />
                  </Grid>
                  <Grid
                    item
                    md={6}
                    xs={12}
                  >
                    <TextField
                      fullWidth
                      label="Email Address"
                      name="email"
                      type="email"
                      disabled
                      onChange={updateUserDetailsHandler}
                      value={userDetails.email}
                      variant="outlined"
                    />
                  </Grid>
                  <Grid
                    item
                    md={2}
                    xs={6}
                  >
                    <TextField
                      fullWidth
                      label="Code"
                      name="phoneCode"
                      error={Boolean(formContactInformation.errors.phoneCode)}
                      inputRef={formContactInformation.register({
                        required: false,
                        pattern: "^[+]*[0-9]{1,4}$"
                      })}
                      onChange={updateUserDetailsHandler}
                      value={userDetails.phoneCode}
                      variant="outlined"
                    />
                  </Grid>
                  <Grid
                    item
                    md={4}
                    xs={6}
                  >
                    <TextField
                      fullWidth
                      label="Phone Number"
                      name="phoneNumber"
                      inputRef={formContactInformation.register}
                      onChange={updateUserDetailsHandler}
                      type="number"
                      value={userDetails.phoneNumber}
                      variant="outlined"
                    />
                  </Grid>
                  <Grid
                    item
                    md={6}
                    xs={12}
                  >
                    <FormControl fullWidth variant="outlined">
                      <InputLabel>Country</InputLabel>
                      <Controller
                        render={(renderProps) => (
                          <Select
                            key="select_country"
                            labelId="country"
                            label="Country"
                            name="country"
                            data-testid="country"
                            value={userDetails.country}
                            onChange={(event) => {
                              renderProps.onChange(updateUserDetailsHandler(event));
                            }}
                          >
                            <MenuItem key="default" value="">Country</MenuItem>
                            {
                              countries.map((country) => (
                                <MenuItem key={country.code} value={country.code}>
                                  {country.name}
                                </MenuItem>
                              ))
                            }
                          </Select>
                        )}
                        control={formContactInformation.control}
                        defaultValue={userDetails.country}
                        name="country"
                      />
                    </FormControl>
                  </Grid>
                </Grid>
              </AccordionDetails>
              <Divider />
              <AccordionActions>
                <Box
                  display="flex"
                  justifyContent="flex-end"
                  p={1}
                >
                  <Button
                    color="primary"
                    variant="contained"
                    type="submit"
                    name="contactInfo-save"
                  >
                    Save
                  </Button>
                </Box>
              </AccordionActions>
            </Accordion>
          </form>
          {enablePersonalData
            ? (
              <form
                autoComplete="off"
                onSubmit={(event) => {
                  event.preventDefault();
                  formPersonalInformation.handleSubmit(
                    savePersonalInformationHandler
                  )(event);
                }}
                className={clsx(classes.root, className)}
              >
                <Accordion>
                  <AccordionSummary
                    expandIcon={<ExpandMoreIcon />}
                    aria-controls="contactInfo-content"
                    id="contactInfo-header"
                  >
                    <Typography component="h2">Personal information</Typography>
                  </AccordionSummary>
                  <AccordionDetails>
                    <Grid
                      container
                      spacing={3}
                    >
                      <Grid
                        item
                        xs={6}
                      >
                        <FormControl fullWidth variant="outlined">
                          <InputLabel>Measure Type</InputLabel>
                          <Controller
                            render={(renderProps) => (
                              <Select
                                labelId="measureType"
                                label="Measure Type"
                                name="measureType"
                                value={userDetails.measureType}
                                onChange={(event) => {
                                  renderProps.onChange(updateUserDetailsHandler(event));
                                }}
                              >
                                <MenuItem value="KG_CM">Kg/cm</MenuItem>
                                <MenuItem value="LBS_IN">Lbs/in</MenuItem>
                              </Select>
                            )}
                            control={formPersonalInformation.control}
                            defaultValue={userDetails.measureType}
                            name="measureType"
                          />
                        </FormControl>
                      </Grid>
                      <Grid
                        item
                        xs={6}
                      >
                        <FormControl fullWidth variant="outlined">
                          <InputLabel>Gender</InputLabel>
                          <Controller
                            render={(renderProps) => (
                              <Select
                                labelId="gender"
                                label="Gender"
                                name="gender"
                                value={userDetails.gender}
                                onChange={(event) => {
                                  renderProps.onChange(updateUserDetailsHandler(event));
                                }}
                              >
                                <MenuItem value="">Gender</MenuItem>
                                <MenuItem value="M">Male</MenuItem>
                                <MenuItem value="F">Female</MenuItem>
                                <MenuItem value="O">Other</MenuItem>
                              </Select>
                            )}
                            control={formPersonalInformation.control}
                            defaultValue={userDetails.gender}
                            name="gender"
                          />
                        </FormControl>
                      </Grid>
                      <Grid
                        item
                        xs={6}
                      >
                        <TextField
                          fullWidth
                          helperText="Please specify your weight"
                          label="Weight"
                          name="weight"
                          type="number"
                          inputProps={{
                            step: 0.05,
                            min: 0
                          }}
                          inputRef={formPersonalInformation.register}
                          onChange={updateUserDetailsHandler}
                          value={userDetails.weight}
                          variant="outlined"
                        />
                      </Grid>
                      <Grid
                        item
                        xs={6}
                      >
                        <TextField
                          fullWidth
                          helperText="Please specify your height"
                          label="Height"
                          name="height"
                          type="number"
                          inputProps={{
                            step: 0.05,
                            min: 0
                          }}
                          inputRef={formPersonalInformation.register}
                          onChange={updateUserDetailsHandler}
                          value={userDetails.height}
                          variant="outlined"
                        />
                      </Grid>
                    </Grid>
                  </AccordionDetails>
                  <Divider />
                  <AccordionActions>
                    <Box
                      display="flex"
                      justifyContent="flex-end"
                      p={2}
                    >
                      <Button
                        color="primary"
                        variant="contained"
                        type="submit"
                        name="personalInfo-save"
                      >
                        Save
                      </Button>
                    </Box>
                  </AccordionActions>
                </Accordion>
              </form>
            )
            : null}
        </CardContent>
      </Card>
    </Box>
  );
}
Example #24
Source File: createJob.page.js    From hiring-system with GNU General Public License v3.0 4 votes vote down vote up
CreateJob = () => {
  const { handleSubmit, watch, errors, control, getValues } = useForm({
    mode: "all",
    reValidateMode: "onChange",
  });
  const [selectedPostDate, setSelectedPostDate] = useState();
  const watchDate = watch("jobPostDate");

  const onSubmit = (data) => {
    // code to submit form
    console.log(data);
  };

  useEffect(() => {
    if (!getValues("jobPostDate")) {
      return;
    }
    const selectedDate = new Date(getValues("jobPostDate"));
    setSelectedPostDate(selectedDate.toDateString());
  }, [watchDate]);

  return (
    <>
      <div className="create-job-container" style={styles.pageContainer}>
        <div>
          <Card style={styles.cardContainer}>
            <CardBody>
              <CardTitle style={styles.section}>
                <h3> Create New Job</h3>
              </CardTitle>
              <Form
                style={styles.formContainer}
                onSubmit={handleSubmit(onSubmit)}
              >
                <FormGroup>
                  <Controller
                    as={Input}
                    type="text"
                    name="jobTitle"
                    control={control}
                    rules={{ required: true }}
                    placeholder="Enter Job Title"
                  />
                  {errors.jobTitle && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup>
                  <Controller
                    as={Input}
                    type="text"
                    name="jobDesc"
                    control={control}
                    rules={{ required: true }}
                    placeholder="Enter Job Description"
                  />
                  {errors.jobDesc && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup>
                  <Controller
                    name="skills"
                    as={Select}
                    options={skills}
                    control={control}
                    rules={{ required: true }}
                    isMulti
                    placeholder="Select Skills"
                  />
                  {errors.skills && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup>
                  <Controller
                    as={Input}
                    type="text"
                    name="companyName"
                    control={control}
                    rules={{ required: true }}
                    placeholder="Enter Company Name"
                  />
                  {errors.companyName && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup style={styles.relativeEle}>
                  <Input
                    type="text"
                    name="jobPostDateInput"
                    placeholder="Select Job Post Date"
                    value={selectedPostDate}
                  />
                  {errors.jobPostDate && (
                    <span className="error-text">This field is required</span>
                  )}
                  <Controller
                    name="jobPostDate"
                    as={DatePicker}
                    control={control}
                    rules={{ required: true }}
                    maxDate={new Date()}
                    clearIcon={null}
                    className="app-date-custom-style"
                  />
                </FormGroup>
                <FormGroup>
                  <Controller
                    as={Input}
                    type="text"
                    name="workLocation"
                    control={control}
                    rules={{ required: true }}
                    placeholder="Enter Work Location"
                  />
                  {errors.workLocation && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup>
                  <Controller
                    name="benefits"
                    as={Select}
                    options={benefits}
                    control={control}
                    rules={{ required: true }}
                    placeholder="Select Benefits"
                    isMulti
                  />
                  {errors.benefits && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>
                <FormGroup>
                  <Controller
                    name="workVisa"
                    as={Select}
                    options={visaSelection}
                    control={control}
                    rules={{ required: true }}
                    placeholder="Will Sponsor Work Visa"
                  />
                  {errors.workVisa && (
                    <span className="error-text">This field is required</span>
                  )}
                </FormGroup>

                <div style={styles.section}>
                  <Button type="submit" variant="primary">
                    Create New Job
                  </Button>
                </div>
              </Form>
            </CardBody>
          </Card>
        </div>
      </div>
    </>
  );
}
Example #25
Source File: EventEditor.jsx    From club-connect with GNU General Public License v3.0 4 votes vote down vote up
EventEditor = (props) => {
  const { formType, submitFunction, submitting } = props;

  const router = useRouter();
  const { register, handleSubmit, control, watch, reset } = useForm();
  const useCustomInternalName = watch('useCustomInternalName');

  const [bannerFile, setBannerFile] = useState(null);
  const [presenterImageFile, setPresenterImageFile] = useState(null);
  const [editorReady, setEditorReady] = useState(formType !== 'edit');

  useEffect(async () => {
    if (formType === 'edit') {
      // Get event ID from query string
      const parsedQueryString = queryString.parse(location.search);
      if (!parsedQueryString.id) {
        toastErrorCenter('No event ID was specified for editing.');
        await router.push('/events');
        return;
      }

      const eventId = parsedQueryString.id;

      // Get the event data to edit
      let res;
      try {
        res = await axios.get(`${API_ROOT}/events/${eventId}`);
      } catch (err) {
        toastErrorCenter('An error occurred while getting the event data.');
        await router.push(`/events/${eventId}`);
        return;
      }

      // Load event data into the form
      reset(res.data);
      setEditorReady(true);
    }
  }, []);

  // Prepare form data to be submitted
  const prepareFormData = (submittedData) => {
    const eventData = cloneDeep(submittedData);

    // Set empty string values and undefined to null
    for (const [key, value] of Object.entries(eventData)) {
      if (value === '' || value === undefined) {
        eventData[key] = null;
      }
    }

    // Convert datetimes to ISO strings
    if (eventData.startDateTime) {
      eventData.startDateTime = new Date(eventData.startDateTime).toISOString();
    }

    if (eventData.endDateTime) {
      eventData.endDateTime = new Date(eventData.endDateTime).toISOString();
    }

    // Prepare FormData by serializing form data to JSON and appending files if they exist
    // Remove files from form data before serializing
    delete eventData.banner;
    delete eventData.presenterImage;

    const formData = new FormData();
    formData.append('formDataJson', JSON.stringify(eventData));
    if (bannerFile) {
      formData.append('bannerFile', bannerFile);
    }
    if (presenterImageFile) {
      formData.append('presenterImageFile', presenterImageFile);
    }

    // Submit the form
    submitFunction(formData);
  };

  return (
    <>
      <form onSubmit={handleSubmit(prepareFormData)}>
        <div className={formStyles.labeledInput}>
          <label htmlFor="title">Title*</label>
          <input
            type="text"
            id="title"
            name="title"
            disabled={!editorReady || submitting}
            placeholder={!editorReady ? 'Loading...' : ''}
            ref={register}
            required
          />
        </div>

        {(formType === 'create' || formType === 'edit') && (
          <div className={eventEditorStyles.presenterInputs}>
            <div className={formStyles.labeledInput}>
              <label htmlFor="presenter">Presenter</label>
              <input
                type="text"
                id="presenter"
                name="presenter"
                disabled={!editorReady || submitting}
                ref={register}
              />
            </div>
            <div className={formStyles.labeledInput}>
              <label
                className={eventEditorStyles.presenterImageLabel}
                htmlFor="presenterImage"
              >
                {windowSupported() && window.innerWidth <= 700
                  ? 'Presenter Image'
                  : 'Image'}
              </label>
              <Controller
                name="presenterImage"
                control={control}
                render={({ onChange }) => (
                  <PresenterImageUpload
                    onChange={onChange}
                    setPresenterImageFile={setPresenterImageFile}
                  />
                )}
              />
            </div>
          </div>
        )}

        <div className={formStyles.labeledInput}>
          <label htmlFor="banner">
            Banner (Will be resized to a 16:9 aspect ratio)
            {formType === 'request' && '*'}
          </label>
          <Controller
            name="banner"
            control={control}
            render={({ onChange }) => (
              <BannerUpload onChange={onChange} setBannerFile={setBannerFile} />
            )}
          />
        </div>

        <MuiPickersUtilsProvider utils={DayJsUtils}>
          <div className={formStyles.twoColumn}>
            <div className={formStyles.labeledInput}>
              <label htmlFor="startDateTime">
                Start Date and Time{formType === 'request' && '*'}
              </label>
              <Controller
                control={control}
                name="startDateTime"
                id="startDateTime"
                as={
                  <DateTimePicker
                    defaultValue={null}
                    variant="dialog"
                    format="MM/DD/YYYY, h:mm A"
                    TextFieldComponent={(props) => <input {...props} />}
                    readOnly={!editorReady || submitting}
                    required={formType === 'request'}
                    emptyLabel
                    showTodayButton
                  />
                }
              />
            </div>

            <div className={formStyles.labeledInput}>
              <label htmlFor="endDateTime">
                End Date and Time{formType === 'request' && '*'}
              </label>
              <Controller
                control={control}
                name="endDateTime"
                id="endDateTime"
                as={
                  <DateTimePicker
                    variant="dialog"
                    format="MM/DD/YYYY, h:mm A"
                    TextFieldComponent={(props) => <input {...props} />}
                    readOnly={!editorReady || submitting}
                    required={formType === 'request'}
                    emptyLabel
                    showTodayButton
                  />
                }
              />
            </div>
          </div>
        </MuiPickersUtilsProvider>

        <div className={formStyles.labeledInput}>
          <label htmlFor="eventLocation">
            Location (Either Online or a building's address and room number)
            {formType === 'request' && '*'}
          </label>
          <input
            type="text"
            id="eventLocation"
            name="eventLocation"
            disabled={!editorReady || submitting}
            required={formType === 'request'}
            ref={register}
          />
        </div>

        <div className={formStyles.labeledInput}>
          <label htmlFor="externalLink">
            External Link (This can be a direct Zoom/Google Meet link)
            {formType === 'request' && '*'}
          </label>
          <input
            type="text"
            id="externalLink"
            name="externalLink"
            disabled={!editorReady || submitting}
            required={formType === 'request'}
            ref={register}
          />
        </div>

        <div className={formStyles.labeledInput}>
          <label htmlFor="externalLinkButtonText">
            External Link Button Text (The green button on the event page)
            {formType === 'request' && '*'}
          </label>
          <input
            type="text"
            id="externalLinkButtonText"
            name="externalLinkButtonText"
            disabled={!editorReady || submitting}
            required={formType === 'request'}
            ref={register}
          />
        </div>

        <div className={formStyles.labeledInput}>
          <label htmlFor="shortDescription">
            Short Event Description (Under 250 characters)
            {formType === 'request' && '*'}
          </label>
          <input
            type="text"
            id="shortDescription"
            name="shortDescription"
            disabled={!editorReady || submitting}
            required={formType === 'request'}
            ref={register}
          />
        </div>

        <div className={formStyles.labeledInput}>
          <label htmlFor="longDescription">
            Long Description{formType === 'request' && '*'}
          </label>
          <textarea
            rows="10"
            id="longDescription"
            name="longDescription"
            disabled={!editorReady || submitting}
            required={formType === 'request'}
            ref={register}
          />
        </div>

        <div
          className={`${formStyles.customInternalName} ${formStyles.checkbox} ${formStyles.checkboxCentered}`}
        >
          <input
            type="checkbox"
            name="useCustomInternalName"
            id="useCustomInternalName"
            disabled={!editorReady || submitting}
            ref={register}
          />
          <label htmlFor="useCustomInternalName">
            Use Custom Internal Name
          </label>
        </div>

        {useCustomInternalName && (
          <div className={`${formStyles.labeledInput}`}>
            <label htmlFor="internalName">
              Internal Name (must-be-lowercase-kebab-case-like-this)*
            </label>
            <input
              type="text"
              id="internalName"
              name="internalName"
              pattern="^([a-z][a-z0-9]*)(-[a-z0-9]+)*$"
              disabled={!editorReady || submitting}
              required={useCustomInternalName}
              ref={register}
            />
          </div>
        )}

        {formType === 'create' && (
          <Button
            classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
            type="submit"
            disabled={!editorReady || submitting}
          >
            {submitting ? 'Creating Event...' : 'Create Event'}
          </Button>
        )}

        {formType === 'request' && (
          <Button
            classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
            type="submit"
            disabled={!editorReady || submitting}
          >
            {submitting ? 'Submitting Request...' : 'Submit Request'}
          </Button>
        )}

        {formType === 'edit' && (
          <Button
            classNamePassed={`${formStyles.formButton} ${commonStyles.actionButton}`}
            type="submit"
            disabled={!editorReady || submitting}
          >
            {submitting ? 'Saving...' : 'Save Changes'}
          </Button>
        )}
      </form>
    </>
  );
}
Example #26
Source File: AddEditAuditoria.jsx    From core-audit with MIT License 4 votes vote down vote up
AddEditAuditoria = ({history})=> {

    
    const refFire = useFirestore();
    const [iglesias, setIglesias] = useState([])


    const { register, handleSubmit,control, formState:{ errors } } = useForm({
        resolver: yupResolver(schema)
    })

    const crear = async (datos) => {
        console.log(datos)
        await refFire.collection('auditorias').doc().set(datos)
        toast('Auditoria Creada.')
        history.push('/auditorias')

    }


    const onSubmit = (datos)=> {
        crear(datos)
    }

    const onCancelar = ()=> {
        history.push('/auditorias')
    }

    useEffect(() => {
        const traerDatos = async () => {
            const temporales = []
            const snapshot = await refFire.collection('iglesias').get()
            snapshot.docs.forEach((doc)=>{
                const elem = {
                    id: doc.id,
                    ...doc.data(),
                    value: doc.id,
                    label: doc.data().nombre
                }
                temporales.push(elem)
            })
            setIglesias(temporales)
        }

        traerDatos()

    }, [refFire])

    return (
        <div className="card">
            <div className="card-body">
                <form onSubmit={handleSubmit(onSubmit)}>
                    
                    <div className="input-gruop">
                            
                        <label>Fecha</label>
                        <input className="form-control" type="date" {...register('fecha')} />
                        { errors.nombre?.message}
                    </div>
                    <div className="input-gruop">
                            
                        <label>Activo</label>
                        <input value="0" type="radio"  {...register('activo')} />
                        <label>Inactivo</label>
                        <input value="1" type="radio"  {...register('activo')} />
                    </div>
                    <div className="input-gruop">
                            
                        <label>Actual</label>
                        <input value="0" type="radio"  {...register('actual')} />
                        <label>No actual</label>
                        <input value="1" type="radio"  {...register('actual')} />
                    </div>
                    <Controller
                        name="iglesia"
                        control={control}
                        render={({field}) => <Select
                        {...field}
                        options={iglesias}
                        />}
                    />

                    <button className="btn btn-primary" type="submit" >Guardar</button>
                    <button className="btn btn-warning" type="button" onClick={() => onCancelar()}>Cancelar</button>
                </form>
            </div>
        </div>
    )
}