diff --git a/index.html b/index.html index e4b78ea..229c4a8 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,16 @@ - - - - - Vite + React + TS - - -
- - - + + + + + + داناک - dzone + + + +
+ + + + \ No newline at end of file diff --git a/src/assets/.DS_Store b/src/assets/.DS_Store index 62c0022..3bf9c76 100644 Binary files a/src/assets/.DS_Store and b/src/assets/.DS_Store differ diff --git a/src/langs/fa.json b/src/langs/fa.json index a07c907..eccf40b 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -69,7 +69,8 @@ "login_with_otp": "ورود با رمز عبور یکبار مصرف", "mobile_number": "شماره موبایل", "enter_mobile_number": "شماره موبایل خود را وارد کنید", - "enter_verify_code": "کد تایید خود را وارد کنید" + "enter_verify_code": "کد تایید خود را وارد کنید", + "otp_sent": "کد تایید برای شما ارسال شد" }, "errors": { "required": "این فیلد اجباری می باشد" @@ -320,7 +321,8 @@ "notification": "پیام و ایمیل", "password": "رمز عبور", "setting_email_message": "تنظیمات ارسال پیام و ایمیل", - "notification_announcement": "اعلانات و اطلاعیه ها", + "activity_notifications": "اعلان‌های فعالیت", + "system_notifications": "اعلان‌های سیستمی", "email": "ایمیل", "sms": "پیامک", "change_password": "تغییر رمز عبور", @@ -332,7 +334,8 @@ "min-8": "حداقل 8 کاراکتر باشد", "mix_charachter_number": "ترکیبی از حروف کوچک و بزرگ باشد", "exsist_number": "شامل اعداد باشد", - "exsist_special_character": "شامل کاراکتر های خاص (نماد ها) باشد" + "exsist_special_character": "شامل کاراکتر های خاص (نماد ها) باشد", + "password_changed": "رمز عبور با موفقیت تغییر کرد" }, "wallet": { "increese_wallet": "افزایش موجودی حساب اعتباری", diff --git a/src/pages/company/Detail.tsx b/src/pages/company/Detail.tsx index 4fce78c..8d8e0a4 100644 --- a/src/pages/company/Detail.tsx +++ b/src/pages/company/Detail.tsx @@ -19,10 +19,10 @@ const CompanyDetail: FC = () => {
-
+
{data?.data?.company?.name}
@@ -30,14 +30,14 @@ const CompanyDetail: FC = () => { size={20} color='black' /> -
+
آدرس در نقشه
-
+
{ + + const { t } = useTranslation('global') + // const getSettings = useGetSettings() + const [activeTab, setActiveTab] = useState('notification') + + return ( +
+
+ {t('setting.setting')} +
+ +
+ , + label: t('setting.notification'), + value: 'notification' + }, + { + icon: , + label: t('setting.password'), + value: 'password' + }, + ]} + active={activeTab} + onChange={setActiveTab} + /> +
+ + { + activeTab === 'notification' ? +
+
+ {t('setting.setting_email_message')} +
+ +
+ { + mockSettings.data.settings.map((item: any) => { + return ( + + + { + item.settings?.map((setting: any) => { + return ( +
+
+ {setting?.description} +
+
+
+ +
+
+
+ ) + }) + } +
+ ) + }) + } +
+
+
+ : + + } + +
+ ) +} + +export default Setting \ No newline at end of file diff --git a/src/pages/setting/components/ChangePassword.tsx b/src/pages/setting/components/ChangePassword.tsx new file mode 100644 index 0000000..43132e1 --- /dev/null +++ b/src/pages/setting/components/ChangePassword.tsx @@ -0,0 +1,155 @@ +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({ + initialValues: { + password: '', + newPassword: '', + repeatPassword: '' + }, + validationSchema: Yup.object({ + password: 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 { + // API هنوز ایجاد نشده، بنابراین فقط پیام نمایش می‌دهیم + toast(t('setting.password_changed'), 'success') + formik.resetForm() + // changePassword.mutate(values, { + // onSuccess: () => { + // toast(t('setting.password_changed'), 'success') + // formik.resetForm() + // }, + // onError: (error: ErrorType) => { + // toast(error.response?.data?.error?.message[0], 'error') + // } + // }) + } + } + }) + + return ( +
+
+ {t('setting.change_password')} +
+ +
+
+ + + + +
+ +
+
+ +
+
+ {t('setting.password_is')} +
+
    +
  • + {t('setting.min-8')} +
  • +
  • + {t('setting.mix_charachter_number')} +
  • +
  • + {t('setting.exsist_number')} +
  • +
  • + {t('setting.exsist_special_character')} +
  • +
+
+ +
+ +
+ +
+ +
+
+ +
+
+ ) +} + +export default ChangePassword \ No newline at end of file diff --git a/src/pages/setting/components/Email.tsx b/src/pages/setting/components/Email.tsx new file mode 100644 index 0000000..958fb1d --- /dev/null +++ b/src/pages/setting/components/Email.tsx @@ -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) => { + const updateSetting = useUpdateSetting() + const [email, setEmail] = useState(props.email) + + const handleChange = (value: boolean) => { + setEmail(value) + updateSetting.mutate({ email: value, id: props.id }) + } + + return ( + + ) +} + +export default Email \ No newline at end of file diff --git a/src/pages/setting/components/Sms.tsx b/src/pages/setting/components/Sms.tsx new file mode 100644 index 0000000..56d4773 --- /dev/null +++ b/src/pages/setting/components/Sms.tsx @@ -0,0 +1,35 @@ +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) => { + // const updateSetting = useUpdateSetting() + const [sms, setSms] = useState(props.sms) + + const handleChange = (value: boolean) => { + setSms(value) + // فعلا API نداریم پس فقط توست نمایش می‌دهیم + toast("تنظیمات با موفقیت ذخیره شد", 'success') + // updateSetting.mutate({ sms: value, id: props.id }, { + // onError: (error: ErrorType) => { + // toast(error.response?.data?.error?.message[0], 'error') + // } + // }) + } + + return ( + + ) +} + +export default Sms \ No newline at end of file diff --git a/src/pages/setting/hooks/useSettingData.ts b/src/pages/setting/hooks/useSettingData.ts new file mode 100644 index 0000000..00811b1 --- /dev/null +++ b/src/pages/setting/hooks/useSettingData.ts @@ -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), + }); +}; diff --git a/src/pages/setting/service/SettingService.ts b/src/pages/setting/service/SettingService.ts new file mode 100644 index 0000000..5c4dd5c --- /dev/null +++ b/src/pages/setting/service/SettingService.ts @@ -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); +}; diff --git a/src/pages/setting/types/SettingTypes.ts b/src/pages/setting/types/SettingTypes.ts new file mode 100644 index 0000000..4c7eac2 --- /dev/null +++ b/src/pages/setting/types/SettingTypes.ts @@ -0,0 +1,11 @@ +export type UpdateSettingType = { + id: string; + email?: boolean; + sms?: boolean; +}; + +export type ChangePasswordType = { + password: string; + newPassword: string; + repeatPassword: string; +}; diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 2fc648c..6c2ce8d 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -26,6 +26,7 @@ import TicketDetail from "../pages/ticket/Detail" import AnnouncementtList from "../pages/annoncement/List" import AnnouncementDetail from "../pages/annoncement/Detail" import MyCompany from "../pages/company/MyCompany" +import Setting from "../pages/setting/Setting" const MainRouter = () => { const { slug } = useParams() const getSlugId = useGetSlugId() @@ -79,6 +80,7 @@ const MainRouter = () => { } /> } /> } /> + } />
diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index 5eb72d4..a61a1c3 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -1,7 +1,7 @@ import { FC } from 'react' import LogoImage from '../assets/images/logo.svg' import { useTranslation } from 'react-i18next' -import { DocumentText, Home2, Logout, Messages3, NotificationStatus, Receipt21 } from 'iconsax-react' +import { DocumentText, Home2, Logout, Messages3, NotificationStatus, Receipt21, Setting2 } from 'iconsax-react' import SideBarItem from './SideBarItem' import { useLocation } from 'react-router-dom' import { Pages } from '../config/Pages' @@ -84,6 +84,14 @@ const SideBar: FC = () => { />
+
+ } + title={t('sidebar.setting')} + isActive={isActive('setting')} + link={Pages.setting} + /> +
}