@hookform/resolvers/yup#yupResolver JavaScript Examples

The following examples show how to use @hookform/resolvers/yup#yupResolver. 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: SignIn.jsx    From saasgear with MIT License 6 votes vote down vote up
function SignIn() {
  useDocumentHeader({ title: 'Sign In' });
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(SignInSchema),
  });
  const [loginMutation, { error, loading }] = useMutation(loginQuery);
  const history = useHistory();

  async function onSubmit(params) {
    try {
      const { data } = await loginMutation({ variables: params });
      if (data?.login) {
        history.push('/');
      }
    } catch (e) {
      console.log(e);
    }

    return false;
  }

  return (
    <SignUpFormWrapper>
      <SignUpFormLeft>
        <SignInForm
          onSubmit={handleSubmit(onSubmit)}
          register={register}
          formErrors={formErrors}
          apiError={error?.message}
          isSubmitting={loading}
        />
      </SignUpFormLeft>
      <SignUpAds>
        <AuthAdsArea />
      </SignUpAds>
    </SignUpFormWrapper>
  );
}
Example #2
Source File: PasswordSetting.jsx    From saasgear with MIT License 6 votes vote down vote up
PasswordSetting = () => {
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(PasswordSchema),
  });
  const [changePasswordMutation, { error, loading }] = useMutation(changePasswordQuery);
  const [isOpen, setIsOpen] = useState(false);

  async function onSubmit(params) {
    const { data } = await changePasswordMutation({ variables: params });
    if (data?.changePassword) {
      toast.success('Change password successfully!')
    }
  }

  return (
    <Wrapper expand={isOpen}>
      <Header onClick={() => setIsOpen(!isOpen)}>
        <SubTitleWrapper>
          <SubTitle>Change Password</SubTitle>
          <SubDesc>Forgot your password, find back in seconds</SubDesc>
        </SubTitleWrapper>
        <ActionWrapper>
          <ActionItem mobile><SettingIcon /></ActionItem>
          <ActionItem desktop>Update Password</ActionItem>
          <ArrowDown24IconStyle expand={isOpen ? 1 : 0} />
        </ActionWrapper>
      </Header>
      <SecurityForm
        onSubmit={handleSubmit(onSubmit)}
        register={register}
        formErrors={formErrors}
        apiError={error?.message}
        isSubmitting={loading}
      />
    </Wrapper>
  )
}
Example #3
Source File: TeamDetail.jsx    From saasgear with MIT License 6 votes vote down vote up
export default function TeamDetail({ team }) {
  const history = useHistory();
  const dispatch = useDispatch();
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(TeamSchema),
    defaultValues: {
      teamName: team?.teamName,
      teamID: team?.teamID,
    },
  });
  const [createTeamMutation, { loading, error }] = useMutation(createTeamQuery);

  async function createTeam({ teamName, teamID }) {
    const { data, errors } = await createTeamMutation({
      variables: { name: teamName, alias: teamID },
    });
    if (data?.createTeam) {
      const { id, name, alias } = data.createTeam;
      dispatch(addNew({ data: { id, teamName: name, teamID: alias } }));
      if (!errors) {
        history.replace('/teams');
      }
    }
  }

  return (
    <ContentPage>
      <TitleContent>Team Detail</TitleContent>
      <TeamForm
        onSubmit={handleSubmit(createTeam)}
        register={register}
        formErrors={formErrors}
        loading={loading}
        isEdit={!!team}
      />
      {error?.message && <ErrorText>{error.message}</ErrorText>}
    </ContentPage>
  );
}
Example #4
Source File: ResetPassword.jsx    From saasgear with MIT License 5 votes vote down vote up
function ResetPassword() {
  useDocumentHeader({ title: 'Reset password' });
  const query = getQueryParam();
  const history = useHistory();
  const token = query.get('token');
  const { register, handleSubmit, errors } = useForm({
    resolver: yupResolver(ResetPasswordSchema),
  });
  const [loginMutation, { error, loading }] = useMutation(resetPasswordQuery);

  useEffect(() => {
    if (!token) {
      history.push('/auth/signin');
    }
  }, [token]);

  async function onSubmit({ password, passwordConfirmation }) {
    const { data } = await loginMutation({
      variables: {
        token,
        password,
        confirmPassword: passwordConfirmation,
      },
    });
    if (data?.resetPassword) {
      toast.success('Change password successfully!');
      history.push('/auth/signin');
    }
  }
  return (
    <ForgotPasswordWrapper>
      <Overlay />
      <ForgotPasswordContainer>
        <ResetPasswordForm
          onSubmit={handleSubmit(onSubmit)}
          register={register}
          errors={errors}
          apiError={error?.message}
          isSubmiting={loading}
        />
        <SquareIconTop>
          <img src={squareRadiusTop} alt="" />
        </SquareIconTop>
        <SmallSquareBottom>
          <img src={squareRadiusTopPrimary} alt="" />
        </SmallSquareBottom>
        <SmallSquareTop>
          <img src={squareRadiusTopPrimarySmall} alt="" />
        </SmallSquareTop>
        <SmallSquareGrid>
          <img src={squareGrid} alt="" />
        </SmallSquareGrid>
        <SquareIconBottom>
          <img src={squareRadiusTopBig} alt="" />
        </SquareIconBottom>
        <CircleIcon>
          <img src={circleSmall} alt="" />
        </CircleIcon>
      </ForgotPasswordContainer>
    </ForgotPasswordWrapper>
  );
}
Example #5
Source File: Step1.js    From ultimate-react-hook-form-form with MIT License 5 votes vote down vote up
Step1 = () => {
  const { setValues, data } = useData();
  const history = useHistory();
  const { register, handleSubmit, errors } = useForm({
    defaultValues: { firstName: data.firstName, lastName: data.lastName },
    mode: "onBlur",
    resolver: yupResolver(schema),
  });

  const onSubmit = (data) => {
    history.push("./step2");
    setValues(data);
  };

  return (
    <MainContainer>
      <Typography component="h2" variant="h5">
        ? Step 1
      </Typography>
      <Form onSubmit={handleSubmit(onSubmit)}>
        <Input
          {...register('parentName')}
          id="firstName"
          type="text"
          label="First Name"
          name="firstName"
          error={!!errors.firstName}
          helperText={errors?.firstName?.message}
        />
        <Input
          ref={register}
          id="lastName"
          type="text"
          label="Last Name"
          name="lastName"
          error={!!errors.lastName}
          helperText={errors?.lastName?.message}
        />
        <PrimaryButton>Next</PrimaryButton>
      </Form>
    </MainContainer>
  );
}
Example #6
Source File: NameForm.jsx    From minihackathon-2022 with MIT License 5 votes vote down vote up
function NameForm({ formKey, handleSubmitFunc, width }) {
	const {
		register,
		handleSubmit,
		formState: { errors },
	} = useForm({
		resolver: yupResolver(memberSchema),
	});

	useEffect(() => {
		handleSubmitFunc &&
			handleSubmitFunc(formKey, () => {
				return new Promise((resolve, reject) => {
					handleSubmit(
						(data) => {
							resolve(data);
						},
						() => {
							resolve(null);
						}
					)();
				});
			});
	}, []); // eslint-disable-line react-hooks/exhaustive-deps

	return (
		<div className="h-full" style={{ width: width || "20%" }}>
			<h1 className="text-xl font-bold text-center">Team details</h1>
			<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
				Team Name
			</label>
			<input
				{...register("teamName")}
				type="text"
				placeholder="Team Name"
				className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
			/>
			<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
				{errors.teamName?.message}
			</p>

			<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
				Team Size
			</label>
			<select
				{...register("count")}
				defaultValue=""
				className="border-2 border-black rounded mb-[0.1em] py-1 px-1 cursor-pointer w-full"
			>
				<option value="0">Choose</option>
				<option value="3">3</option>
				<option value="4">4</option>
			</select>
			<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
				{errors.count?.message}
			</p>
		</div>
	);
}
Example #7
Source File: Login.jsx    From react-recoil-jwt-authentication-example with MIT License 5 votes vote down vote up
function Login({ history }) {
    const auth = useRecoilValue(authAtom);
    const userActions = useUserActions();

    useEffect(() => {
        // redirect to home if already logged in
        if (auth) history.push('/');

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // form validation rules 
    const validationSchema = Yup.object().shape({
        username: Yup.string().required('Username is required'),
        password: Yup.string().required('Password is required')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // get functions to build form with useForm() hook
    const { register, handleSubmit, setError, formState } = useForm(formOptions);
    const { errors, isSubmitting } = formState;

    function onSubmit({ username, password }) {
        return userActions.login(username, password)
            .catch(error => {
                setError('apiError', { message: error });
            });
    }

    return (
        <div className="col-md-6 offset-md-3 mt-5">
            <div className="alert alert-info">
                Username: test<br />
                Password: test
            </div>
            <div className="card">
                <h4 className="card-header">Login</h4>
                <div className="card-body">
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-group">
                            <label>Username</label>
                            <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.username?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Password</label>
                            <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.password?.message}</div>
                        </div>
                        <button disabled={isSubmitting} className="btn btn-primary">
                            {isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Login
                        </button>
                        {errors.apiError &&
                            <div className="alert alert-danger mt-3 mb-0">{errors.apiError?.message}</div>
                        }
                    </form>
                </div>
            </div>
        </div>
    )
}
Example #8
Source File: register.jsx    From next-js-11-registration-login-example with MIT License 5 votes vote down vote up
function Register() {
    const router = useRouter();

    // form validation rules 
    const validationSchema = Yup.object().shape({
        firstName: Yup.string()
            .required('First Name is required'),
        lastName: Yup.string()
            .required('Last Name is required'),
        username: Yup.string()
            .required('Username is required'),
        password: Yup.string()
            .required('Password is required')
            .min(6, 'Password must be at least 6 characters')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // get functions to build form with useForm() hook
    const { register, handleSubmit, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit(user) {
        return userService.register(user)
            .then(() => {
                alertService.success('Registration successful', { keepAfterRouteChange: true });
                router.push('login');
            })
            .catch(alertService.error);
    }

    return (
        <Layout>
            <div className="card">
                <h4 className="card-header">Register</h4>
                <div className="card-body">
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-group">
                            <label>First Name</label>
                            <input name="firstName" type="text" {...register('firstName')} className={`form-control ${errors.firstName ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.firstName?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Last Name</label>
                            <input name="lastName" type="text" {...register('lastName')} className={`form-control ${errors.lastName ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.lastName?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Username</label>
                            <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.username?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Password</label>
                            <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.password?.message}</div>
                        </div>
                        <button disabled={formState.isSubmitting} className="btn btn-primary">
                            {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Register
                        </button>
                        <Link href="/account/login" className="btn btn-link">Cancel</Link>
                    </form>
                </div>
            </div>
        </Layout>
    );
}
Example #9
Source File: login.jsx    From next-js-11-registration-login-example with MIT License 5 votes vote down vote up
function Login() {
    const router = useRouter();

    // form validation rules 
    const validationSchema = Yup.object().shape({
        username: Yup.string().required('Username is required'),
        password: Yup.string().required('Password is required')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // get functions to build form with useForm() hook
    const { register, handleSubmit, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit({ username, password }) {
        return userService.login(username, password)
            .then(() => {
                // get return url from query parameters or default to '/'
                const returnUrl = router.query.returnUrl || '/';
                router.push(returnUrl);
            })
            .catch(alertService.error);
    }

    return (
        <Layout>
            <div className="card">
                <h4 className="card-header">Login</h4>
                <div className="card-body">
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-group">
                            <label>Username</label>
                            <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.username?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Password</label>
                            <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.password?.message}</div>
                        </div>
                        <button disabled={formState.isSubmitting} className="btn btn-primary">
                            {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Login
                        </button>
                        <Link href="/account/register" className="btn btn-link">Register</Link>
                    </form>
                </div>
            </div>
        </Layout>
    );
}
Example #10
Source File: login.jsx    From next-js-11-jwt-authentication-example with MIT License 5 votes vote down vote up
function Login() {
    const router = useRouter();

    useEffect(() => {
        // redirect to home if already logged in
        if (userService.userValue) {
            router.push('/');
        }
    }, []);

    // form validation rules 
    const validationSchema = Yup.object().shape({
        username: Yup.string().required('Username is required'),
        password: Yup.string().required('Password is required')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // get functions to build form with useForm() hook
    const { register, handleSubmit, setError, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit({ username, password }) {
        return userService.login(username, password)
            .then(() => {
                // get return url from query parameters or default to '/'
                const returnUrl = router.query.returnUrl || '/';
                router.push(returnUrl);
            })
            .catch(error => {
                setError('apiError', { message: error });
            });
    }

    return (
        <div className="col-md-6 offset-md-3 mt-5">
            <div className="alert alert-info">
                Username: test<br />
                Password: test
            </div>
            <div className="card">
                <h4 className="card-header">Next.js JWT Login Example</h4>
                <div className="card-body">
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-group">
                            <label>Username</label>
                            <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.username?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Password</label>
                            <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.password?.message}</div>
                        </div>
                        <button disabled={formState.isSubmitting} className="btn btn-primary">
                            {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Login
                        </button>
                        {errors.apiError &&
                            <div className="alert alert-danger mt-3 mb-0">{errors.apiError?.message}</div>
                        }
                    </form>
                </div>
            </div>
        </div>
    );
}
Example #11
Source File: login.jsx    From next-js-11-basic-authentication-example with MIT License 5 votes vote down vote up
function Login() {
    const router = useRouter();

    useEffect(() => {
        // redirect to home if already logged in
        if (userService.userValue) {
            router.push('/');
        }

        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // form validation rules 
    const validationSchema = Yup.object().shape({
        username: Yup.string().required('Username is required'),
        password: Yup.string().required('Password is required')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // get functions to build form with useForm() hook
    const { register, handleSubmit, setError, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit({ username, password }) {
        return userService.login(username, password)
            .then(() => {
                // get return url from query parameters or default to '/'
                const returnUrl = router.query.returnUrl || '/';
                router.push(returnUrl);
            })
            .catch(error => {
                setError('apiError', { message: error });
            });
    }

    return (
        <div className="col-md-6 offset-md-3 mt-5">
            <div className="alert alert-info">
                Username: test<br />
                Password: test
            </div>
            <div className="card">
                <h4 className="card-header">Next.js Basic Authentication Example</h4>
                <div className="card-body">
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-group">
                            <label>Username</label>
                            <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.username?.message}</div>
                        </div>
                        <div className="form-group">
                            <label>Password</label>
                            <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                            <div className="invalid-feedback">{errors.password?.message}</div>
                        </div>
                        <button disabled={formState.isSubmitting} className="btn btn-primary">
                            {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                            Login
                        </button>
                        {errors.apiError &&
                            <div className="alert alert-danger mt-3 mb-0">{errors.apiError?.message}</div>
                        }
                    </form>
                </div>
            </div>
        </div>
    );
}
Example #12
Source File: Form.jsx    From sitepoint-books-firebase with MIT License 5 votes vote down vote up
function AuthorForm({ values, submit }) {
  const [errorMsg, setErrorMsg] = useState('')

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

  useEffect(() => {
    reset(values)
  }, [values])

  const onSubmit = (submittedData) => {
    try {
      submit(submittedData) // submit data to action handler
    } catch (err) {
      setErrorMsg(err.message)
    }
  }
  return (
    <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
      <form className="space-y-6" onSubmit={handleSubmit(onSubmit)}>
        {errorMsg && <Alert type="error" message={errorMsg} />}

        <div className="form-control">
          <label className="label" htmlFor="name">
            <span className="label-text">Name</span>
          </label>
          <input
            type="text"
            autoComplete="off"
            {...register('name')}
            className={`input input-bordered ${errors.name && 'input-error'}`}
          />
          {errors.name && (
            <span className="mt-1 text-xs text-error">
              {errors.name.message}
            </span>
          )}
        </div>

        <div className="flex justify-end space-x-4">
          <button type="submit" className="btn btn-primary btn-sm w-24">
            Save
          </button>
          <Link to="/author" className="btn btn-outline btn-sm w-24">
            Cancel
          </Link>
        </div>
      </form>
    </div>
  )
}
Example #13
Source File: ForgotPassword.jsx    From saasgear with MIT License 5 votes vote down vote up
function ForgotPassword() {
  useDocumentHeader({ title: 'Forgot password' });

  const [isSubmitted, setIsSubmitted] = useState(false);
  const { register, handleSubmit, errors } = useForm({
    resolver: yupResolver(ForgotPasswordSchema),
  });
  const [forgotPasswordMutation, { loading, error }] = useMutation(
    forgotpasswordQuery,
  );

  async function onSubmit(data) {
    setIsSubmitted(false);
    try {
      await forgotPasswordMutation({ variables: data });
      setIsSubmitted(true);
    } catch (e) {
      console.log(e);
      setIsSubmitted(false);
    }
  }

  return (
    <ForgotPasswordWrapper>
      <Overlay />
      <ForgotPasswordContainer>
        <ForgotPasswordForm
          onSubmit={handleSubmit(onSubmit)}
          register={register}
          errors={errors}
          isSubmitted={isSubmitted && !error}
          isSubmitting={loading}
          apiError={error?.message}
        />
        <SquareIconTop>
          <img src={squareRadiusTop} alt="" />
        </SquareIconTop>
        <SmallSquareBottom>
          <img src={squareRadiusTopPrimary} alt="" />
        </SmallSquareBottom>
        <SmallSquareTop>
          <img src={squareRadiusTopPrimarySmall} alt="" />
        </SmallSquareTop>
        <SmallSquareGrid>
          <img src={squareGrid} alt="" />
        </SmallSquareGrid>
        <SquareIconBottom>
          <img src={squareRadiusTopBig} alt="" />
        </SquareIconBottom>
        <CircleIcon>
          <img src={circleSmall} alt="" />
        </CircleIcon>
      </ForgotPasswordContainer>
    </ForgotPasswordWrapper>
  );
}
Example #14
Source File: SignUp.jsx    From saasgear with MIT License 5 votes vote down vote up
SignUp = () => {
  useDocumentHeader({ title: 'Sign Up' });
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(SignUpSchema),
    shouldUnregister: false,
  });
  const [registerMutation, { error, loading }] = useMutation(registerQuery);
  const [showStripeForm, setShowStripeForm] = useState(false);
  const [formData, setFormData] = useState({});
  const history = useHistory();
  const query = getQueryParam();
  const planName = query.get('plan');

  async function signup(params) {
    const { data } = await registerMutation({ variables: params });
    if (data?.register) {
      history.push('/');
    }
  }

  async function onSubmit(params) {
    if (planName) {
      setShowStripeForm(true);
      setFormData(params);
    } else {
      signup(params);
    }
  }

  function createPaymentMethodSuccess(token) {
    const data = {
      ...formData,
      paymentMethodToken: token,
      planName,
      billingType: query.get('isYearly') === '1' ? 'YEARLY' : 'MONTHLY',
    };
    signup(data);
  }

  function handleGoBack() {
    setShowStripeForm(false);
  }

  return (
    <SignUpFormWrapper>
      <SignUpFormLeft>
        {showStripeForm ? (
          <StripeContainer
            onSubmitSuccess={createPaymentMethodSuccess}
            onGoBack={handleGoBack}
            apiLoading={loading}
            apiError={error?.message}
          />
        ) : (
          <SignUpForm
            onSubmit={handleSubmit(onSubmit)}
            register={register}
            formErrors={formErrors}
            apiError={error?.message}
            isSubmitting={loading}
            submitText={planName ? 'Next' : 'Sign up'}
          />
        )}
      </SignUpFormLeft>
      <SignUpAds>
        <AuthAdsArea />
      </SignUpAds>
    </SignUpFormWrapper>
  );
}
Example #15
Source File: DeleteAccount.jsx    From saasgear with MIT License 5 votes vote down vote up
export default function DeleteAccount({ closeModal, isOpen }) {
  const {
    data: { email },
  } = useSelector((state) => state.user);
  const history = useHistory();
  const AccountSettingSchema = yup.object().shape({
    email: yup
      .string()
      .required('Email is required')
      .email('Email invalid')
      .matches(email),
  });
  const { register, handleSubmit, errors, watch, formState } = useForm({
    resolver: yupResolver(AccountSettingSchema),
    defaultValues: { email: '' },
    mode: 'all',
  });
  const watchEmail = watch('email');
  const [deleteAccountMutation] = useMutation(deleteAccountQuery);

  async function onSubmit() {
    const { data } = await deleteAccountMutation();
    if (data?.deleteAccount) {
      history.replace('/auth/signin');
    }
  }

  return (
    <Portal id="delete-account">
      <DeleteAccountModal
        closeModal={closeModal}
        isOpen={isOpen}
        register={register}
        errors={errors}
        email={email}
        isValid={formState.isValid && watchEmail !== ''}
        onSubmit={handleSubmit(onSubmit)}
      />
    </Portal>
  );
}
Example #16
Source File: FormRegister.jsx    From saasgear with MIT License 5 votes vote down vote up
export default function FormRegister({ data }) {
  const [registerMutation, { error }] = useMutation(registerAccountBySocial);
  const history = useHistory();
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(registerSchema),
  });

  async function onSubmit(formdata) {
    const params = {
      provider: data.user.provider.toUpperCase(),
      providerId: data.user.providerId,
      avatarUrl: data.user.avatarUrl,
      name: data.user.name,
      email: formdata.email,
    };
    const registerResponse = await registerMutation({ variables: params });

    if (registerResponse.data?.registerSocialAccount) {
      history.push('/');
    }
  }

  return (
    data?.user && (
      <div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
        <div className="max-w-md w-full">
          <img
            src={data.user.avatarUrl}
            alt="avatar"
            className="rounded-full h-64 w-64 mx-auto"
          />
          <h2 className="mt-6 text-center text-3xl leading-9 font-extrabold text-gray-900">
            Hi {data.user.name} !!
          </h2>
          <SignUpSocialForm
            onSubmit={handleSubmit(onSubmit)}
            register={register}
            formErrors={formErrors}
            errorAPI={error?.message}
          />
        </div>
      </div>
    )
  );
}
Example #17
Source File: InviteMember.jsx    From saasgear with MIT License 5 votes vote down vote up
function InviteMember({ teamMembers, alias }) {
  const { register, handleSubmit, errors: formErrors } = useForm({
    resolver: yupResolver(inviteMemberSchema),
  });
  const dispatch = useDispatch();
  const [InviteMemberMutation, { loading, error }] = useMutation(
    InviteMemberQuery,
  );

  async function onSubmit({ emailMember }) {
    try {
      const { data } = await InviteMemberMutation({
        variables: {
          email: emailMember,
          alias,
        },
      });
      if (data?.inviteMember) {
        const member = data.inviteMember;
        dispatch(addTeamMember({ teamID: alias, data: [member] }));
      }
    } catch (e) {
      console.log(error);
      setTimeout(() => console.log(error), 50);
      toast.error(e.message);
      console.log(JSON.stringify(e, null, 2));
    }
  }
  function onActionInlistMember(params) {
    console.log(params);
  }

  return (
    <ContentPage>
      <TitleContent>Invite Team Members</TitleContent>
      <InviteMemberForm
        register={register}
        onSubmit={handleSubmit(onSubmit)}
        formErrors={formErrors}
        isSubmiting={loading}
        apiError={error?.message}
      />
      {teamMembers && teamMembers.length > 0 && (
        <ListInvitation>
          <TitleContent>Pending Invitations</TitleContent>
          <ListTeamMember
            handleAction={onActionInlistMember}
            teamMembers={teamMembers}
          />
        </ListInvitation>
      )}
    </ContentPage>
  );
}
Example #18
Source File: AnswerForm.js    From stack-underflow with MIT License 4 votes vote down vote up
AnswerForm = ({ quesId, tags }) => {
  const classes = useQuesPageStyles();
  const { user } = useAuthContext();
  const { clearEdit, notify } = useStateContext();
  const { register, handleSubmit, reset, errors } = useForm({
    mode: 'onChange',
    resolver: yupResolver(validationSchema),
  });

  const [addAnswer, { loading }] = useMutation(POST_ANSWER, {
    onError: (err) => {
      notify(getErrorMsg(err), 'error');
    },
  });

  const postAnswer = ({ answerBody }) => {
    addAnswer({
      variables: { quesId, body: answerBody },
      update: (proxy, { data }) => {
        reset();

        const dataInCache = proxy.readQuery({
          query: VIEW_QUESTION,
          variables: { quesId },
        });

        const updatedData = {
          ...dataInCache.viewQuestion,
          answers: data.postAnswer,
        };

        proxy.writeQuery({
          query: VIEW_QUESTION,
          variables: { quesId },
          data: { viewQuestion: updatedData },
        });

        notify('Answer submitted!');
      },
    });
  };

  return (
    <div className={classes.answerForm}>
      {user && (
        <Typography variant="h6" color="secondary">
          Your Answer
        </Typography>
      )}
      {user && (
        <form onSubmit={handleSubmit(postAnswer)}>
          <TextField
            inputRef={register}
            name="answerBody"
            required
            fullWidth
            type="text"
            placeholder="Enter atleast 30 characters"
            variant="outlined"
            size="small"
            error={'answerBody' in errors}
            helperText={'answerBody' in errors ? errors.answerBody.message : ''}
            multiline
            rows={5}
          />
          <div>
            <Button
              color="primary"
              variant="contained"
              style={{ marginTop: '0.8em' }}
              type="submit"
              disabled={loading}
            >
              Post Your Answer
            </Button>
          </div>
        </form>
      )}
      <div className={classes.footerText}>
        <span>
          Browse other questions tagged{' '}
          {tags.map((t) => (
            <Chip
              key={t}
              label={t}
              variant="outlined"
              color="primary"
              size="small"
              component={RouterLink}
              to={`/tags/${t}`}
              className={classes.footerTag}
              clickable
            />
          ))}
          or{' '}
          {user ? (
            <Link component={RouterLink} to="/ask" onClick={() => clearEdit()}>
              ask your own question.
            </Link>
          ) : (
            <AuthFormModal buttonType="link" />
          )}
        </span>
      </div>
    </div>
  );
}
Example #19
Source File: MemberForm2.jsx    From minihackathon-2022 with MIT License 4 votes vote down vote up
function MemberForm2({ formKey, handleSubmitFunc, width }) {
	const {
		register,
		handleSubmit,
		formState: { errors },
	} = useForm({
		resolver: yupResolver(memberSchema),
	});
	const padded_key = String(formKey).padStart(2, "0");

	useEffect(() => {
		handleSubmitFunc &&
			handleSubmitFunc(formKey, () => {
				return new Promise((resolve, reject) => {
					handleSubmit(
						(data) => {
							resolve(data);
						},
						() => {
							resolve(null);
						}
					)();
				});
			});
	}, []); // eslint-disable-line react-hooks/exhaustive-deps

	return (
		<div className="h-full" style={{ width: width || "20%" }}>
			<h1 className="text-xl font-bold text-center">
				Member {String(formKey).padStart(2, "0")}{" "}
				{formKey === 1 ? "(Leader Details)" : "Details"}
			</h1>
			<form>
				<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
					Name
				</label>
				<input
					{...register("name")}
					type="text"
					placeholder="Name"
					className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
				/>
				<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
					{errors.name?.message}
				</p>

				<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
					Email
				</label>
				<input
					{...register("email")}
					type="text"
					placeholder="Email"
					className="border-2 border-black  rounded mb-[0.1em] px-2 py-1 w-full"
				/>
				<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
					{errors.email?.message}
				</p>

				<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
					Contact Number
				</label>
				<input
					{...register("contactNumber")}
					type="text"
					placeholder="Contact No"
					className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
				/>
				<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
					{errors.contactNumber?.message}
				</p>

				<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
					IT Number
				</label>
				<input
					{...register("itNumber")}
					type="text"
					placeholder="IT Number"
					className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
				/>
				<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
					{errors.itNumber?.message}
				</p>

				<div className="flex flex-row">
					<div className="mr-2 w-full">
						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							Academic Year
						</label>
						<select
							{...register("academicYear")}
							defaultValue=""
							className="border-2 border-black rounded mb-[0.1em] py-1 px-1 cursor-pointer w-full"
						>
							<option value="">Choose</option>
							<option value="Year 01 Semester 01">Year 01 Semester 01</option>
							<option value="Year 01 Semester 02">Year 01 Semester 02</option>
							<option value="Year 02 Semester 01">Year 02 Semester 01</option>
							<option value="Year 02 Semester 02">Year 02 Semester 02</option>
							<option value="Year 03 Semester 01">Year 03 Semester 01</option>
						</select>
						<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
							{errors.academicYear?.message}
						</p>
					</div>

					<div className="w-full">
						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							Faculty
						</label>
						<select
							{...register("faculty")}
							defaultValue=""
							className="border-2 border-black rounded mb-[0.1em] py-1 px-1 cursor-pointer w-full"
						>
							<option value="">Choose</option>
							<option value="Faculty of Computing">Faculty of Computing</option>
							<option value="Faculty of Engineering">
								Faculty of Engineering
							</option>
							<option value="Faculty of Business">Faculty of Business</option>
						</select>
						<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
							{errors.faculty?.message}
						</p>
					</div>
				</div>
				<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
					Member {padded_key} Profile Image
				</label>
				<input
					type="file"
					accept="image/*"
					placeholder={`member ${formKey} image`}
					{...register("image")}
				/>
				<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
					{errors.image?.message}
				</p>
			</form>
		</div>
	);
}
Example #20
Source File: index.jsx    From minihackathon-2022 with MIT License 4 votes vote down vote up
function AwarenessSession() {
	const {
		register,
		handleSubmit,
		formState: { errors },
		reset,
	} = useForm({
		resolver: yupResolver(awarenessSchema),
	});

	const [status, setStatus] = useState({ state: "none", message: "" });
	const [ticket, setTicket] = useState({
		display: false,
		it_no: "",
		number: 0,
		name: "",
		link: "",
		onRender: null,
	});

	const resetStatus = (timeout) => {
		setTimeout(() => {
			setStatus({ state: "none", message: "" });
		}, timeout);
	};

	const onSubmit = async (member_data) => {
		try {
			setStatus({ state: "loading" });

			// Registers use and Adds new number and document ref to member details
			await registerAwarenessSession(member_data);

			const onRender = async (dataURL) => {
				try {
					let url = await saveTicket(dataURL);
					let str = jsx2html(<EmailTemplate image={url} />);

					// update with the ticket image url
					await updateTicket(member_data.ref, url);

					await sendEmail(
						member_data.email,
						"Mini hackathon awareness session",
						str
					);

					setStatus({
						state: "success",
						message:
							"Success, You have successfully registered for the Awareness Session.",
					});

					setTicket((prevTicket) => {
						return { ...prevTicket, display: true };
					});

					reset();
				} catch (error) {
					setStatus({
						state: "error",
						message:
							"Failed to register, Something went wrong. Try again later",
					});
				}

				resetStatus(3000);
			};

			setTicket({
				...member_data,
				onRender,
				number: String(member_data.number).padStart(4, "0"),
			});
		} catch (error) {
			if (error instanceof EmailExists) {
				setStatus({
					state: "error",
					message: "Email already exists. Try again",
				});
				// TODO - show the already existing ticket
			} else {
				setStatus({
					state: "error",
					message: "Failed to register, Something went wrong. Try again later",
				});
			}

			resetStatus(5000);
		}
	};

	const closePopup = () => {
		setTicket((prevTicket) => {
			return { ...prevTicket, display: false };
		});
	};

	return (
		<>
			<div className="fixed z-[-1] w-screen h-screen top-0 left-0 bg-white"></div>
			<div className="w-full h-full flex flex-col justify-center items-center">
				<h1 className="text-center font-bold text-4xl mb-[1.5em] mt-[1.5em]">
					AWARENESS SESSION REGISTRATION
				</h1>
				<form onSubmit={handleSubmit(onSubmit)}>
					<div className="w-[22em] md:w-[35em] rounded-[5px] p-[2em] md:py-[2em] relative border-2 border-gray-400 overflow-hidden mb-5">
						<div
							className={`${
								status.state === "error" ? "bg-white" : "bg-white"
							} ${
								status.state === "none" ? "hidden" : ""
							} absolute flex justify-center items-center top-0 right-0 w-full h-full p-[3em]`}
						>
							<p className="text-center font-bold text-4xl mb-[1.5em]">
								<HashLoader
									color="#000000"
									loading={status.state === "error" ? false : true}
									cssOverride={override}
									size={90}
								/>
								{status.message}
							</p>
						</div>
						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							Name
						</label>
						<input
							{...register("name")}
							type="text"
							placeholder="Name"
							className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
						/>
						<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
							{errors.name?.message}
						</p>

						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							Email
						</label>
						<input
							{...register("email")}
							type="text"
							placeholder="Email"
							className="border-2 border-black  rounded mb-[0.1em] px-2 py-1 w-full"
						/>
						<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
							{errors.email?.message}
						</p>

						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							Contact Number
						</label>
						<input
							{...register("contact_no")}
							type="text"
							placeholder="Contact No"
							className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
						/>
						<p className="text-red-500 text-[0.8em] font-semibold h-[1em] italic">
							{errors.contact_no?.message}
						</p>

						<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
							IT Number
						</label>
						<input
							{...register("it_no")}
							type="text"
							placeholder="IT Number"
							className="border-2 border-black rounded mb-[0.1em] px-2 py-1 w-full"
						/>
						<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
							{errors.it_no?.message}
						</p>

						<div className="flex flex-row">
							<div className="mr-2 w-full">
								<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
									Academic Year
								</label>
								<select
									{...register("academic_year")}
									defaultValue=""
									className="border-2 border-black rounded mb-[0.1em] py-1 px-1 cursor-pointer w-full"
								>
									<option value="">Choose</option>
									<option value="Year 01 Semester 01">
										Year 01 Semester 01
									</option>
									<option value="Year 01 Semester 02">
										Year 01 Semester 02
									</option>
									<option value="Year 02 Semester 01">
										Year 02 Semester 01
									</option>
									<option value="Year 02 Semester 02">
										Year 02 Semester 02
									</option>
									<option value="Year 03 Semester 01">
										Year 03 Semester 01
									</option>
								</select>
								<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
									{errors.academic_year?.message}
								</p>
							</div>

							<div className="w-full">
								<label className="block font-semibold text-[#969696] text-[1em] md:text-left mb-1 md:mb-0 pr-4">
									Faculty
								</label>
								<select
									{...register("faculty")}
									defaultValue=""
									className="border-2 border-black rounded mb-[0.1em] py-1 px-1 cursor-pointer w-full"
								>
									<option value="">Choose</option>
									<option value="Faculty of Computing">
										Faculty of Computing
									</option>
									<option value="Faculty of Engineering">
										Faculty of Engineering
									</option>
									<option value="Faculty of Business">
										Faculty of Business
									</option>
								</select>
								<p className="text-red-500 text-[0.8em] font-semibold min-h-[1em] italic">
									{errors.faculty?.message}
								</p>
							</div>
						</div>

						<br></br>
						<div className="w-full flex items-center justify-center">
							<button
								type="submit"
								disabled={status.state === "success"}
								className="mt-2 w-48 h-10 rounded bg-black text-white hover:bg-gray-300 hover:text-black transition duration-0 hover:duration-500"
							>
								Register
							</button>
						</div>
					</div>
				</form>
			</div>
			<TicketPopup
				ticketNo={ticket.number}
				studentItNo={ticket.it_no}
				studentName={ticket.name}
				display={ticket.display}
				onRender={ticket.onRender}
				onClose={closePopup}
			/>
		</>
	);
}
Example #21
Source File: Action.jsx    From saasgear with MIT License 4 votes vote down vote up
ActionDocument = () => {
  const match = useRouteMatch();
  const history = useHistory();
  const documentId = parseInt(match.params.id, 10);
  const { handleSubmit, control, register, errors, setValue } = useForm({
    resolver: yupResolver(ActionDocumentSchema),
    mode: 'onChange',
  });
  const [
    createDocumentMutation,
    { loading: isCreating, error: createError },
  ] = useMutation(createDocumentQuery);
  const [
    updateDocumentMutation,
    { loading: isUpdating, error: updateError },
  ] = useMutation(updateDocumentQuery);
  const [fetchDocumentDetail, { data: documentData }] = useLazyQuery(
    getDocumentDetailQuery,
  );
  const [editorContent, setEditorContent] = useState('');

  useEffect(() => {
    if (documentId) {
      fetchDocumentDetail({ variables: { id: documentId } });
    }
  }, [documentId]);

  useEffect(() => {
    if (documentData?.getDocumentDetail) {
      const values = documentData.getDocumentDetail;
      setValue('name', values.name);
      setEditorContent(values.body);
    }
  }, [documentData]);

  async function onSubmit(data) {
    if (documentId) {
      await updateDocumentMutation({
        variables: {
          ...data,
          id: documentId,
        },
      });
    } else {
      await createDocumentMutation({ variables: data });
    }

    if (!createError && !updateError) {
      history.push('/document');
    }
  }

  return (
    <div>
      <Header>
        <TitlePageStyle>
          {documentData?.getDocumentDetail?.name
            ? documentData.getDocumentDetail.name
            : 'New Document'}
        </TitlePageStyle>
        <SaveBtn
          color="primary"
          onClick={handleSubmit(onSubmit)}
          disabled={isCreating || isUpdating}
        >
          {isCreating || isUpdating ? 'Please wait' : 'Save'}
        </SaveBtn>
      </Header>
      <ContentPage>
        <DocumentForm
          editorContent={editorContent}
          onSubmit={handleSubmit(onSubmit)}
          control={control}
          register={register}
          isSubmitting={isCreating || isUpdating}
          formErrors={errors}
          apiError={createError?.message || updateError?.message}
        />
      </ContentPage>
    </div>
  );
}
Example #22
Source File: AddEdit.jsx    From react-hook-form-crud-example with MIT License 4 votes vote down vote up
function AddEdit({ history, match }) {
    const { id } = match.params;
    const isAddMode = !id;
    
    // form validation rules 
    const validationSchema = Yup.object().shape({
        title: Yup.string()
            .required('Title is required'),
        firstName: Yup.string()
            .required('First Name is required'),
        lastName: Yup.string()
            .required('Last Name is required'),
        email: Yup.string()
            .email('Email is invalid')
            .required('Email is required'),
        role: Yup.string()
            .required('Role is required'),
        password: Yup.string()
            .transform(x => x === '' ? undefined : x)
            .concat(isAddMode ? Yup.string().required('Password is required') : null)
            .min(6, 'Password must be at least 6 characters'),
        confirmPassword: Yup.string()
            .transform(x => x === '' ? undefined : x)
            .when('password', (password, schema) => {
                if (password || isAddMode) return schema.required('Confirm Password is required');
            })
            .oneOf([Yup.ref('password')], 'Passwords must match')
    });

    // functions to build form returned by useForm() hook
    const { register, handleSubmit, reset, setValue, errors, formState } = useForm({
        resolver: yupResolver(validationSchema)
    });

    function onSubmit(data) {
        return isAddMode
            ? createUser(data)
            : updateUser(id, data);
    }

    function createUser(data) {
        return userService.create(data)
            .then(() => {
                alertService.success('User added', { keepAfterRouteChange: true });
                history.push('.');
            })
            .catch(alertService.error);
    }

    function updateUser(id, data) {
        return userService.update(id, data)
            .then(() => {
                alertService.success('User updated', { keepAfterRouteChange: true });
                history.push('..');
            })
            .catch(alertService.error);
    }

    useEffect(() => {
        if (!isAddMode) {
            // get user and set form fields
            userService.getById(id).then(user => {
                const fields = ['title', 'firstName', 'lastName', 'email', 'role'];
                fields.forEach(field => setValue(field, user[field]));
            });
        }
    }, []);

    return (
        <form onSubmit={handleSubmit(onSubmit)} onReset={reset}>
            <h1>{isAddMode ? 'Add User' : 'Edit User'}</h1>
            <div className="form-row">
                <div className="form-group col">
                    <label>Title</label>
                    <select name="title" ref={register} className={`form-control ${errors.title ? 'is-invalid' : ''}`}>
                        <option value=""></option>
                        <option value="Mr">Mr</option>
                        <option value="Mrs">Mrs</option>
                        <option value="Miss">Miss</option>
                        <option value="Ms">Ms</option>
                    </select>
                    <div className="invalid-feedback">{errors.title?.message}</div>
                </div>
                <div className="form-group col-5">
                    <label>First Name</label>
                    <input name="firstName" type="text" ref={register} className={`form-control ${errors.firstName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.firstName?.message}</div>
                </div>
                <div className="form-group col-5">
                    <label>Last Name</label>
                    <input name="lastName" type="text" ref={register} className={`form-control ${errors.lastName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.lastName?.message}</div>
                </div>
            </div>
            <div className="form-row">
                <div className="form-group col-7">
                    <label>Email</label>
                    <input name="email" type="text" ref={register} className={`form-control ${errors.email ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.email?.message}</div>
                </div>
                <div className="form-group col">
                    <label>Role</label>
                    <select name="role" ref={register} className={`form-control ${errors.role ? 'is-invalid' : ''}`}>
                        <option value=""></option>
                        <option value="User">User</option>
                        <option value="Admin">Admin</option>
                    </select>
                    <div className="invalid-feedback">{errors.role?.message}</div>
                </div>
            </div>
            {!isAddMode &&
                <div>
                    <h3 className="pt-3">Change Password</h3>
                    <p>Leave blank to keep the same password</p>
                </div>
            }
            <div className="form-row">
                <div className="form-group col">
                    <label>Password</label>
                    <input name="password" type="password" ref={register} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.password?.message}</div>
                </div>
                <div className="form-group col">
                    <label>Confirm Password</label>
                    <input name="confirmPassword" type="password" ref={register} className={`form-control ${errors.confirmPassword ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.confirmPassword?.message}</div>
                </div>
            </div>
            <div className="form-group">
                <button type="submit" disabled={formState.isSubmitting} className="btn btn-primary">
                    {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                    Save
                </button>
                <Link to={isAddMode ? '.' : '..'} className="btn btn-link">Cancel</Link>
            </div>
        </form>
    );
}
Example #23
Source File: InformationSetting.jsx    From saasgear with MIT License 4 votes vote down vote up
InformationSetting = ({ user }) => {
  const dispatch = useDispatch();
  const { register, handleSubmit, errors, setValue, getValues, watch } = useForm({
    resolver: yupResolver(AccountSchema),
    defaultValues: user,
  });
  const [isOpen, setIsOpen] = useState(false);
  const [isOpenModalDeleteAccount, setIsOpenModalDeleteAccount] = useState(
    false,
  );
  const [updateProfileMutation, { error, loading }] = useMutation(
    updateProfileQuery,
  );
  const [
    updateProfileAvatarMutation,
    { error: updateAvatarError, loading: isUpdatingAvatar },
  ] = useMutation(updateProfileAvatarQuery);


  async function onSubmit(dataForm) {
    const { name, company, position } = dataForm;
    const params = {
      name,
      company,
      position,
    };

    try {
      const { data } = await updateProfileMutation({ variables: params });
      if (data?.updateProfile) {
        toast.success('Update profile successfully!');
      }
    } catch (err) {
      console.log(err);
    }
  }

  async function changeProfile(e) {
    try {
      const file = e.target.files[0];
      if (file) {
        if (file.size > 2 * 1000 * 1000) {
          toast.error('File is too big');
          return;
        }
        const { data } = await updateProfileAvatarMutation({
          variables: {
            file,
          },
        });
        if (data && data.updateProfileAvatar && data.updateProfileAvatar.url) {
          dispatch(setProfileUser({ data: {avatarUrl: data.updateProfileAvatar.url}, loading: isUpdatingAvatar }));
          setValue('avatarUrl', data.updateProfileAvatar.url);
          toast.success('Change avatar successfully');
        }
      }
    } catch (errorChangeProfile) {
      toast.error('Can not update your avatar');
    }
  }

  useEffect(() => {
    register('avatarUrl');
    watch('avatarUrl');
  }, []);

  useEffect(() => {
    setValue('avatarUrl', user.avatarUrl);
  }, [user.avatarUrl]);

  return (
    <Wrapper expand={isOpen}>
      <Header onClick={() => setIsOpen(!isOpen)}>
        <AvatarWrapper>
          <Avatar htmlFor="avatar">
            <img src={resolveAvatarPath(getValues('avatarUrl'), AvatarIcon)} alt="avatar" />
            <input
              type="file"
              id="avatar"
              hidden
              onChange={changeProfile}
              accept="image/*"
            />
          </Avatar>
          <Info>
            <Name>{user.name}</Name>
            <Email>{user.email}</Email>
          </Info>
        </AvatarWrapper>
        <ActionWrapper>
          <ActionItem mobile><SettingIcon /></ActionItem>
          <ActionItem desktop>Edit Profile</ActionItem>
          <ArrowDown24IconStyle expand={isOpen ? 1 : 0} />
        </ActionWrapper>
      </Header>Avatar
      <AccountForm
        onSubmit={handleSubmit(onSubmit)}
        register={register}
        loading={loading || isUpdatingAvatar}
        errors={errors}
        apiError={error?.message || updateAvatarError?.message}
        openPopupDeleteAccount={() => setIsOpenModalDeleteAccount(true)}
      />
      <DeleteAccount
        isOpen={isOpenModalDeleteAccount}
        closeModal={() => setIsOpenModalDeleteAccount(false)}
      />
    </Wrapper>
  );
}
Example #24
Source File: AddEdit.jsx    From next-js-11-registration-login-example with MIT License 4 votes vote down vote up
function AddEdit(props) {
    const user = props?.user;
    const isAddMode = !user;
    const router = useRouter();
    
    // form validation rules 
    const validationSchema = Yup.object().shape({
        firstName: Yup.string()
            .required('First Name is required'),
        lastName: Yup.string()
            .required('Last Name is required'),
        username: Yup.string()
            .required('Username is required'),
        password: Yup.string()
            .transform(x => x === '' ? undefined : x)
            .concat(isAddMode ? Yup.string().required('Password is required') : null)
            .min(6, 'Password must be at least 6 characters')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // set default form values if in edit mode
    if (!isAddMode) {
        formOptions.defaultValues = props.user;
    }

    // get functions to build form with useForm() hook
    const { register, handleSubmit, reset, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit(data) {
        return isAddMode
            ? createUser(data)
            : updateUser(user.id, data);
    }

    function createUser(data) {
        return userService.register(data)
            .then(() => {
                alertService.success('User added', { keepAfterRouteChange: true });
                router.push('.');
            })
            .catch(alertService.error);
    }

    function updateUser(id, data) {
        return userService.update(id, data)
            .then(() => {
                alertService.success('User updated', { keepAfterRouteChange: true });
                router.push('..');
            })
            .catch(alertService.error);
    }

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <div className="form-row">
                <div className="form-group col">
                    <label>First Name</label>
                    <input name="firstName" type="text" {...register('firstName')} className={`form-control ${errors.firstName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.firstName?.message}</div>
                </div>
                <div className="form-group col">
                    <label>Last Name</label>
                    <input name="lastName" type="text" {...register('lastName')} className={`form-control ${errors.lastName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.lastName?.message}</div>
                </div>
            </div>
            <div className="form-row">
                <div className="form-group col">
                    <label>Username</label>
                    <input name="username" type="text" {...register('username')} className={`form-control ${errors.username ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.email?.message}</div>
                </div>
                <div className="form-group col">
                    <label>
                        Password
                        {!isAddMode && <em className="ml-1">(Leave blank to keep the same password)</em>}
                    </label>
                    <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.password?.message}</div>
                </div>
            </div>
            <div className="form-group">
                <button type="submit" disabled={formState.isSubmitting} className="btn btn-primary mr-2">
                    {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                    Save
                </button>
                <button onClick={() => reset(formOptions.defaultValues)} type="button" disabled={formState.isSubmitting} className="btn btn-secondary">Reset</button>
                <Link href="/users" className="btn btn-link">Cancel</Link>
            </div>
        </form>
    );
}
Example #25
Source File: AddEdit.jsx    From next-js-10-crud-example with MIT License 4 votes vote down vote up
function AddEdit(props) {
    const user = props?.user;
    const isAddMode = !user;
    const router = useRouter();
    const [showPassword, setShowPassword] = useState(false);
    
    // form validation rules 
    const validationSchema = Yup.object().shape({
        title: Yup.string()
            .required('Title is required'),
        firstName: Yup.string()
            .required('First Name is required'),
        lastName: Yup.string()
            .required('Last Name is required'),
        email: Yup.string()
            .email('Email is invalid')
            .required('Email is required'),
        role: Yup.string()
            .required('Role is required'),
        password: Yup.string()
            .transform(x => x === '' ? undefined : x)
            .concat(isAddMode ? Yup.string().required('Password is required') : null)
            .min(6, 'Password must be at least 6 characters'),
        confirmPassword: Yup.string()
            .transform(x => x === '' ? undefined : x)
            .when('password', (password, schema) => {
                if (password || isAddMode) return schema.required('Confirm Password is required');
            })
            .oneOf([Yup.ref('password')], 'Passwords must match')
    });
    const formOptions = { resolver: yupResolver(validationSchema) };

    // set default form values if in edit mode
    if (!isAddMode) {
        const { password, confirmPassword, ...defaultValues } = user;
        formOptions.defaultValues = defaultValues;
    }

    // get functions to build form with useForm() hook
    const { register, handleSubmit, reset, formState } = useForm(formOptions);
    const { errors } = formState;

    function onSubmit(data) {
        return isAddMode
            ? createUser(data)
            : updateUser(user.id, data);
    }

    function createUser(data) {
        return userService.create(data)
            .then(() => {
                alertService.success('User added', { keepAfterRouteChange: true });
                router.push('.');
            })
            .catch(alertService.error);
    }

    function updateUser(id, data) {
        return userService.update(id, data)
            .then(() => {
                alertService.success('User updated', { keepAfterRouteChange: true });
                router.push('..');
            })
            .catch(alertService.error);
    }

    return (
        <form onSubmit={handleSubmit(onSubmit)}>
            <h1>{isAddMode ? 'Add User' : 'Edit User'}</h1>
            <div className="form-row">
                <div className="form-group col">
                    <label>Title</label>
                    <select name="title" {...register('title')} className={`form-control ${errors.title ? 'is-invalid' : ''}`}>
                        <option value=""></option>
                        <option value="Mr">Mr</option>
                        <option value="Mrs">Mrs</option>
                        <option value="Miss">Miss</option>
                        <option value="Ms">Ms</option>
                    </select>
                    <div className="invalid-feedback">{errors.title?.message}</div>
                </div>
                <div className="form-group col-5">
                    <label>First Name</label>
                    <input name="firstName" type="text" {...register('firstName')} className={`form-control ${errors.firstName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.firstName?.message}</div>
                </div>
                <div className="form-group col-5">
                    <label>Last Name</label>
                    <input name="lastName" type="text" {...register('lastName')} className={`form-control ${errors.lastName ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.lastName?.message}</div>
                </div>
            </div>
            <div className="form-row">
                <div className="form-group col-7">
                    <label>Email</label>
                    <input name="email" type="text" {...register('email')} className={`form-control ${errors.email ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.email?.message}</div>
                </div>
                <div className="form-group col">
                    <label>Role</label>
                    <select name="role" {...register('role')} className={`form-control ${errors.role ? 'is-invalid' : ''}`}>
                        <option value=""></option>
                        <option value="User">User</option>
                        <option value="Admin">Admin</option>
                    </select>
                    <div className="invalid-feedback">{errors.role?.message}</div>
                </div>
            </div>
            {!isAddMode &&
                <div>
                    <h3 className="pt-3">Change Password</h3>
                    <p>Leave blank to keep the same password</p>
                </div>
            }
            <div className="form-row">
                <div className="form-group col">
                    <label>
                        Password
                        {!isAddMode &&
                            (!showPassword
                                ? <span> - <a onClick={() => setShowPassword(!showPassword)} className="text-primary">Show</a></span>
                                : <em> - {user.password}</em>
                            )
                        }
                    </label>
                    <input name="password" type="password" {...register('password')} className={`form-control ${errors.password ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.password?.message}</div>
                </div>
                <div className="form-group col">
                    <label>Confirm Password</label>
                    <input name="confirmPassword" type="password" {...register('confirmPassword')} className={`form-control ${errors.confirmPassword ? 'is-invalid' : ''}`} />
                    <div className="invalid-feedback">{errors.confirmPassword?.message}</div>
                </div>
            </div>
            <div className="form-group">
                <button type="submit" disabled={formState.isSubmitting} className="btn btn-primary mr-2">
                    {formState.isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
                    Save
                </button>
                <button onClick={() => reset(formOptions.defaultValues)} type="button" disabled={formState.isSubmitting} className="btn btn-secondary">Reset</button>
                <Link href="/users" className="btn btn-link">Cancel</Link>
            </div>
        </form>
    );
}
Example #26
Source File: Login.jsx    From sitepoint-books-firebase with MIT License 4 votes vote down vote up
function ScreenLogin() {
  const [message, setMessage] = useState('')
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  })

  const onSubmit = (data) => {
    setMessage('Feature not yet available')
    console.log(data)
  }

  return (
    <>
      <PageHeading title="Sign in to your account" />
      <div className="flex flex-col justify-center py-12 bg-base sm:px-6 lg:px-8">
        <div className="sm:mx-auto sm:w-full sm:max-w-md">
          <h2 className="mt-6 text-3xl font-extrabold text-center">
            User Login
          </h2>
        </div>

        <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
          <div className="px-4 py-8 shadow bg-base-200 sm:rounded-lg sm:px-10">
            <form className="space-y-6" onSubmit={handleSubmit(onSubmit)}>
              {message && <Alert type="error" message={message} />}

              <div className="form-control">
                <label className="label" htmlFor="email">
                  <span className="label-text">Email address</span>
                </label>
                <input
                  type="email"
                  autoComplete="email"
                  {...register('email')}
                  className={`input input-bordered ${
                    errors.email && 'input-error'
                  }`}
                />
                {errors.email && (
                  <span className="mt-1 text-xs text-error">
                    {errors.email.message}
                  </span>
                )}
              </div>

              <div className="form-control">
                <label className="label" htmlFor="password">
                  <span className="label-text">Password</span>
                </label>
                <input
                  type="password"
                  autoComplete="current-password"
                  {...register('password')}
                  className={`input input-bordered ${
                    errors.password && 'input-error'
                  }`}
                />
                {errors.password && (
                  <span className="mt-1 text-xs text-error">
                    {errors.password.message}
                  </span>
                )}
              </div>

              <div className="flex items-center justify-between">
                <div className="flex items-center">
                  <input
                    id="rememberMe"
                    name="rememberMe"
                    type="checkbox"
                    {...register('rememberMe')}
                    className="w-4 h-4 text-base border-gray-300 rounded focus:ring-base"
                  />
                  <label htmlFor="rememberMe" className="block ml-2 text-sm">
                    Remember me
                  </label>
                </div>

                <div className="text-sm">
                  <a
                    href="#"
                    className="font-medium hover:text-accent-content link"
                  >
                    Forgot your password?
                  </a>
                </div>
              </div>

              <div>
                <button type="submit" className="btn btn-primary btn-block">
                  Sign in
                </button>
              </div>
            </form>

            <div className="mt-6">
              <div className="relative">
                <div className="absolute inset-0 flex items-center">
                  <div className="w-full border-t border-gray-300" />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}
Example #27
Source File: Join.jsx    From sitepoint-books-firebase with MIT License 4 votes vote down vote up
function ScreenJoin() {
  const [message, setMessage] = useState('')
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  })

  const onSubmit = (data) => {
    setMessage('Feature not yet available')
    console.log(data)
  }

  return (
    <>
      <PageHeading title="Join Sitepoint Books" />
      <div className="flex flex-col justify-center py-12 bg-base sm:px-6 lg:px-8">
        <div className="sm:mx-auto sm:w-full sm:max-w-md">
          <h2 className="mt-6 text-3xl font-extrabold text-center">
            Create User Account
          </h2>
        </div>

        <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
          <div className="px-4 py-8 shadow bg-base-200 sm:rounded-lg sm:px-10">
            <form className="space-y-6" onSubmit={handleSubmit(onSubmit)}>
              {message && <Alert type="error" message={message} />}

              <div className="form-control">
                <label className="label" htmlFor="email">
                  <span className="label-text">Email address</span>
                </label>
                <input
                  type="email"
                  autoComplete="off"
                  className={`input input-bordered ${
                    errors.email && 'input-error'
                  }`}
                  {...register('email')}
                />
                {errors.email && (
                  <span className="mt-1 text-xs text-error">
                    {errors.email.message}
                  </span>
                )}
              </div>

              <div className="form-control">
                <label className="label" htmlFor="password">
                  <span className="label-text">Password</span>
                </label>
                <input
                  type="password"
                  className={`input input-bordered ${
                    errors.password && 'input-error'
                  }`}
                  {...register('password')}
                />
                {errors.password && (
                  <span className="mt-1 text-xs text-error">
                    {errors.password.message}
                  </span>
                )}
              </div>

              <div className="form-control">
                <label className="label" htmlFor="passwordConfirm">
                  <span className="label-text">Password Confirmation</span>
                </label>
                <input
                  type="password"
                  className={`input input-bordered ${
                    errors.passwordConfirm && 'input-error'
                  }`}
                  {...register('passwordConfirm')}
                />
                {errors.passwordConfirm && (
                  <span className="mt-1 text-xs text-error">
                    {errors.passwordConfirm.message}
                  </span>
                )}
              </div>

              <div>
                <button type="submit" className="btn btn-primary btn-block">
                  Sign up
                </button>
              </div>
            </form>

            <div className="flex justify-end mt-4 text-sm">
              Already have an account?{' '}
              <Link className="ml-2 link" to="/login">
                Log In
              </Link>
            </div>
          </div>
        </div>
      </div>
    </>
  )
}
Example #28
Source File: Form.jsx    From sitepoint-books-firebase with MIT License 4 votes vote down vote up
function CategoryForm({ values, action }) {
  const [errorMsg, setErrorMsg] = useState('')
  const [coverURL, setCoverURL] = useState()
  const [coverOptions, setCoverOptions] = useState([])

  const {
    register,
    watch,
    reset,
    handleSubmit,
    formState: { errors },
  } = useForm({
    resolver: yupResolver(schema),
  })
  const watchCover = watch('cover')

  // Get list of available images from cloud storage
  useEffect(async () => {
    const availableFiles = await StorageService.listFiles('categories')
    setCoverOptions(availableFiles)
  }, [])

  // Load current document values if available
  useEffect(() => {
    reset(values)
  }, [reset])

  // Display the current cover
  useEffect(async () => {
    if (watchCover && watchCover != 'nocover') {
      const url = await StorageService.getImageURL(watchCover)
      setCoverURL(url)
    }
  }, [watchCover])

  const onSubmit = async (submittedData) => {
    try {
      await action(submittedData) // submit data to action handler
    } catch (err) {
      setErrorMsg(err.message)
    }
  }

  return (
    <div className="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
      <form className="space-y-6" onSubmit={handleSubmit(onSubmit)}>
        {errorMsg && <Alert type="error" message={errorMsg} />}

        <div className="form-control">
          <label className="label" htmlFor="name">
            <span className="label-text">Name</span>
          </label>
          <input
            type="text"
            autoComplete="off"
            {...register('name')}
            className={`input input-bordered ${errors.name && 'input-error'}`}
          />
          {errors.name && (
            <span className="mt-1 text-xs text-error">
              {errors.name.message}
            </span>
          )}
        </div>

        <div className="form-control">
          <label className="label" htmlFor="cover">
            <span className="label-text">Select Cover</span>
          </label>
          <div className="flex items-center">
            <select
              {...register('cover')}
              value={watchCover}
              className={`select select-bordered w-full ${
                errors.cover ? 'select-error' : ''
              }`}
            >
              <option disabled="disabled" value="nocover">
                Choose a cover
              </option>
              {coverOptions.map((fileName, index) => (
                <option key={index} value={fileName}>
                  {fileName}
                </option>
              ))}
            </select>
            <button type="button" className="btn btn-secondary btn-sm ml-8">
              Upload New
            </button>
          </div>
          {errors.cover && (
            <span className="mt-1 text-xs text-error">
              {errors.cover.message}
            </span>
          )}
          <div className="avatar mt-4">
            <div className="mb-8 rounded-btn w-36 h-36">
              {coverURL && <img src={coverURL} />}
            </div>
          </div>
        </div>

        <div className="flex justify-end space-x-4">
          <button type="submit" className="btn btn-primary btn-sm w-24">
            Save
          </button>
          <Link to="/category" className="btn btn-outline btn-sm w-24">
            Cancel
          </Link>
        </div>
      </form>
    </div>
  )
}
Example #29
Source File: CommentSection.js    From stack-underflow with MIT License 4 votes vote down vote up
CommentSection = ({
  user,
  comments,
  addComment,
  editComment,
  deleteComment,
  quesAnsId,
}) => {
  const classes = useQuesPageStyles();
  const [isCollapsed, setIsCollapsed] = useState(true);
  const [inputOpen, setInputOpen] = useState(false);
  const { register, handleSubmit, reset, errors } = useForm({
    mode: 'onChange',
    resolver: yupResolver(validationSchema),
  });

  const closeInput = () => {
    setInputOpen(false);
  };

  const showComments = () => {
    setIsCollapsed(false);
  };

  const handleCommentAdd = ({ commentBody }) => {
    addComment(commentBody, quesAnsId);
    showComments();
    closeInput();
    reset();
  };

  const visibleComments = isCollapsed ? comments.slice(0, 3) : comments;

  return (
    <div className={classes.commentSection}>
      {comments.length !== 0 && <Divider />}
      {visibleComments.map((c) => (
        <div key={c.id}>
          <Comment
            comment={c}
            user={user}
            quesAnsId={quesAnsId}
            editComment={editComment}
            deleteComment={deleteComment}
          />
          <Divider />
        </div>
      ))}
      {visibleComments.length !== comments.length ? (
        <Button size="small" color="primary" onClick={showComments}>
          show {comments.length - visibleComments.length} more comments
        </Button>
      ) : (
        user &&
        !inputOpen && (
          <Button
            size="small"
            color="primary"
            onClick={() => setInputOpen(true)}
          >
            add a comment
          </Button>
        )
      )}
      {inputOpen && (
        <form
          className={classes.smallForm}
          onSubmit={handleSubmit(handleCommentAdd)}
        >
          <TextField
            inputRef={register}
            name="commentBody"
            required
            fullWidth
            type="text"
            placeholder="Enter at least 5 characters"
            variant="outlined"
            size="small"
            multiline
            rows={3}
            error={'commentBody' in errors}
            helperText={
              'commentBody' in errors ? errors.commentBody.message : ''
            }
          />
          <div className={classes.submitCancelBtns}>
            <Button
              type="submit"
              size="small"
              variant="contained"
              color="primary"
              style={{ marginRight: 9 }}
            >
              Add Comment
            </Button>
            <Button
              size="small"
              variant="outlined"
              color="primary"
              onClick={() => setInputOpen(false)}
            >
              Cancel
            </Button>
          </div>
        </form>
      )}
    </div>
  );
}