erp-platform/ui/src/views/auth/settings/Password.tsx
2025-06-29 00:34:28 +03:00

197 lines
6.6 KiB
TypeScript

import Button from '@/components/ui/Button'
import { FormContainer } from '@/components/ui/Form'
import Input from '@/components/ui/Input'
import Notification from '@/components/ui/Notification'
import toast from '@/components/ui/toast'
import { changePassword } from '@/proxy/account/account.service'
import { useLocalization } from '@/utils/hooks/useLocalization'
import FormDesription from '@/views/shared/FormDesription'
import FormRow from '@/views/shared/FormRow'
import { Field, Form, Formik } from 'formik'
import {
HiOutlineDesktopComputer,
HiOutlineDeviceMobile,
HiOutlineDeviceTablet,
} from 'react-icons/hi'
import * as Yup from 'yup'
type LoginHistory = {
type: string
deviceName: string
time: number
location: string
}
type PasswordFormModel = {
password: string
newPassword: string
confirmNewPassword: string
}
const LoginHistoryIcon = ({ type }: { type: string }) => {
switch (type) {
case 'Desktop':
return <HiOutlineDesktopComputer />
case 'Mobile':
return <HiOutlineDeviceMobile />
case 'Tablet':
return <HiOutlineDeviceTablet />
default:
return <HiOutlineDesktopComputer />
}
}
const validationSchema = Yup.object().shape({
password: Yup.string().required('Password Required'),
newPassword: Yup.string()
.required('Enter your new password')
.min(6, 'Too Short!')
.matches(
/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{6,})/,
'Must Contain Uppercase, Lowercase, Number and Special Character',
),
confirmNewPassword: Yup.string().oneOf([Yup.ref('newPassword'), ''], 'Password not match'),
})
const Password = ({ data }: { data?: LoginHistory[] }) => {
const onFormSubmit = async (
values: PasswordFormModel,
setSubmitting: (isSubmitting: boolean) => void,
) => {
const resp = await changePassword(values.password, values.newPassword)
if (resp.status === 204) {
toast.push(<Notification title={'Password updated'} type="success" />, {
placement: 'top-center',
})
} else {
toast.push(<Notification title={resp?.error?.message} type="danger" />, {
placement: 'top-center',
})
}
setSubmitting(false)
}
const { translate } = useLocalization()
return (
<>
<Formik
initialValues={{
password: '',
newPassword: '',
confirmNewPassword: '',
}}
validationSchema={validationSchema}
onSubmit={(values, { setSubmitting }) => {
setSubmitting(true)
setTimeout(() => {
onFormSubmit(values, setSubmitting)
}, 1000)
}}
>
{({ touched, errors, isSubmitting, resetForm }) => {
const validatorProps = { touched, errors }
return (
<Form>
<FormContainer>
<FormDesription
title={translate('::Abp.Identity.Password')}
desc={translate('::Abp.Identity.Password.Description')}
/>
<FormRow
name="password"
label={translate('::Abp.Identity.Password.CurrentPassword')}
{...validatorProps}
>
<Field
type="password"
autoComplete="off"
name="password"
placeholder={translate('::Abp.Identity.Password.CurrentPassword')}
component={Input}
/>
</FormRow>
<FormRow
name="newPassword"
label={translate('::Abp.Identity.Password.NewPassword')}
{...validatorProps}
>
<Field
type="password"
autoComplete="off"
name="newPassword"
placeholder={translate('::Abp.Identity.Password.NewPassword')}
component={Input}
/>
</FormRow>
<FormRow
name="confirmNewPassword"
label={translate('::Abp.Identity.Password.ConfirmPassword')}
{...validatorProps}
>
<Field
type="password"
autoComplete="off"
name="confirmNewPassword"
placeholder={translate('::Abp.Identity.Password.ConfirmPassword')}
component={Input}
/>
</FormRow>
<div className="mt-4 ltr:text-right">
<Button className="ltr:mr-2 rtl:ml-2" type="button" onClick={() => resetForm()}>
{translate('::Cancel')}
</Button>
<Button variant="solid" loading={isSubmitting} type="submit">
{isSubmitting ? translate('::SavingWithThreeDot') : translate('::Save')}
</Button>
</div>
</FormContainer>
</Form>
)
}}
</Formik>
{/* <div className="mt-6">
<FormDesription
title="Where you're signed in"
desc="You're signed in to your account on these devices."
/>
{data && (
<div className="rounded-lg border border-gray-200 dark:border-gray-600 mt-6">
{data.map((log, index) => (
<div
key={log.deviceName}
className={classNames(
'flex items-center px-4 py-6',
!isLastChild(data, index) && 'border-b border-gray-200 dark:border-gray-600',
)}
>
<div className="flex items-center">
<div className="text-3xl">
<LoginHistoryIcon type={log.type} />
</div>
<div className="ml-3 rtl:mr-3">
<div className="flex items-center">
<div className="text-gray-900 dark:text-gray-100 font-semibold">
{log.deviceName}
</div>
{index === 0 && (
<Tag className="bg-emerald-100 text-emerald-600 dark:bg-emerald-500/20 dark:text-emerald-100 rounded-md border-0 mx-2">
<span className="capitalize"> Current </span>
</Tag>
)}
</div>
<span>
{log.location} • {dayjs.unix(log.time).format('DD-MMM-YYYY, hh:mm A')}
</span>
</div>
</div>
</div>
))}
</div>
)}
</div> */}
</>
)
}
export default Password