hooks#useFormatMessage JavaScript Examples

The following examples show how to use hooks#useFormatMessage. 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: index.jsx    From react-firebase-admin with MIT License 6 votes vote down vote up
Home = () => (
  <>
    <section className="hero is-hero-bar">
      <div className="hero-body">
        <h1 className="title">{useFormatMessage('Home.home')}</h1>
      </div>
    </section>

    <section className="section is-main-section">
      {useFormatMessage('Home.content')}
    </section>
  </>
)
Example #2
Source File: index.jsx    From react-firebase-admin with MIT License 6 votes vote down vote up
NotFound = () => {
  const location = useLocation();

  const { isAuth } = useSelector(
    state => ({
      isAuth: !!state.auth.userData.id
    }),
    shallowEqual
  );

  const userPath = isAuth ? path.ROOT : path.LOGIN;

  return (
    <section className="hero is-fullheight">
      <div className="hero-body">
        <section className={`section ${classes.section}`}>
          <div className="container">
            <div className="columns is-vcentered is-desktop">
              <div className="column has-text-centered">
                <h1 className="title">{useFormatMessage('NotFound.404')}</h1>
                <p className="subtitle">
                  {useFormatMessage('NotFound.url', { url: location.pathname })}
                </p>
                <Link className="button is-info is-normal" to={userPath}>
                  {useFormatMessage('NotFound.back')}
                </Link>
              </div>
              <div className="column has-text-centered">
                <img src={NotFoudImage} alt="404 error" />
              </div>
            </div>
          </div>
        </section>
      </div>
    </section>
  );
}
Example #3
Source File: index.jsx    From react-firebase-admin with MIT License 6 votes vote down vote up
Section = () => (
  <>
    <section className="hero is-hero-bar">
      <div className="hero-body">
        <h1 className="title">{useFormatMessage('Section.section')}</h1>
      </div>
    </section>
    <section className="section is-main-section">
      {useFormatMessage('Section.content')}
    </section>
  </>
)
Example #4
Source File: index.jsx    From react-firebase-admin with MIT License 6 votes vote down vote up
Submenu = () => (
  <>
    <section className="hero is-hero-bar">
      <div className="hero-body">
        <h1 className="title">{useFormatMessage('Submenu.submenu')}</h1>
      </div>
    </section>
    <section className="section is-main-section">
      {useFormatMessage('Submenu.content')}
    </section>
  </>
)
Example #5
Source File: index.jsx    From react-firebase-admin with MIT License 5 votes vote down vote up
ErrorMessage = ({ text = '' }) => {
  const defaultText = useFormatMessage('ErrorMessage.defaultMessage');
  return <p className="error">{text || defaultText}</p>;
}
Example #6
Source File: index.jsx    From react-firebase-admin with MIT License 5 votes vote down vote up
Aside = ({ handleMobileToggle }) => {
  const { isAdmin } = useSelector(
    (state) => ({
      isAdmin: state.auth.userData.isAdmin,
    }),
    shallowEqual
  );

  const usersMessage = useFormatMessage('Aside.users');

  return (
    <aside className="aside is-placed-left is-expanded">
      <Link to={paths.ROOT} className="aside-tools">
        <div className="aside-tools-label">
          <span>
            <b>React</b> Firebase
          </span>
        </div>
      </Link>
      <div className="menu is-menu-main">
        <ul className="menu-list">
          <li>
            <NavLink
              to={paths.ROOT}
              className="has-icon"
              onClick={handleMobileToggle}
            >
              <span className="icon">
                <i className="mdi mdi-home" />
              </span>
              <span className="menu-item-label">
                {useFormatMessage('Aside.home')}
              </span>
            </NavLink>
          </li>
          {isAdmin && (
            <li>
              <NavLink
                to={paths.USERS}
                className="has-icon"
                onClick={handleMobileToggle}
              >
                <span className="icon">
                  <i className="mdi mdi-account-supervisor" />
                </span>
                <span className="menu-item-label">{usersMessage}</span>
              </NavLink>
            </li>
          )}
          <SubMenu label={useFormatMessage('Aside.dropdownMenu')}>
            <li>
              <NavLink
                className={classes.submenuLink}
                to={paths.SUBMENU_1}
                onClick={handleMobileToggle}
              >
                <span>{useFormatMessage('Aside.submenu1')}</span>
              </NavLink>
            </li>
            <li>
              <NavLink
                className={classes.submenuLink}
                to={paths.SUBMENU_2}
                onClick={handleMobileToggle}
              >
                <span>{useFormatMessage('Aside.submenu2')}</span>
              </NavLink>
            </li>
          </SubMenu>
        </ul>
      </div>
    </aside>
  );
}
Example #7
Source File: index.jsx    From react-firebase-admin with MIT License 5 votes vote down vote up
Profile = () => {
  const { userData } = useSelector(
    (state) => ({
      userData: state.auth.userData,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const onSubmitHandler = (value) => {
    const newUser = {
      ...value,
      file: value?.file[0] || null,
      isEditing: true,
      isProfile: true,
      id: userData.id,
    };
    dispatch(modifyUser(newUser));
  };

  return (
    <>
      <section className="hero is-hero-bar">
        <div className="hero-body">
          <h1 className="title">{useFormatMessage('Profile.profile')}</h1>
        </div>
      </section>
      <section className="section is-main-section">
        <UserForm
          isEditing
          isProfile
          user={userData}
          onSubmitHandler={onSubmitHandler}
          schema={schema}
        />
        <ChangePassword />
      </section>
    </>
  );
}
Example #8
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
NavBar = ({ handleMobileToggle, asideMobileActive }) => {
  const [navMobileActive, setNavMobileActive] = useState(false);

  const { userName, logoUrl, locale } = useSelector(
    (state) => ({
      userName: state.auth.userData.name,
      logoUrl: state.auth.userData.logoUrl,
      locale: state.preferences.locale,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const onClickLogoutHandler = () => {
    dispatch(logout());
  };

  const onMobileToggleHandler = useCallback(() => {
    setNavMobileActive(!navMobileActive);
  }, [setNavMobileActive, navMobileActive]);

  const changeLocaleHandler = (local) => {
    dispatch(setUserLocale(local));
  };

  const locales = availableLocales.filter((local) => local !== locale);

  return (
    <nav id="navbar-main" className="navbar is-fixed-top">
      <div className="navbar-brand">
        <a
          className="navbar-item is-hidden-desktop jb-aside-mobile-toggle"
          onClick={handleMobileToggle}
        >
          <span className="icon">
            <i
              className={classNames(
                'mdi',
                'mdi-24px',
                { 'mdi-forwardburger': !asideMobileActive },
                { 'mdi-backburger': asideMobileActive }
              )}
            />
          </span>
        </a>
      </div>
      <div className="navbar-brand is-right">
        <a
          className="navbar-item is-hidden-desktop jb-navbar-menu-toggle"
          data-target="navbar-menu"
          onClick={onMobileToggleHandler}
        >
          <span className="icon">
            <i
              className={classNames(
                'mdi',
                { 'mdi-dots-vertical': !navMobileActive },
                { 'mdi-close': navMobileActive }
              )}
            />
          </span>
        </a>
      </div>
      <div
        className={classNames('navbar-menu', 'fadeIn', 'animated', 'faster', {
          'is-active': navMobileActive,
        })}
        id="navbar-menu"
      >
        <div className="navbar-end">
          <div className="navbar-item has-dropdown has-dropdown-with-icons has-divider has-user-avatar is-hoverable">
            <a className="navbar-link is-arrowless">
              <div className="is-user-avatar">
                <span>
                  <img id={locale} src={flags[locale]} alt={`${locale} flag`} />
                </span>
              </div>
              <span className="icon">
                <i className="mdi mdi-chevron-down" />
              </span>
            </a>
            <div className="navbar-dropdown">
              {locales.map((local) => (
                <a
                  onClick={() => changeLocaleHandler(local)}
                  className="navbar-item"
                  id={local}
                  key={local}
                >
                  <div className="is-user-avatar">
                    <span>
                      <img src={flags[local]} alt={`${local} flag`} />
                    </span>
                  </div>
                </a>
              ))}
            </div>
          </div>
          <div className="navbar-item has-dropdown has-dropdown-with-icons has-divider has-user-avatar is-hoverable">
            <a className="navbar-link is-arrowless">
              <div className="is-user-avatar">
                <img src={logoUrl || defaultLogo} alt="User profile" />
              </div>
              <div className="is-user-name">
                <span>{userName}</span>
              </div>
              <span className="icon">
                <i className="mdi mdi-chevron-down" />
              </span>
            </a>
            <div className="navbar-dropdown">
              <Link to={paths.PROFILE} onClick={onMobileToggleHandler}>
                <span className="icon">
                  <i className="mdi mdi-account" />
                </span>
                <span>{useFormatMessage('NavBar.profile')}</span>
              </Link>
              <hr className="navbar-divider" />
              <a
                className="navbar-item"
                id="logout"
                onClick={onClickLogoutHandler}
              >
                <span className="icon">
                  <i className="mdi mdi-logout" />
                </span>
                <span>{useFormatMessage('NavBar.logOut')}</span>
              </a>
            </div>
          </div>
        </div>
      </div>
    </nav>
  );
}
Example #9
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
Table = ({ columns, data }) => {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    page,
    prepareRow,
    pageCount,
    state: { pageIndex, pageSize },
    gotoPage,
    previousPage,
    nextPage,
    setPageSize,
    canPreviousPage,
    canNextPage,
  } = useTable(
    {
      columns,
      data,
    },
    useSortBy,
    usePagination
  );

  const perPage = useFormatMessage('Table.perPage');

  return (
    <div className="table-wrapper">
      <table
        className="table is-striped has-mobile-cards is-hoverable"
        {...getTableProps()}
      >
        <thead>
          {headerGroups.map((headerGroup) => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map((column) => (
                <th
                  className={classNames(
                    { [classes.isCurrentSort]: column.isSorted },
                    { [classes.isSortable]: column.canSort }
                  )}
                  {...column.getHeaderProps(column.getSortByToggleProps())}
                >
                  <div className="th-wrap">
                    {column.render('Header')}
                    {column.isSorted && (
                      <span className="icon is-small">
                        <i
                          className={classNames(
                            'mdi',
                            classes.tableIcon,
                            { 'mdi-arrow-down': column.isSortedDesc },
                            { 'mdi-arrow-up': !column.isSortedDesc }
                          )}
                        />
                      </span>
                    )}
                  </div>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {page.map((row) => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map((cell) => {
                  return (
                    <td
                      className={classNames(
                        { 'is-actions-cell': cell.column.id === 'actions' },
                        {
                          'has-no-head-mobile is-image-cell':
                            cell.column.id === 'logoUrl',
                        }
                      )}
                      data-label={cell.column.Header}
                      {...cell.getCellProps()}
                    >
                      {cell.render('Cell')}
                    </td>
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>
      <div className={classNames('level', classes.level)}>
        <div className="level-left">
          <div className="control">
            <span className="select">
              <select
                value={pageSize}
                onChange={(e) => {
                  setPageSize(Number(e.target.value));
                }}
              >
                {[5, 10, 15, 20, 50].map((size) => (
                  <option key={size} value={size}>
                    {size} {perPage}
                  </option>
                ))}
              </select>
            </span>
          </div>
        </div>
        <div className="level-right">
          <div className="level-item">
            <nav className="pagination">
              <button
                type="button"
                className="pagination-link pagination-previous"
                onClick={() => previousPage()}
                disabled={!canPreviousPage}
              >
                <span className="icon" aria-hidden="true">
                  <i className="mdi mdi-chevron-left mdi-24px" />
                </span>
              </button>
              <button
                type="button"
                className="pagination-link pagination-next"
                onClick={() => nextPage()}
                disabled={!canNextPage}
              >
                <span className="icon" aria-hidden="true">
                  <i className="mdi mdi-chevron-right mdi-24px" />
                </span>
              </button>
              <ul className="pagination-list">
                {pageIndex !== 0 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(0)}
                    >
                      1
                    </button>
                  </li>
                )}
                {pageIndex > 3 && (
                  <li>
                    <span className="pagination-ellipsis">…</span>
                  </li>
                )}
                {pageIndex === 3 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(1)}
                    >
                      2
                    </button>
                  </li>
                )}
                {pageIndex - 1 > 0 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => previousPage()}
                    >
                      {pageIndex}
                    </button>
                  </li>
                )}
                <li>
                  <button
                    type="button"
                    className={classNames(
                      'pagination-link',
                      classes.currentPage
                    )}
                    aria-current="true"
                  >
                    {pageIndex + 1}
                  </button>
                </li>
                {canNextPage && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => nextPage()}
                    >
                      {pageIndex + 2}
                    </button>
                  </li>
                )}
                {pageCount - pageIndex === 4 && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(pageCount - 2)}
                    >
                      {pageCount - 1}
                    </button>
                  </li>
                )}
                {pageCount - pageIndex > 4 && (
                  <li>
                    <span className="pagination-ellipsis">…</span>
                  </li>
                )}
                {pageIndex + 2 < pageCount && (
                  <li>
                    <button
                      type="button"
                      className="pagination-link"
                      onClick={() => gotoPage(pageCount - 1)}
                    >
                      {pageCount}
                    </button>
                  </li>
                )}
              </ul>
            </nav>
          </div>
        </div>
      </div>
    </div>
  );
}
Example #10
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 #11
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
Login = () => {
  const { error, isAuth, loading, locale } = useSelector(
    (state) => ({
      error: state.auth.error,
      isAuth: !!state.auth.userData.id,
      loading: state.auth.loading,
      locale: state.preferences.locale,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

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

  useEffect(() => {
    document.documentElement.classList.remove(
      'has-aside-left',
      'has-navbar-fixed-top'
    );
    return () => {
      document.documentElement.classList.add(
        'has-aside-left',
        'has-navbar-fixed-top'
      );
      dispatch(authCleanUp());
    };
  }, [dispatch]);

  const isEmailLink = firebase
    .auth()
    .isSignInWithEmailLink(window.location.href);

  const onSubmitHandler = ({ email, password }) => {
    if (isEmailLink) {
      dispatch(setPassword(email, password, window.location.href));
    } else {
      dispatch(auth(email, password));
    }
  };

  const onSignInSuccessHandler = (authResult) => {
    dispatch(authWithSocialMedia(authResult));
  };

  const onSignInFailHandler = (signInEror) => {
    const signInErrorMessage = firebaseError(signInEror.code, locale);
    toastr.error('', signInErrorMessage);
  };

  const isValidPassword = watch('password') && watch('password').length >= 6;

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

  const safePasswordMessage = useFormatMessage('Login.safePassword');

  const unsafePasswordMessage = useFormatMessage('Login.unsafePassword');

  const redirect = isAuth && <Redirect to={paths.ROOT} />;

  const setNewPasswordMessage = useFormatMessage('Login.setNewPassword');

  const loginMessage = useFormatMessage('Login.login');

  const setPasswordMessage = useFormatMessage('Login.setPassword');

  const forgotPasswordMessage = useFormatMessage('Login.forgotPassword');

  const invalidPasswordMessage = useFormatMessage('Login.invalidPassword');

  return (
    <section className="section hero is-fullheight is-error-section">
      {redirect}
      <div className="hero-body">
        <div className="container">
          <div className="columns is-centered">
            <div className="column is-two-fifths">
              <div className="card has-card-header-background">
                <header className="card-header">
                  <p className="card-header-title">
                    <span className="icon">
                      <i className="mdi mdi-lock default" />
                    </span>
                    <span>
                      {isEmailLink ? setNewPasswordMessage : loginMessage}
                    </span>
                  </p>
                </header>
                <div className="card-content">
                  <form onSubmit={handleSubmit(onSubmitHandler)}>
                    <div className="field">
                      <p className="label">{useFormatMessage('Login.email')}</p>
                      <div className="control is-clearfix">
                        <input
                          className={classNames('input', {
                            'is-danger': errors.email,
                          })}
                          name="email"
                          ref={register}
                        />
                      </div>
                      {errors.email && (
                        <ErrorMessage text={invalidEmailMessage} />
                      )}
                    </div>
                    <div className="field">
                      <p className="label">
                        {useFormatMessage('Login.password')}
                      </p>
                      <div className="control is-clearfix">
                        <input
                          className={classNames(
                            'input',
                            {
                              'is-danger': errors.password,
                            },
                            {
                              'is-success': isEmailLink && isValidPassword,
                            }
                          )}
                          type="password"
                          name="password"
                          ref={register}
                        />
                      </div>
                      {errors.password ? (
                        <ErrorMessage
                          text={
                            isEmailLink
                              ? unsafePasswordMessage
                              : invalidPasswordMessage
                          }
                        />
                      ) : (
                        isEmailLink &&
                        isValidPassword && (
                          <p className="is-success">{safePasswordMessage}</p>
                        )
                      )}
                    </div>
                    <br />
                    <div className="field is-grouped">
                      <div className="control">
                        <button
                          type="submit"
                          className={classNames('button', 'is-black', {
                            'is-loading': loading,
                          })}
                        >
                          {isEmailLink ? setPasswordMessage : loginMessage}
                        </button>
                      </div>
                      {!isEmailLink && (
                        <div className="control">
                          <Link
                            to={paths.RESET_PASSWORD}
                            className="button is-outlined"
                          >
                            {forgotPasswordMessage}
                          </Link>
                        </div>
                      )}
                    </div>
                    {error && (
                      <p
                        className={classNames(
                          'has-text-danger',
                          classes.errorMessage
                        )}
                      >
                        {error}
                      </p>
                    )}
                  </form>
                  {!isEmailLink && (
                    <>
                      <hr />
                      <div
                        className={classNames(
                          'field',
                          'is-grouped',
                          classes.socialButtons
                        )}
                      >
                        <StyledFirebaseAuth
                          uiConfig={uiConfig(
                            onSignInSuccessHandler,
                            onSignInFailHandler
                          )}
                          firebaseAuth={firebase.auth()}
                        />
                      </div>
                    </>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}
Example #12
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
ChangePasswordCard = () => {
  const { loading, changedPassword } = useSelector(
    (state) => ({
      loading: state.auth.loading,
      changedPassword: state.auth.changedPassword,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const { register, handleSubmit, watch, setValue, errors } = useForm({
    mode: 'onChange',
    defaultValues: {
      current: '',
      new: '',
      confirmation: '',
    },
    resolver: yupResolver(schema),
  });

  useEffect(() => {
    if (changedPassword) {
      setValue('current', '');
      setValue('new', '');
      setValue('confirmation', '');
    }
    return () => dispatch(authCleanUp());
  }, [dispatch, changedPassword, setValue]);

  const newPassword = watch('new');
  const confirmationPassword = watch('confirmation');

  const invalidPasswordMessage = useFormatMessage(
    `ChangePassword.invalidPassword`
  );

  const safePasswordMessage = useFormatMessage(`ChangePassword.safePassword`);

  const insecurePasswordMessage = useFormatMessage(
    `ChangePassword.insecurePassword`
  );

  const passwordsMatchMessagge = useFormatMessage(
    `ChangePassword.matchPassword`
  );

  const notMatchPasswordMessage = useFormatMessage(
    `ChangePassword.notMatchPassword`
  );

  const samePasswordMessage = useFormatMessage(`ChangePassword.samePassword`);

  const onSubmitHandler = ({ current, confirmation }) => {
    dispatch(changeUserPassword(current, confirmation));
  };

  return (
    <div className="card">
      <header className="card-header">
        <p className="card-header-title">
          <span className="icon">
            <i className="fa fa-lock" />
          </span>
          {useFormatMessage(`ChangePassword.changePassword`)}
        </p>
      </header>
      <div className="card-content">
        <form onSubmit={handleSubmit(onSubmitHandler)}>
          <div className="field is-horizontal">
            <div className="field-label is-normal">
              <label className="label">
                {useFormatMessage(`ChangePassword.currentPassword`)}
              </label>
            </div>
            <div className="field-body">
              <div className="field">
                <div className="control">
                  <input
                    data-testid="current"
                    className={classNames('input', {
                      'is-danger': errors.current,
                    })}
                    type="password"
                    name="current"
                    ref={register}
                  />
                </div>
                {errors.current && (
                  <ErrorMessage text={invalidPasswordMessage} />
                )}
              </div>
            </div>
          </div>
          <hr />
          <div className="field is-horizontal">
            <div className="field-label is-normal">
              <label className="label">
                {useFormatMessage(`ChangePassword.newPassword`)}
              </label>
            </div>
            <div className="field-body">
              <div className="field">
                <div className="control">
                  <input
                    data-testid="new"
                    className={classNames(
                      `input`,
                      { 'is-success': newPassword && !errors.new },
                      { 'is-danger': errors.new }
                    )}
                    type="password"
                    name="new"
                    ref={register}
                  />
                </div>
                {errors.new ? (
                  <ErrorMessage
                    text={
                      newPassword.length < 6
                        ? insecurePasswordMessage
                        : samePasswordMessage
                    }
                  />
                ) : (
                  newPassword && (
                    <p className="is-success">{safePasswordMessage}</p>
                  )
                )}
              </div>
            </div>
          </div>

          <div className="field is-horizontal">
            <div className="field-label is-normal">
              <label className="label">
                {useFormatMessage(`ChangePassword.confirmPassword`)}
              </label>
            </div>
            <div className="field-body">
              <div className="field">
                <div className="control">
                  <input
                    data-testid="confirmation"
                    className={classNames(
                      `input`,
                      {
                        'is-success':
                          confirmationPassword && !errors.confirmation,
                      },
                      {
                        'is-danger': errors.confirmation,
                      }
                    )}
                    type="password"
                    name="confirmation"
                    ref={register}
                  />
                </div>
                {errors.confirmation ? (
                  <ErrorMessage text={notMatchPasswordMessage} />
                ) : (
                  confirmationPassword && (
                    <p className="is-success">{passwordsMatchMessagge}</p>
                  )
                )}
              </div>
            </div>
          </div>
          <div className="field is-horizontal">
            <div className="field-label is-normal" />
            <div className="field-body">
              <div className="field">
                <div className="control">
                  <button
                    type="submit"
                    className={`button is-primary ${loading && 'is-loading'}`}
                  >
                    {useFormatMessage(`ChangePassword.submits`)}
                  </button>
                </div>
              </div>
            </div>
          </div>
        </form>
      </div>
    </div>
  );
}
Example #13
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
ResetPassword = () => {
  const { loading, error, restoredPassword, isAuth } = useSelector(
    (state) => ({
      loading: state.auth.loading,
      error: state.auth.error,
      restoredPassword: state.auth.restoredPassword,
      isAuth: !!state.auth.userData.userId,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const { register, handleSubmit, errors, watch } = useForm({
    resolver: yupResolver(schema),
  });

  useEffect(() => {
    document.documentElement.classList.remove(
      'has-aside-left',
      'has-navbar-fixed-top'
    );
    return () => {
      document.documentElement.classList.add(
        'has-aside-left',
        'has-navbar-fixed-top'
      );
      dispatch(authCleanUp());
    };
  }, [dispatch]);

  const onSubmitHandler = ({ email }) => {
    dispatch(resetPassword(email));
  };

  const redirect = isAuth && <Redirect to={paths.ROOT} />;

  const recoverEmailMessage = useFormatMessage('ResetPassword.recoverEmail', {
    mail: watch('email'),
  });
  const emailMessage = useFormatMessage('ResetPassword.email');
  const emailRegistrationMessage = useFormatMessage(
    'ResetPassword.emailRegistration'
  );
  const resetLinkMessage = useFormatMessage('ResetPassword.resetLink');
  const backMessage = useFormatMessage('ResetPassword.back');

  const invalidEmailMessage = useFormatMessage('invalidEmail');

  return (
    <section className="section hero is-fullheight is-error-section">
      {redirect}
      <div className="hero-body">
        <div className="container">
          <div className="columns is-centered">
            <div className="column is-two-fifths">
              <div className="card has-card-header-background">
                <header className="card-header">
                  <p className="card-header-title">
                    <span className="icon">
                      <i className="mdi mdi-lock-open default" />
                    </span>
                    <span>{useFormatMessage('ResetPassword.recovery')}</span>
                  </p>
                </header>
                <div className="card-content">
                  {restoredPassword ? (
                    <p className={classes['sub-title']}>
                      {recoverEmailMessage}
                    </p>
                  ) : (
                    <form onSubmit={handleSubmit(onSubmitHandler)}>
                      <div className="field">
                        <p className="label">{emailMessage}</p>
                        <div className="control">
                          <input
                            className={classNames('input', {
                              'is-danger': errors.email,
                            })}
                            ref={register}
                            name="email"
                          />
                        </div>
                        {errors.email && (
                          <ErrorMessage text={invalidEmailMessage} />
                        )}
                        <p className="help">{emailRegistrationMessage}</p>
                      </div>
                      <hr />
                      <div className="field is-grouped">
                        <div className="control">
                          <button
                            className={classNames(`button is-black`, {
                              'is-loading': loading,
                            })}
                            type="submit"
                          >
                            {resetLinkMessage}
                          </button>
                        </div>
                        <div className="control">
                          <Link to={paths.LOGIN} className="button is-outlined">
                            {backMessage}
                          </Link>
                        </div>
                      </div>
                      {error && (
                        <p
                          className={`has-text-danger ${classes.errorMessage}`}
                        >
                          {error}
                        </p>
                      )}
                    </form>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}
Example #14
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
User = () => {
  const { id } = useParams();

  const isEditing = useMemo(() => !!id, [id]);

  const { success, userData, error } = useSelector(
    (state) => ({
      success: state.users.success,
      userData: state.users.data.find((user) => user.id === id),
      error: state.users.error,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  useEffect(() => {
    if (isEditing) {
      if (!userData) {
        dispatch(fetchUsers(id));
      }
    }
  }, [isEditing, id, userData, dispatch]);

  const redirect = ((isEditing && error) || success) && (
    <Redirect to={paths.USERS} />
  );

  const editUserMessage = useFormatMessage('User.editUser');

  const newUserMessage = useFormatMessage('User.editUser');

  const onSubmitHandler = (value) => {
    const newUser = {
      ...value,
      file: value?.file[0] || null,
      isEditing,
      id,
    };

    if (isEditing) {
      dispatch(modifyUser(newUser));
    } else {
      dispatch(createUser(newUser));
    }
  };

  return (
    <>
      {redirect}
      <section className="hero is-hero-bar">
        <div className="hero-body">
          <h1 className="title">
            {isEditing ? editUserMessage : newUserMessage}
          </h1>
        </div>
      </section>
      <section className="section is-main-section">
        {isEditing && !userData ? (
          <ClipLoader />
        ) : (
          <UserForm
            isEditing={isEditing}
            user={
              isEditing
                ? userData
                : {
                    name: '',
                    email: '',
                    location: '',
                    createdAt: new Date().toDateString(),
                    isAdmin: false,
                  }
            }
            onSubmitHandler={onSubmitHandler}
            schema={schema}
          />
        )}
      </section>
    </>
  );
}
Example #15
Source File: index.jsx    From react-firebase-admin with MIT License 4 votes vote down vote up
Users = () => {
  const { usersList, isAdmin, error, loading, deleted } = useSelector(
    (state) => ({
      usersList: state.users.data,
      isAdmin: state.auth.userData.isAdmin,
      error: state.users.error,
      loading: state.users.loading,
      deleted: state.users.deleted,
    }),
    shallowEqual
  );

  const [deleteModal, setDeleteModal] = useState({
    userId: null,
    isOpen: false,
  });

  const dispatch = useDispatch();

  const [search, setSearch] = useState('');

  useEffect(() => {
    if (isAdmin) {
      dispatch(fetchUsers());
    }

    return () => dispatch(usersCleanUp());
  }, [dispatch, isAdmin]);

  useEffect(() => {
    if (deleted && !loading) {
      setDeleteModal((prevState) => ({
        userId: null,
        isOpen: !prevState.isOpen,
      }));
    }
  }, [deleted, loading]);

  const redirect = !isAdmin && <Redirect to={paths.ROOT} />;

  const onRemoveButtonClickHandler = (userId) => {
    setDeleteModal((prevState) => ({
      userId,
      isOpen: !prevState.isOpen,
    }));
  };

  const onCloseModalHandler = () => {
    setDeleteModal({ userId: null, isOpen: false });
  };

  const onDeleteUserHandler = () => {
    dispatch(deleteUser(deleteModal.userId));
  };

  const columns = [
    {
      Header: '',
      accessor: 'logoUrl',
      Cell: ({ row }) => (
        <div className="image">
          <img src={row.original.logoUrl} alt="" className="is-rounded" />
        </div>
      ),
      disableSortBy: true,
    },
    {
      Header: useFormatMessage('Users.name'),
      accessor: 'name',
    },
    {
      Header: useFormatMessage('Users.email'),
      accessor: 'email',
    },
    {
      Header: useFormatMessage('Users.location'),
      accessor: 'location',
    },
    {
      Header: useFormatMessage('Users.admin'),
      accessor: 'isAdmin',
      Cell: ({ row }) => (
        <small className="has-text-grey is-abbr-like">
          {row.original.isAdmin ? (
            <span className="icon">
              <i className="mdi mdi-check" />
            </span>
          ) : (
            <span className="icon">
              <i className="mdi mdi-close" />
            </span>
          )}
        </small>
      ),
    },
    {
      Header: useFormatMessage('Users.created'),
      accessor: 'created',
      Cell: ({ row }) => (
        <small className="has-text-grey is-abbr-like">
          {useFormatDate(row.original.createdAt, {
            weekday: 'short',
            year: 'numeric',
            month: 'short',
            day: 'numeric',
          })}
        </small>
      ),
    },
    {
      Header: '',
      id: 'actions',
      accessor: 'actions',
      Cell: ({ row }) => (
        <>
          {!row.original.isAdmin && (
            <div className="buttons is-right">
              <Link
                to={`/users/${row.original.id}`}
                className="button is-small is-primary"
              >
                <span className="icon is-small">
                  <i className="mdi mdi-account-edit" />
                </span>
              </Link>

              <button
                type="button"
                className="button is-small is-danger"
                onClick={() => onRemoveButtonClickHandler(row.original.id)}
              >
                <span className="icon is-small">
                  <i className="mdi mdi-trash-can" />
                </span>
              </button>
            </div>
          )}
        </>
      ),
      disableSortBy: true,
    },
  ];

  const data = search
    ? usersList.filter((el) => {
        const clonedElem = { ...el };
        delete clonedElem.id;
        delete clonedElem.isAdmin;
        delete clonedElem.logoUrl;
        return Object.values(clonedElem).some((field) =>
          field.toLowerCase().includes(search.toLowerCase())
        );
      })
    : usersList;

  const deleteMessage = useFormatMessage('Users.delete');

  const confirmMessage = useFormatMessage('Users.confirm');

  const permDeleteMessage = useFormatMessage('Users.permDelete');

  const cancelMessage = useFormatMessage('Users.cancel');

  return (
    <>
      {redirect}
      {deleteModal.isOpen && (
        <ConfirmationModal
          isActive={deleteModal.isOpen}
          isLoading={loading}
          confirmButtonMessage={deleteMessage}
          title={confirmMessage}
          body={permDeleteMessage}
          cancelButtonMessage={cancelMessage}
          onConfirmation={onDeleteUserHandler}
          onCancel={onCloseModalHandler}
        />
      )}
      <section className="hero is-hero-bar">
        <div className="hero-body">
          <div className="level">
            <div className="level-left">
              <div className="level-item">
                <h1 className="title">{useFormatMessage('Users.users')}</h1>
              </div>
            </div>
            <div className="level-right">
              <div className="level-item">
                <Link to={paths.ADD_USER} className="button">
                  {useFormatMessage('Users.newUser')}
                </Link>
              </div>
            </div>
          </div>
        </div>
      </section>
      <section className="section is-main-section">
        <div className="card has-table has-mobile-sort-spaced">
          <header className="card-header">
            <p className={classNames('card-header-title', classes.tableHeader)}>
              <span>{useFormatMessage('Users.search')}</span>
              <input
                type="text"
                className="input"
                value={search}
                onChange={(e) => setSearch(e.target.value)}
              />
            </p>
          </header>
          <div className="b-table">
            {loading ? <ClipLoader /> : <Table columns={columns} data={data} />}
            {error && 'Show error'}
          </div>
        </div>
      </section>
    </>
  );
}