openreplay/frontend/app/components/ForgotPassword/CreatePassword.tsx
Delirium a71381da40
getting rid of redux for good (#2556)
* start moving ui to redux tlk

* remove unused reducer

* changes for gdpr and site types

* ui: migrating duck/roles to mobx

* ui: drop unreferenced types

* ui: drop unreferenced types

* ui: move player slice reducer to mobx family

* ui: move assignments to issueReportingStore.ts

* remove issues store

* some fixes after issues store

* remove errors reducer, drop old components

* finish removing errors reducer

* start moving integrations state to mobx

* change(ui): funnel duck cleanup

* change(ui): custom fields

* change(ui): customMetrics cleanup

* change(ui): customMetrics cleanup

* change(ui): duck/filters minor cleanup

* change(ui): duck/filters cleanup

* change(ui): duck/customMetrics cleanup and upgrades

* fix integrations service, fix babel config to >.25 + not ie

* refactoring integrations reducers etc WIP

* finish removing integrations state

* some fixes for integrated check

* start of projects refactoring

* move api and "few" files to new project store

* new batch for site -> projects

* fix setid context

* move all critical components, drop site duck

* remove all duck/site refs, remove old components

* fixup for SessionTags.tsx, remove duck/sources (?)

* move session store

* init sessionstore outside of context

* fix userfilter

* replace simple actions for session store

* sessions sotre

* Rtm temp (#2597)

* change(ui): duck/search wip

* change(ui): duck/search wip

* change(ui): duck/search wip

* change(ui): duck/searchLive wip

* change(ui): duck/searchLive wip

* change(ui): duck/searchLive wip

* change(ui): duck/searchLive wip

* change(ui): search states

* change(ui): search states

* change(ui): search states

* change(ui): fix savedSearch store

* change(ui): fix savedSearch store

* some fixes for session connector

* change(ui): fix savedSearch store

* change(ui): fix searchLive

* change(ui): fix searchLive

* fixes for session replay

* change(ui): bookmark fetch

* last components for sessions

* add fetchautoplaylist

* finish session reducer, remove deleted reducers

* change(ui): fix the search fetch

* change(ui): fix the search fetch

* fix integrations call ctx

* ensure ctx for sessionstore

* fix(ui): checking for latest sessions path

* start removing user reducer

* removing user reducer pt2...

* finish user store

* remove rand log

* fix crashes

* tinkering workflow file for tracker test

* making sure prefetched sessions work properly

* fix conflict

* fix router redirects during loading

---------

Co-authored-by: Shekar Siri <sshekarsiri@gmail.com>
2024-10-03 11:38:36 +02:00

149 lines
4.9 KiB
TypeScript

import React, { useEffect } from 'react';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import ReCAPTCHA from 'react-google-recaptcha';
import { Form, Input, Loader, Button, Icon, Message } from 'UI';
import stl from './forgotPassword.module.css';
import { validatePassword } from 'App/validate';
import { PASSWORD_POLICY } from 'App/constants';
const recaptchaRef = React.createRef();
const ERROR_DONT_MATCH = "Passwords don't match.";
const CAPTCHA_ENABLED = window.env.CAPTCHA_ENABLED === 'true';
const CAPTCHA_SITE_KEY = window.env.CAPTCHA_SITE_KEY;
interface Props {
params: any;
}
function CreatePassword(props: Props) {
const { params } = props;
const { userStore } = useStore();
const loading = userStore.loading;
const resetPassword = userStore.resetPassword;
const [error, setError] = React.useState<String | null>(null);
const [validationError, setValidationError] = React.useState<String | null>(null);
const [updated, setUpdated] = React.useState(false);
const [passwordRepeat, setPasswordRepeat] = React.useState('');
const [password, setPassword] = React.useState('');
const pass = params.get('pass');
const invitation = params.get('invitation');
const handleSubmit = () => {
if (!validatePassword(password)) {
return;
}
resetPassword({ invitation, pass, password }).then((response: any) => {
if (response && response.errors && response.errors.length > 0) {
setError(response.errors[0]);
} else {
setUpdated(true);
}
});
};
const onSubmit = (e: any) => {
e.preventDefault();
if (CAPTCHA_ENABLED && recaptchaRef.current) {
recaptchaRef.current.execute();
} else if (!CAPTCHA_ENABLED) {
handleSubmit();
}
};
const write = (e: any) => {
const { name, value } = e.target;
if (name === 'password') setPassword(value);
if (name === 'passwordRepeat') setPasswordRepeat(value);
};
useEffect(() => {
if (passwordRepeat.length > 0 && passwordRepeat !== password) {
setValidationError(ERROR_DONT_MATCH);
} else if (passwordRepeat.length > 0 && !validatePassword(password)) {
setValidationError(PASSWORD_POLICY);
} else {
setValidationError(null);
}
}, [passwordRepeat, password]);
return (
<Form
onSubmit={onSubmit}
style={{ minWidth: '50%' }}
className="flex flex-col items-center justify-center"
>
{!error && (
<>
<Loader loading={loading}>
<div data-hidden={updated} className="w-full">
{CAPTCHA_ENABLED && (
<div className={stl.recaptcha}>
<ReCAPTCHA
ref={recaptchaRef}
size="invisible"
sitekey={CAPTCHA_SITE_KEY}
onChange={(token: any) => handleSubmit(token)}
/>
</div>
)}
<React.Fragment>
<Form.Field>
<label>{'New password'}</label>
<Input
autoComplete="new-password"
type="password"
placeholder="Type here..."
name="password"
onChange={write}
className="w-full"
icon="key"
required
/>
</Form.Field>
<Form.Field>
<label>{'Cofirm password'}</label>
<Input
autoComplete="new-password"
type="password"
placeholder="Re-enter your new password"
name="passwordRepeat"
onChange={write}
className="w-full"
icon="key"
required
/>
</Form.Field>
</React.Fragment>
</div>
</Loader>
<div className="mt-4">
<div data-hidden={!updated} className="flex items-center flex-col text-center">
<div className="w-10 h-10 bg-tealx-lightest rounded-full flex items-center justify-center mb-3">
<Icon name="check" size="30" color="tealx" />
</div>
<span>{'Your password has been updated successfully.'}</span>
</div>
</div>
{validationError && <Message error>{validationError}</Message>}
<Button type="submit" variant="primary" loading={loading} className="w-full mt-4">
Create
</Button>
</>
)}
{error && (
<div className="flex items-center flex-col text-center">
<div className="w-16 h-16 rounded-full bg-red-lightest flex items-center justify-center mb-2">
<Icon name="envelope-x" size="30" color="red" />
</div>
{error}
</div>
)}
</Form>
);
}
export default observer(CreatePassword);