change password + setting + notification + header
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
import { Fragment } from 'react'
|
||||||
|
import { Switch } from '@headlessui/react'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
active: boolean,
|
||||||
|
onChange: (value: boolean) => void,
|
||||||
|
isLoading?: boolean,
|
||||||
|
label?: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const SwitchComponent = (props: Props) => {
|
||||||
|
|
||||||
|
const handleChange = (value: boolean) => {
|
||||||
|
props.onChange(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='dltr w-fit flex gap-2 items-center'>
|
||||||
|
<Switch checked={props.active} onChange={handleChange} as={Fragment}>
|
||||||
|
{({ checked }) => (
|
||||||
|
<button
|
||||||
|
className={`${checked ? 'bg-primary' : 'bg-gray-200'
|
||||||
|
} relative inline-flex h-6 w-11 items-center rounded-full`}
|
||||||
|
>
|
||||||
|
<span className="sr-only">Enable notifications</span>
|
||||||
|
<span
|
||||||
|
className={`${checked ? 'translate-x-6' : 'translate-x-1'
|
||||||
|
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</Switch>
|
||||||
|
{
|
||||||
|
props.label &&
|
||||||
|
<div className='text-sm'>
|
||||||
|
: {props.label}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SwitchComponent
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
title: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
const TitleLine: FC<Props> = (props: Props) => {
|
||||||
|
return (
|
||||||
|
<div className='w-full text-sm flex items-center gap-4'>
|
||||||
|
<div className='whitespace-nowrap'>{props.title}</div>
|
||||||
|
<svg style={{ width: '100%', height: 1 }} xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="none">
|
||||||
|
<line x1="0" y1="0" x2="100%" y2="0" stroke="#aaa" strokeWidth="1" strokeDasharray="5 3" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TitleLine
|
||||||
+22
-57
@@ -70,65 +70,30 @@
|
|||||||
"all_read": "خواندن همه"
|
"all_read": "خواندن همه"
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"title": "تنظیمات",
|
|
||||||
"personality": "شخصی سازی",
|
|
||||||
"mail_server": "تنظیمات میل سرور",
|
|
||||||
"domain": "تنظیمات دامنه",
|
|
||||||
"address": "نشانی ها",
|
|
||||||
"setting": "تنظیمات",
|
"setting": "تنظیمات",
|
||||||
"background": "رنگ زمینه",
|
"notification": "نوتیفیکیشن",
|
||||||
"upload_background": "تصویر پس زمینه مورد نظر را آپلود کنید",
|
"password": "رمز عبور",
|
||||||
"size": "سایز",
|
"setting_email_message": "تنظیمات نوتیفیکیشن",
|
||||||
"horizontal_position": "موقعیت افقی",
|
"notification_announcement": "اعلانات و اطلاعیه ها",
|
||||||
"vertical_position": "موقعیت عمودی",
|
|
||||||
"text": "متن",
|
|
||||||
"add_text": "اضافه کردن متن",
|
|
||||||
"button": "دکمه",
|
|
||||||
"button_text": "متن دکمه",
|
|
||||||
"button_link": "لینک",
|
|
||||||
"select": "انتخاب",
|
|
||||||
"border": "حاشیه",
|
|
||||||
"text_color": "رنگ متن",
|
|
||||||
"background_color": "رنگ زمینه",
|
|
||||||
"border_color": "رنگ حاشیه",
|
|
||||||
"add_button": "اضافه کردن دکمه",
|
|
||||||
"image": "تصویر",
|
|
||||||
"upload_image": "تصویر مورد نظر را آپلود کنید",
|
|
||||||
"add_image": "اضافه کردن تصویر",
|
|
||||||
"setting_fetch": "تنظیمات فچ",
|
|
||||||
"setting_fetch_description": "تنظیمات فچ خود را با دقت انتخاب کنید.",
|
|
||||||
"setting_smtp": "تنظیمات SMTP",
|
|
||||||
"setting_smtp_description": "تنظیمات SMTP خود را با دقت وارد کنید.",
|
|
||||||
"smtp_server": "SMTP سرور",
|
|
||||||
"smtp_port": "SMTP پورت",
|
|
||||||
"username": "نام کاربری",
|
|
||||||
"password": "پسورد",
|
|
||||||
"record_dns": "رکوردهای DNS",
|
|
||||||
"record_dns_description": "در این قسمت میتوانید وضعیت رکوردهای DNS سرویس ایمیل خود را بررسی کنید.",
|
|
||||||
"your_domain": "دامنه شما",
|
|
||||||
"submit": "ثبت",
|
|
||||||
"status": "وضعیت",
|
|
||||||
"search": "جستجو",
|
|
||||||
"address_title": "عنوان نشانی",
|
|
||||||
"email": "ایمیل",
|
"email": "ایمیل",
|
||||||
"marketing": "بازاریابی",
|
"sms": "پیامک",
|
||||||
"actions": "عملیات",
|
"change_password": "تغییر رمز عبور",
|
||||||
"delete": "حذف کردن ایمیل",
|
"current_password": "رمز عبور فعلی",
|
||||||
"active": "فعال",
|
"new_password": "رمز عبور جدید",
|
||||||
"inactive": "غیرفعال",
|
"reapeat_password": "تکرار رمز عبور",
|
||||||
"add_address": "اضافه کردن نشانی",
|
"save_change": "ذخیره تغییرات",
|
||||||
"domain1": "دامنه",
|
"password_is": "رمز عبور میبایست:",
|
||||||
"create": "ساخت",
|
"min-8": "حداقل 8 کاراکتر باشد",
|
||||||
"header_email": "هدر ایمیل شما",
|
"mix_charachter_number": "ترکیبی از حروف کوچک و بزرگ باشد",
|
||||||
"content_email": "محتوای ایمیل شما",
|
"exsist_number": "شامل اعداد باشد",
|
||||||
"footer_email": "پاورقی ایمیل شما",
|
"exsist_special_character": "شامل کاراکتر های خاص (نماد ها) باشد",
|
||||||
"signature": "امضا",
|
"password_changed": "رمز عبور با موفقیت تغییر یافت",
|
||||||
"signature_description": "تصویر و توضیحات امضای خود را با دقت وارد کنید",
|
"SUPPORT": "پشتیبانی",
|
||||||
"upload_sign": "آپلود امضا",
|
"SERVICE": "سرویس",
|
||||||
"description_sign": "توضیحات امضا",
|
"INVOICE": "صورتحساب",
|
||||||
"select_section": "لطفا یک بخش انتخاب کنید",
|
"ACCOUNT": "حساب",
|
||||||
"title1": "عنوان",
|
"NOTIFICATION": "اعلان",
|
||||||
"quota": "فضا/ استفاده شده "
|
"FINANCE": "مالی"
|
||||||
},
|
},
|
||||||
"attachment_select": "اضافه کردن فایل ضمیمه",
|
"attachment_select": "اضافه کردن فایل ضمیمه",
|
||||||
"domain": {
|
"domain": {
|
||||||
|
|||||||
@@ -82,9 +82,9 @@ const Notifications: FC = () => {
|
|||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<div onClick={() => setShowModal(!showModal)} className='relative cursor-pointer'>
|
<div onClick={() => setShowModal(!showModal)} className='relative cursor-pointer'>
|
||||||
<Notification size={18} color="black" />
|
<Notification size={18} color="black" />
|
||||||
{/* <div className="absolute top-0 right-0 -mt-1 -mr-1 rounded-full bg-red-500 text-white text-[8px] size-3 flex pt-0.5 pl-[1px] justify-center items-center">
|
<div className="absolute top-0 right-0 -mt-1 -mr-1 rounded-full bg-red-500 text-white text-[8px] size-3 flex pt-0.5 pl-[1px] justify-center items-center">
|
||||||
{getDashboard.data?.data?.notificationCount}
|
{data?.pages[0]?.data?.notificationCount}
|
||||||
</div> */}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{showModal && (
|
{showModal && (
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
import { FC, Fragment, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Tabs from '../../components/Tabs'
|
||||||
|
import { KeySquare, Notification1 } from 'iconsax-react'
|
||||||
|
import { useGetSettings } from './hooks/useSettingData'
|
||||||
|
import Sms from './components/Sms'
|
||||||
|
import ChangePassword from './components/ChangePassword'
|
||||||
|
import TitleLine from '@/components/TitleLine'
|
||||||
|
import { SettingCategoryType, SettingItemType } from './types/SettingTypes'
|
||||||
|
|
||||||
|
const Setting: FC = () => {
|
||||||
|
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const getSettings = useGetSettings()
|
||||||
|
const [activeTab, setActiveTab] = useState<string>('notification')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mt-4'>
|
||||||
|
<div>
|
||||||
|
{t('setting.setting')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-10'>
|
||||||
|
<Tabs
|
||||||
|
items={[
|
||||||
|
{
|
||||||
|
icon: <Notification1 color={activeTab === 'notification' ? 'black' : '#8C90A3'} size={22} />,
|
||||||
|
label: t('setting.notification'),
|
||||||
|
value: 'notification'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: <KeySquare color={activeTab === 'password' ? 'black' : '#8C90A3'} size={22} />,
|
||||||
|
label: t('setting.password'),
|
||||||
|
value: 'password'
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
active={activeTab}
|
||||||
|
onChange={setActiveTab}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
activeTab === 'notification' ?
|
||||||
|
<div className='mt-10 bg-white xl:p-8 p-4 rounded-3xl'>
|
||||||
|
<div>
|
||||||
|
{t('setting.setting_email_message')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex xl:flex-row flex-wrap flex-col gap-6 text-sm mt-8'>
|
||||||
|
{
|
||||||
|
getSettings.isPending ?
|
||||||
|
<div className='w-full'>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
getSettings.data?.data?.settings?.map((item: SettingCategoryType) => {
|
||||||
|
return (
|
||||||
|
<Fragment key={item.category}>
|
||||||
|
<TitleLine
|
||||||
|
title={t(`setting.${item.category}`)}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
item.settings?.map((settingItem: SettingItemType) => {
|
||||||
|
return (
|
||||||
|
<div key={settingItem.id} className='flex-1 min-w-[40%] border border-border px-4 rounded-2xl min-h-14 items-center flex justify-between'>
|
||||||
|
<div className='xl:text-[13px] text-xs'>
|
||||||
|
{settingItem?.description}
|
||||||
|
</div>
|
||||||
|
<div className='flex xl:gap-4 gap-2'>
|
||||||
|
{/* <div className='flex gap-2 text-xs items-center text-description'>
|
||||||
|
<div>
|
||||||
|
{t('setting.email')}
|
||||||
|
</div>
|
||||||
|
<Email id={settingItem.id} email={settingItem.email} />
|
||||||
|
</div> */}
|
||||||
|
<div className='flex gap-2 text-xs items-center text-description'>
|
||||||
|
<Sms
|
||||||
|
sms={settingItem.isActive}
|
||||||
|
id={settingItem.id}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
<div className='flex-1 px-4 min-w-[40%]'></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<ChangePassword />
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Setting
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { FC } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Input from '../../../components/Input'
|
||||||
|
import Button from '../../../components/Button'
|
||||||
|
import { useFormik } from 'formik'
|
||||||
|
import { ChangePasswordType } from '../types/SettingTypes'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import { toast } from '../../../components/Toast'
|
||||||
|
import { useChangePassword } from '../hooks/useSettingData'
|
||||||
|
import { ErrorType } from '../../../helpers/types'
|
||||||
|
import { TickCircle } from 'iconsax-react'
|
||||||
|
|
||||||
|
const ChangePassword: FC = () => {
|
||||||
|
|
||||||
|
const changePassword = useChangePassword()
|
||||||
|
const { t } = useTranslation('global')
|
||||||
|
|
||||||
|
const formik = useFormik<ChangePasswordType>({
|
||||||
|
initialValues: {
|
||||||
|
oldPassword: '',
|
||||||
|
newPassword: '',
|
||||||
|
repeatPassword: ''
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
oldPassword: Yup.string()
|
||||||
|
.required(t('errors.required')),
|
||||||
|
newPassword: Yup.string()
|
||||||
|
.required(t('errors.required')),
|
||||||
|
repeatPassword: Yup.string()
|
||||||
|
.required(t('errors.required')),
|
||||||
|
}),
|
||||||
|
onSubmit: (values) => {
|
||||||
|
if (values.newPassword !== values.repeatPassword) {
|
||||||
|
toast(t('errors.password_not_match'), 'error')
|
||||||
|
} else {
|
||||||
|
changePassword.mutate(values, {
|
||||||
|
onSuccess: () => {
|
||||||
|
toast(t('setting.password_changed'), 'success')
|
||||||
|
formik.resetForm()
|
||||||
|
},
|
||||||
|
onError: (error: ErrorType) => {
|
||||||
|
toast(error.response?.data?.error?.message[0], 'error')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className='mt-10 bg-white p-8 rounded-3xl'>
|
||||||
|
<div>
|
||||||
|
{t('setting.change_password')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex xl:flex-row flex-col xl:gap-10 gap-4'>
|
||||||
|
<div className='flex-1'>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
className='mt-6'
|
||||||
|
placeholder={t('setting.current_password')}
|
||||||
|
name='oldPassword'
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
error_text={formik.touched.oldPassword && formik.errors.oldPassword ? formik.errors.oldPassword : ''}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
className='mt-6'
|
||||||
|
placeholder={t('setting.new_password')}
|
||||||
|
name='newPassword'
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
error_text={formik.touched.newPassword && formik.errors.newPassword ? formik.errors.newPassword : ''}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
className='mt-6'
|
||||||
|
placeholder={t('setting.reapeat_password')}
|
||||||
|
name='repeatPassword'
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
error_text={formik.touched.repeatPassword && formik.errors.repeatPassword ? formik.errors.repeatPassword : ''}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className='mt-9 xl:block hidden'>
|
||||||
|
<Button
|
||||||
|
className='w-fit px-4'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('setting.save_change')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='flex-1 xl:p-8 p-4 bg-[#EEF0F7] rounded-3xl text-sm'>
|
||||||
|
<div>
|
||||||
|
{t('setting.password_is')}
|
||||||
|
</div>
|
||||||
|
<ul className='list-disc ps-4 flex flex-col gap-2 text-xs mt-4'>
|
||||||
|
<li>
|
||||||
|
{t('setting.min-8')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{t('setting.mix_charachter_number')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{t('setting.exsist_number')}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{t('setting.exsist_special_character')}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className=' xl:hidden block'>
|
||||||
|
<Button
|
||||||
|
className='w-32 hidden xl:block'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
>
|
||||||
|
<div className='flex gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('setting.save_change')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='justify-end xl:hidden flex'>
|
||||||
|
<Button
|
||||||
|
className='xl:w-fit px-10'
|
||||||
|
onClick={() => formik.handleSubmit()}
|
||||||
|
loading={changePassword.isPending}
|
||||||
|
>
|
||||||
|
<div className='flex justify-center gap-2 items-center'>
|
||||||
|
<TickCircle size={20} color='white' />
|
||||||
|
<div>
|
||||||
|
{t('setting.save_change')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='h-14'></div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChangePassword
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { FC, useState } from 'react'
|
||||||
|
import SwitchComponent from '../../../components/Switch'
|
||||||
|
import { useUpdateSetting } from '../hooks/useSettingData'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
email: boolean,
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Email: FC<Props> = (props: Props) => {
|
||||||
|
const updateSetting = useUpdateSetting()
|
||||||
|
const [email, setEmail] = useState<boolean>(props.email)
|
||||||
|
|
||||||
|
const handleChange = (value: boolean) => {
|
||||||
|
setEmail(value)
|
||||||
|
updateSetting.mutate({ email: value, id: props.id })
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SwitchComponent
|
||||||
|
active={email}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Email
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { FC, useState } from 'react'
|
||||||
|
import SwitchComponent from '@/components/Switch'
|
||||||
|
import { useUpdateSetting } from '../hooks/useSettingData'
|
||||||
|
import { ErrorType } from '../../../helpers/types'
|
||||||
|
import { toast } from '../../../components/Toast'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
sms: boolean,
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const Sms: FC<Props> = (props: Props) => {
|
||||||
|
const updateSetting = useUpdateSetting()
|
||||||
|
const [sms, setSms] = useState<boolean>(props.sms)
|
||||||
|
|
||||||
|
const handleChange = (value: boolean) => {
|
||||||
|
setSms(value)
|
||||||
|
updateSetting.mutate({ sms: value, id: props.id }, {
|
||||||
|
onError: (error: ErrorType) => {
|
||||||
|
toast(error.response?.data?.error?.message[0], 'error')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SwitchComponent
|
||||||
|
active={sms}
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Sms
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
|
import * as api from "../service/SettingService";
|
||||||
|
import { ChangePasswordType, UpdateSettingType } from "../types/SettingTypes";
|
||||||
|
|
||||||
|
export const useGetSettings = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ["settings"],
|
||||||
|
queryFn: () => api.getSettings(),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUpdateSetting = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (variables: UpdateSettingType) => api.updateSettings(variables),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useChangePassword = () => {
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: (variables: ChangePasswordType) =>
|
||||||
|
api.changePassword(variables),
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import axios from "../../../config/axios";
|
||||||
|
import { ChangePasswordType, UpdateSettingType } from "../types/SettingTypes";
|
||||||
|
|
||||||
|
export const getSettings = async () => {
|
||||||
|
const { data } = await axios.get(`/settings`);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const updateSettings = async (params: UpdateSettingType) => {
|
||||||
|
await axios.patch(`/settings/${params.id}/toggle`, params);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const changePassword = async (params: ChangePasswordType) => {
|
||||||
|
await axios.patch(`/auth/change-password`, params);
|
||||||
|
};
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
export type UpdateSettingType = {
|
||||||
|
id: string;
|
||||||
|
email?: boolean;
|
||||||
|
sms?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ChangePasswordType = {
|
||||||
|
oldPassword: string;
|
||||||
|
newPassword: string;
|
||||||
|
repeatPassword: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SettingItemType = {
|
||||||
|
id: string;
|
||||||
|
type: string;
|
||||||
|
isActive: boolean;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SettingCategoryType = {
|
||||||
|
category: string;
|
||||||
|
settings: SettingItemType[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SettingsResponseType = {
|
||||||
|
statusCode: number;
|
||||||
|
success: boolean;
|
||||||
|
data: {
|
||||||
|
settings: SettingCategoryType[];
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -11,6 +11,7 @@ import SpamList from '@/pages/spam/List'
|
|||||||
import SearchList from '@/pages/search/List'
|
import SearchList from '@/pages/search/List'
|
||||||
import DetailEmail from '@/pages/received/Detail'
|
import DetailEmail from '@/pages/received/Detail'
|
||||||
import Login from '@/pages/auth/Login'
|
import Login from '@/pages/auth/Login'
|
||||||
|
import Setting from '@/pages/setting/Setting'
|
||||||
|
|
||||||
const AppRouter: FC = () => {
|
const AppRouter: FC = () => {
|
||||||
return (
|
return (
|
||||||
@@ -26,6 +27,7 @@ const AppRouter: FC = () => {
|
|||||||
<Route path={Paths.search} element={<SearchList />} />
|
<Route path={Paths.search} element={<SearchList />} />
|
||||||
<Route path={Paths.detailEmail + ':id'} element={<DetailEmail />} />
|
<Route path={Paths.detailEmail + ':id'} element={<DetailEmail />} />
|
||||||
<Route path={Paths.login} element={<Login />} />
|
<Route path={Paths.login} element={<Login />} />
|
||||||
|
<Route path={Paths.setting} element={<Setting />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user