complete setting page
This commit is contained in:
parent
887b3a5e75
commit
25161d4afa
24
src/Components/Switch/Switch.tsx
Normal file
24
src/Components/Switch/Switch.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import { Switch } from 'antd';
|
||||
export interface SwitchProps {
|
||||
onChange?: (checked: any, event: any) => any;
|
||||
checked?: boolean;
|
||||
}
|
||||
const onSwitchChange = (checked: boolean) => {
|
||||
console.log(`switch to ${checked}`);
|
||||
};
|
||||
|
||||
const SwitchButton = ({onChange,checked}:SwitchProps) => {
|
||||
return(
|
||||
<Switch
|
||||
className='switch_button'
|
||||
defaultChecked
|
||||
onChange={(checked: any, event: any) =>
|
||||
onChange ? onChange(checked, event) : onSwitchChange(checked)
|
||||
}
|
||||
// checked={checked}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default SwitchButton;
|
||||
18
src/Components/Ui/Buttons/EditSettingButton.tsx
Normal file
18
src/Components/Ui/Buttons/EditSettingButton.tsx
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
import { Button } from 'antd'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { CiEdit } from "react-icons/ci";
|
||||
|
||||
const EditSettingButton = ({buttonName,onClick}:{buttonName?:string,onClick?:() => void}) => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Button className=' setting_edit_button' onClick={onClick}>
|
||||
<CiEdit/>
|
||||
{t(`header.edit`) ?? (`header.${buttonName}`)}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default EditSettingButton
|
||||
13
src/Components/Ui/Buttons/SecuritySettingButton.tsx
Normal file
13
src/Components/Ui/Buttons/SecuritySettingButton.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { Button } from 'antd'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const SecuritySettingButton = ({name,danger = false}:{name:string,danger?:boolean}) => {
|
||||
const {t} = useTranslation();
|
||||
return (
|
||||
<div>
|
||||
<Button className={`security_setting_button ${danger ? "security_setting_button_danger" :""}`}>{t(name)}</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SecuritySettingButton
|
||||
|
|
@ -28,7 +28,6 @@ const SelectField = ({
|
|||
formik.setFieldValue(name, value);
|
||||
};
|
||||
const options = translateOptions(option, t);
|
||||
console.log(options);
|
||||
|
||||
return (
|
||||
<div className="ValidationField w-100">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
export const translateOptions = (options: any, t: any) => {
|
||||
console.log(options);
|
||||
|
||||
return options?.map((opt: any) => ({
|
||||
...opt,
|
||||
|
|
|
|||
|
|
@ -82,10 +82,6 @@ const LayoutModel = ({
|
|||
}
|
||||
}, [isOpen]);
|
||||
|
||||
console.log(formik.initialValues);
|
||||
console.log(formik?.values);
|
||||
|
||||
|
||||
return <Form className="w-100">
|
||||
|
||||
<header>
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ const TableHeader = () => {
|
|||
|
||||
const handleOpenModel = () =>{
|
||||
handel_open_model(ModalEnum?.RE_SELLER_COLLECTION_ADD);
|
||||
|
||||
}
|
||||
|
||||
const deleteMutation = useDeleteReseller();
|
||||
return (
|
||||
<div className="TableWithHeader single_student">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { FaImage, FaStore } from "react-icons/fa";
|
||||
import {FaStore } from "react-icons/fa";
|
||||
import ImageBoxField from "./ImageBoxField/ImageBoxField";
|
||||
|
||||
const AttachmentForm = () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next";
|
|||
import { FaStore } from "react-icons/fa";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { statusType } from "../../../../../config/statusType";
|
||||
import { Col } from "antd";
|
||||
|
||||
const PersonalDetailsForm = () => {
|
||||
const [t] = useTranslation();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { useTranslation } from "react-i18next";
|
|||
import { FaStore } from "react-icons/fa";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { nationalities } from "../../../../../types/App";
|
||||
import { CiEdit } from "react-icons/ci";
|
||||
|
||||
const TitleDetailsForm = () => {
|
||||
const [t] = useTranslation();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import React from 'react'
|
||||
import TabHeader from './TabHeader'
|
||||
import NotificationCard from './Notification/NotificationCard'
|
||||
import { NotificationData } from '../../../../faker/item'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import React from 'react'
|
||||
import TabHeader from './TabHeader'
|
||||
import SecurityCard from './SecuritySetting/SecurityCard'
|
||||
import { Button } from 'antd'
|
||||
import { SecurityData } from './SecuritySetting/SecurityData'
|
||||
import { SettingType } from '../../../../types/Setting'
|
||||
|
||||
|
|
@ -20,7 +18,6 @@ const SecuritySetting = () => {
|
|||
description={e?.description}
|
||||
children={e?.children}/>
|
||||
))}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
import EditSettingButton from '../../../../../Components/Ui/Buttons/EditSettingButton'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FaCheck } from 'react-icons/fa6';
|
||||
import useModalHandler from '../../../../../utils/useModalHandler';
|
||||
import { ModalEnum } from '../../../../../enums/Model';
|
||||
import { canEditEmail } from '../../../../../utils/hasAbilityFn';
|
||||
import EditEmailModel from './Model/EditEmailModel';
|
||||
|
||||
const EmailAddress = () => {
|
||||
const {t} = useTranslation();
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
const handleOpenModel = () =>{
|
||||
handel_open_model(ModalEnum?.Email_EDIT);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='setting_email_address'>
|
||||
{canEditEmail && <EditSettingButton onClick={handleOpenModel}/>}
|
||||
<EditEmailModel />
|
||||
<span>{t("input.verify")} <FaCheck/></span>
|
||||
<p>{t("admin@example.com")}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default EmailAddress
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
import { getInitialValuesEmail, getValidationSchemaEmail } from "./formUtil";
|
||||
import { ModalEnum } from "../../../../../../enums/Model";
|
||||
import LayoutModel from "../../../../../../Layout/Dashboard/LayoutModel";
|
||||
import {EmailForm} from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
||||
import { useUpdateReseller } from "../../../../../../api/reseller";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdateReseller();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.Email_EDIT}
|
||||
modelTitle="email_address"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValuesEmail(objectToEdit)}
|
||||
getValidationSchema={getValidationSchemaEmail}
|
||||
isAddModal={false}
|
||||
>
|
||||
<EmailForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditModel;
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import React from "react";
|
||||
import { getInitialValuesPhone, getValidationSchemaPhone } from "./formUtil";
|
||||
import { ModalEnum } from "../../../../../../enums/Model";
|
||||
import LayoutModel from "../../../../../../Layout/Dashboard/LayoutModel";
|
||||
import {PhoneForm} from "./ModelForm";
|
||||
import { QueryStatusEnum } from "../../../../../../enums/QueryStatus";
|
||||
import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
|
||||
import { useUpdateReseller } from "../../../../../../api/reseller";
|
||||
|
||||
const EditModel: React.FC = () => {
|
||||
const { mutate, status } = useUpdateReseller();
|
||||
const { objectToEdit } = useObjectToEdit((state) => state);
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
mutate({
|
||||
...values,
|
||||
});
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<LayoutModel
|
||||
status={status as QueryStatusEnum}
|
||||
ModelEnum={ModalEnum.PHONE_EDIT}
|
||||
modelTitle="phone_number"
|
||||
handleSubmit={handleSubmit}
|
||||
getInitialValues={getInitialValuesPhone(objectToEdit)}
|
||||
getValidationSchema={getValidationSchemaPhone}
|
||||
isAddModal={false}
|
||||
>
|
||||
<PhoneForm />
|
||||
</LayoutModel>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditModel;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { Col, Row } from "reactstrap";
|
||||
import ValidationField from "../../../../../../Components/ValidationField/ValidationField";
|
||||
|
||||
export const PhoneForm = () => {
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField placeholder="phone_number" label="phone_number" name="phone_number" />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
PhoneForm;
|
||||
|
||||
|
||||
export const EmailForm = () => {
|
||||
return (
|
||||
<Row className="w-100">
|
||||
<Col>
|
||||
<ValidationField placeholder="email_address" label="email_address" name="email_address" />
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
EmailForm;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import * as Yup from "yup";
|
||||
export const getInitialValuesPhone = (objectToEdit: any): any => {
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
phone_number: objectToEdit?.phone_number ?? null,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchemaPhone = () => {
|
||||
return Yup.object().shape({
|
||||
phone_number: Yup.string().required("validation.required"),
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
export const getInitialValuesEmail = (objectToEdit: any): any => {
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
email_address: objectToEdit?.email_address ?? null,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchemaEmail = () => {
|
||||
return Yup.object().shape({
|
||||
email_address: Yup.string().required("validation.required"),
|
||||
|
||||
});
|
||||
};
|
||||
|
|
@ -1,13 +1,10 @@
|
|||
import { useTranslation } from "react-i18next"
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { ReactElement } from "react";
|
||||
import { SettingType } from "../../../../../types/Setting";
|
||||
|
||||
const SecurityCard = ({
|
||||
name,
|
||||
description,
|
||||
children
|
||||
}:SettingType) => {
|
||||
children}:SettingType) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +1,52 @@
|
|||
import { Button } from "antd";
|
||||
import { SettingType } from "../../../../../types/Setting";
|
||||
import SwitchButton from "../../../../../Components/Switch/Switch"
|
||||
import SecuritySettingButton from "../../../../../Components/Ui/Buttons/SecuritySettingButton";
|
||||
import VerifyPhone from "./VerifyPhone";
|
||||
import EmailAddress from "./EmailAddress";
|
||||
|
||||
export const SecurityData:SettingType[] = [
|
||||
{
|
||||
name:"password",
|
||||
description:"Set a unique password to protect the account",
|
||||
children:<Button className='security_setting_button'>تغيير كلمة المرور</Button>,
|
||||
children:<SecuritySettingButton name="تغيير كلمة المرور"/>,
|
||||
},
|
||||
{
|
||||
name:"two_factors",
|
||||
description:"Receive codes via SMS or email every time you log in",
|
||||
// children:<Button className='button'> change</Button>,
|
||||
children:<SwitchButton />,
|
||||
},
|
||||
{
|
||||
name:"verify_phone_number",
|
||||
description:"The phone number associated with the account",
|
||||
// children:<Button className='button'> change</Button>,
|
||||
children:<VerifyPhone/>,
|
||||
},
|
||||
{
|
||||
name:"email_address",
|
||||
description:"The email address associated with the account",
|
||||
// children:<Button className='button'> change</Button>,
|
||||
children:<EmailAddress/>,
|
||||
},
|
||||
{
|
||||
name:"device_management",
|
||||
description:"Devices associated with the account",
|
||||
children:<Button className='security_setting_button'>إدارة</Button>,
|
||||
children:<SecuritySettingButton name="إدارة"/>,
|
||||
},
|
||||
{
|
||||
name:"account_activity",
|
||||
description:"account_activities",
|
||||
children:<Button className='security_setting_button'>عرض</Button>,
|
||||
children:<SecuritySettingButton name="عرض"/>,
|
||||
|
||||
},
|
||||
{
|
||||
name:"deactivate_the_account",
|
||||
description:"This will close your account. Your account will be interactive when you log in again",
|
||||
children:<Button className='security_setting_button'>الغاء تنشيط </Button>,
|
||||
children:<SecuritySettingButton name="الغاء تنشيط"/>,
|
||||
|
||||
},
|
||||
{
|
||||
name:"delete_account",
|
||||
description:"Your account will be permanently deleted",
|
||||
children:<Button className='security_setting_button security_setting_button_danger'>حذف</Button>,
|
||||
children:<SecuritySettingButton name="حذف" danger={true}/>,
|
||||
|
||||
},
|
||||
|
||||
]
|
||||
|
|
|
|||
26
src/Pages/Admin/Setting/Form/SecuritySetting/VerifyPhone.tsx
Normal file
26
src/Pages/Admin/Setting/Form/SecuritySetting/VerifyPhone.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import EditSettingButton from '../../../../../Components/Ui/Buttons/EditSettingButton'
|
||||
import { t } from 'i18next'
|
||||
import { FaCheck } from 'react-icons/fa6'
|
||||
import useModalHandler from '../../../../../utils/useModalHandler';
|
||||
import { ModalEnum } from '../../../../../enums/Model';
|
||||
import { canEditPhone } from '../../../../../utils/hasAbilityFn';
|
||||
import EditPhoneModel from './Model/EditPhoneModel';
|
||||
|
||||
const VerifyPhone = () => {
|
||||
const { handel_open_model } = useModalHandler();
|
||||
|
||||
const handleOpenModel = () => {
|
||||
handel_open_model(ModalEnum?.PHONE_EDIT);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='setting_verify_phone'>
|
||||
{canEditPhone && <EditSettingButton onClick={handleOpenModel} />}
|
||||
<EditPhoneModel/>
|
||||
<span>{t("input.verify")} <FaCheck/></span>
|
||||
<p>{t("0965289543")}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default VerifyPhone
|
||||
|
|
@ -1,13 +1,11 @@
|
|||
import React, { useState } from 'react';
|
||||
import React, { lazy, useState } from 'react';
|
||||
import type { TabsProps } from 'antd';
|
||||
import { Tabs } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CgProfile } from "react-icons/cg";
|
||||
import { useWindowResize } from '../../../../Hooks/useWindowResize';
|
||||
import Card from '../../../ReSeller/Notifications/Card';
|
||||
import FileSetting from './FileSetting';
|
||||
import SecuritySetting from './SecuritySetting';
|
||||
import Notification from './Notification';
|
||||
const FileSetting = lazy(() => import("./FileSetting"));
|
||||
const SecuritySetting = lazy(() => import("./SecuritySetting"));
|
||||
const Notification = lazy(() => import("./Notification"));
|
||||
|
||||
type TabPosition = 'left' | 'right' | 'top' | 'bottom';
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
import { FaPlus } from "react-icons/fa";
|
||||
import useModalHandler from "../../../utils/useModalHandler";
|
||||
import { ModalEnum } from "../../../enums/Model";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { lazy, Suspense } from "react";
|
||||
import { Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
||||
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
||||
|
|
|
|||
|
|
@ -339,14 +339,14 @@ export const CrudRoute: TCrudRoute[] = [
|
|||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
},
|
||||
{
|
||||
header: "page_header.setting",
|
||||
element: <Setting />,
|
||||
path: `/${ABILITIES_ENUM?.SETTING}`,
|
||||
abilities: ABILITIES_ENUM?.SETTING,
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
},
|
||||
// {
|
||||
// header: "page_header.setting",
|
||||
// element: <Setting />,
|
||||
// path: `/${ABILITIES_ENUM?.SETTING}`,
|
||||
// abilities: ABILITIES_ENUM?.SETTING,
|
||||
// abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
// prevPath: 0,
|
||||
// },
|
||||
//// RE_SELLER
|
||||
{
|
||||
header: "page_header.notifications",
|
||||
|
|
|
|||
|
|
@ -151,3 +151,47 @@
|
|||
background: var(--warning) !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.setting_edit_button{
|
||||
@include Flex;
|
||||
background: #F2F4F8;
|
||||
border: none;
|
||||
color: #515B73;
|
||||
svg{
|
||||
font-size: 20px;
|
||||
}
|
||||
&:hover{
|
||||
background: #F2F4F8 !important;
|
||||
border: none !important;
|
||||
color: #515B73 !important;
|
||||
scale: 1 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.setting_email_address,
|
||||
.setting_verify_phone{
|
||||
display: flex; align-items: center;flex-direction: row-reverse !important;
|
||||
> span{
|
||||
@include Flex;
|
||||
gap: 5px;
|
||||
font-size: 10px;
|
||||
padding: 8px ;
|
||||
direction: ltr;
|
||||
color: #1ABE17;
|
||||
background: #E7F9E7;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
svg{
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
p{
|
||||
color: var(--value);
|
||||
font-size: 14px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.switch_button{
|
||||
background: var(--primary) !important;
|
||||
}
|
||||
|
|
@ -215,4 +215,12 @@ export enum ModalEnum {
|
|||
/// sales
|
||||
|
||||
Sales_ADD = "Sales.add",
|
||||
|
||||
/// phone
|
||||
|
||||
PHONE_EDIT = "Phone.edit",
|
||||
|
||||
/// email
|
||||
|
||||
Email_EDIT = "Email.edit",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,8 +56,9 @@ export enum ABILITIES_ENUM {
|
|||
Profile_RE_SELLER = "profile_re_seller" ,
|
||||
Sales = "sales",
|
||||
Collections = "collections",
|
||||
SETTING = "setting"
|
||||
|
||||
SETTING = "setting",
|
||||
Email = "email",
|
||||
Phone = "phone"
|
||||
////
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -380,7 +380,9 @@
|
|||
"managers":"مدراء",
|
||||
"manager":"مدير",
|
||||
"sale":"عملية بيع",
|
||||
"collections": "التحصيلات"
|
||||
"collections": "التحصيلات",
|
||||
"phone_number":"رقم الهاتف",
|
||||
"email_address":"عنوان البريد الإلكتروني"
|
||||
},
|
||||
"education_class_actions": {
|
||||
"Student_Records": "سجلات الطلاب",
|
||||
|
|
@ -508,7 +510,8 @@
|
|||
"empty":"",
|
||||
"role":"الدور",
|
||||
"submit_password":"تأكيد كلمة المرور",
|
||||
"join_date":"تاريخ الانضمام"
|
||||
"join_date":"تاريخ الانضمام",
|
||||
"verify":"التحقق"
|
||||
},
|
||||
"select": {
|
||||
"enums": {
|
||||
|
|
|
|||
|
|
@ -736,3 +736,18 @@ export const canDeleteSales = hasAbility(
|
|||
ABILITIES_ENUM.Sales,
|
||||
ABILITIES_VALUES_ENUM.DELETE,
|
||||
);
|
||||
|
||||
|
||||
/// Phone
|
||||
|
||||
export const canEditPhone = hasAbility(
|
||||
ABILITIES_ENUM.Phone,
|
||||
ABILITIES_VALUES_ENUM.UPDATE,
|
||||
);
|
||||
|
||||
/// Email
|
||||
|
||||
export const canEditEmail = hasAbility(
|
||||
ABILITIES_ENUM.Email,
|
||||
ABILITIES_VALUES_ENUM.UPDATE,
|
||||
);
|
||||
Loading…
Reference in New Issue
Block a user