Compare commits
4 Commits
fa8f705a75
...
9644b4e6ba
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9644b4e6ba | ||
|
|
25161d4afa | ||
|
|
887b3a5e75 | ||
|
|
e0e2839cf3 |
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,
|
||||
|
|
|
|||
20
src/Hooks/useWindowResize.tsx
Normal file
20
src/Hooks/useWindowResize.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
|
||||
export const useWindowResize = () => {
|
||||
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('resize', handleResize);
|
||||
// Cleanup function to remove the event listener
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
};
|
||||
}, [windowWidth]);
|
||||
|
||||
const handleResize = () => {
|
||||
setWindowWidth(window.innerWidth);
|
||||
};
|
||||
|
||||
return {windowWidth , handleResize};
|
||||
}
|
||||
|
||||
|
|
@ -82,10 +82,6 @@ const LayoutModel = ({
|
|||
}
|
||||
}, [isOpen]);
|
||||
|
||||
console.log(formik.initialValues);
|
||||
console.log(formik?.values);
|
||||
|
||||
|
||||
return <Form className="w-100">
|
||||
|
||||
<header>
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ const SideBar = ({
|
|||
</div>
|
||||
<div className="side_bar_setting">
|
||||
<p>{t("sidebar.setting")}</p>
|
||||
<div>
|
||||
<div onClick={() => {navigate("/setting")}}>
|
||||
<CiSettings />
|
||||
<span>{t("sidebar.setting")}</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
42
src/Pages/Admin/Setting/Form/FileSetting.tsx
Normal file
42
src/Pages/Admin/Setting/Form/FileSetting.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import TabHeader from './TabHeader'
|
||||
import { Form, Formik } from 'formik'
|
||||
import { getInitialValues, getValidationSchema } from './FileSetting/formUtils'
|
||||
import PersonalDetailsForm from './FileSetting/PersonalDetailsForm'
|
||||
import TitleDetailsForm from './FileSetting/TitleDetailsForm'
|
||||
import AttachmentForm from './FileSetting/AttachmentForm'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const FileSetting = () => {
|
||||
const {t} = useTranslation()
|
||||
const handelSubmit = (values: any) => {
|
||||
console.log(values, "values");
|
||||
};
|
||||
return (
|
||||
<div className='file_setting'>
|
||||
<TabHeader
|
||||
name='file_setting'
|
||||
description='upload_your_photo_and_personal_data_here'
|
||||
>
|
||||
<div className="file_setting_buttons">
|
||||
<button type="button">{t("practical.cancel")}</button>
|
||||
<button type="submit">
|
||||
{t("practical.save")}
|
||||
</button>
|
||||
</div>
|
||||
</TabHeader>
|
||||
<Formik
|
||||
initialValues={getInitialValues({})}
|
||||
validationSchema={getValidationSchema}
|
||||
onSubmit={handelSubmit}
|
||||
>
|
||||
<Form className="Form_details_container">
|
||||
<PersonalDetailsForm />
|
||||
<TitleDetailsForm />
|
||||
<AttachmentForm />
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FileSetting
|
||||
22
src/Pages/Admin/Setting/Form/FileSetting/AttachmentForm.tsx
Normal file
22
src/Pages/Admin/Setting/Form/FileSetting/AttachmentForm.tsx
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import {FaStore } from "react-icons/fa";
|
||||
import ImageBoxField from "./ImageBoxField/ImageBoxField";
|
||||
|
||||
const AttachmentForm = () => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="AttachmentForm">
|
||||
<header className="header_form">
|
||||
<FaStore />
|
||||
<h4>{t("header.attachments")}</h4>
|
||||
</header>
|
||||
<main className="main_form_body">
|
||||
<ImageBoxField name="personal_image" />
|
||||
<ImageBoxField name="id_image" />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttachmentForm;
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
.ImageBoxField {
|
||||
.ImageBox {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: max(1.5px, 0.1vw) dashed #a9c3f1;
|
||||
margin-block: 10px;
|
||||
border-radius: 5px;
|
||||
z-index: 9999999 !important;
|
||||
.ImageBoxIcon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.imagePreview {
|
||||
max-width: 99%;
|
||||
height: auto;
|
||||
max-height: 99%;
|
||||
object-fit: contain;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
.ImageHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.ImageCancelIcon {
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
}
|
||||
.ImageBoxIcon {
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
import { useFormikContext } from "formik";
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import "./ImageBoxField.scss";
|
||||
import ImageIcon from "./ImageIcon";
|
||||
import ImageCancelIcon from "./ImageCancelIcon";
|
||||
import { generateImagePreview } from "./generateImagePreview";
|
||||
import { getNestedValue } from "../../../../../../utils/getNestedValue";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
// Helper function to generate image preview from a File
|
||||
|
||||
const ImageBoxField = ({ name }: any) => {
|
||||
const formik = useFormikContext<any>();
|
||||
const value = getNestedValue(formik.values, name);
|
||||
const [imagePreview, setImagePreview] = useState<string | null>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (value instanceof File) {
|
||||
generateImagePreview(value, setImagePreview);
|
||||
} else if (typeof value === "string") {
|
||||
setImagePreview(value);
|
||||
} else {
|
||||
setImagePreview(null);
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
const handleFileChange = (event: any) => {
|
||||
const file = event.target.files[0];
|
||||
if (file) {
|
||||
generateImagePreview(file, setImagePreview);
|
||||
formik.setFieldValue(name, file);
|
||||
}
|
||||
};
|
||||
|
||||
const handleButtonClick = () => {
|
||||
const fileInput = fileInputRef.current;
|
||||
if (fileInput) {
|
||||
fileInput.click();
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setImagePreview("");
|
||||
formik.setFieldValue(name, "");
|
||||
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = "";
|
||||
}
|
||||
};
|
||||
const [t] = useTranslation();
|
||||
return (
|
||||
<div className="ImageBoxField">
|
||||
<header>{t(`input.${name}`)}</header>
|
||||
<div className="ImageHeader">
|
||||
{imagePreview ? (
|
||||
<>
|
||||
<ImageCancelIcon
|
||||
onClick={handleCancel}
|
||||
className="ImageCancelIcon"
|
||||
/>
|
||||
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||
</>
|
||||
) : (
|
||||
<div className="VisibleHidden">hidden</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="ImageBox">
|
||||
{imagePreview ? (
|
||||
<img src={imagePreview} alt="Preview" className="imagePreview" />
|
||||
) : (
|
||||
<ImageIcon onClick={handleButtonClick} className="ImageBoxIcon" />
|
||||
)}
|
||||
</div>
|
||||
<input
|
||||
id={`file-input-${name}`}
|
||||
type="file"
|
||||
accept="image/png, image/jpeg, image/webp"
|
||||
style={{ display: "none" }}
|
||||
onChange={handleFileChange}
|
||||
ref={fileInputRef}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageBoxField;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
|
||||
interface ImageCancelIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
const ImageCancelIcon: React.FC<ImageCancelIconProps> = (props) => {
|
||||
return (
|
||||
<div {...props}>
|
||||
<svg viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M7 5.44469L12.4447 0L14 1.55531L8.55531 7L14 12.4447L12.4436 14L6.9989 8.55531L1.55531 14L0 12.4436L5.44469 6.9989L0 1.55421L1.55531 0.00109986L7 5.44469Z"
|
||||
fill="#515B73"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageCancelIcon;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import React from "react";
|
||||
|
||||
interface ImageIconProps extends React.HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
const ImageIcon: React.FC<ImageIconProps> = (props) => {
|
||||
return (
|
||||
<div {...props}>
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11.25 5.625C11.25 7.11684 10.6574 8.54758 9.60248 9.60248C8.54758 10.6574 7.11684 11.25 5.625 11.25C4.13316 11.25 2.70242 10.6574 1.64752 9.60248C0.592632 8.54758 0 7.11684 0 5.625C0 4.13316 0.592632 2.70242 1.64752 1.64752C2.70242 0.592632 4.13316 0 5.625 0C7.11684 0 8.54758 0.592632 9.60248 1.64752C10.6574 2.70242 11.25 4.13316 11.25 5.625ZM6.25 3.125C6.25 2.95924 6.18415 2.80027 6.06694 2.68306C5.94973 2.56585 5.79076 2.5 5.625 2.5C5.45924 2.5 5.30027 2.56585 5.18306 2.68306C5.06585 2.80027 5 2.95924 5 3.125V5H3.125C2.95924 5 2.80027 5.06585 2.68306 5.18306C2.56585 5.30027 2.5 5.45924 2.5 5.625C2.5 5.79076 2.56585 5.94973 2.68306 6.06694C2.80027 6.18415 2.95924 6.25 3.125 6.25H5V8.125C5 8.29076 5.06585 8.44973 5.18306 8.56694C5.30027 8.68415 5.45924 8.75 5.625 8.75C5.79076 8.75 5.94973 8.68415 6.06694 8.56694C6.18415 8.44973 6.25 8.29076 6.25 8.125V6.25H8.125C8.29076 6.25 8.44973 6.18415 8.56694 6.06694C8.68415 5.94973 8.75 5.79076 8.75 5.625C8.75 5.45924 8.68415 5.30027 8.56694 5.18306C8.44973 5.06585 8.29076 5 8.125 5H6.25V3.125ZM16.25 3.75H12.2413C12.1187 3.3183 11.9542 2.89964 11.75 2.5H16.25C17.2446 2.5 18.1984 2.89509 18.9017 3.59835C19.6049 4.30161 20 5.25544 20 6.25V16.25C20 17.2446 19.6049 18.1984 18.9017 18.9017C18.1984 19.6049 17.2446 20 16.25 20H6.25C5.25544 20 4.30161 19.6049 3.59835 18.9017C2.89509 18.1984 2.5 17.2446 2.5 16.25V11.75C2.89667 11.9533 3.31333 12.1171 3.75 12.2413V16.25C3.75 16.7162 3.8775 17.1525 4.1 17.525L9.93625 11.79C10.2869 11.4457 10.7586 11.2528 11.25 11.2528C11.7414 11.2528 12.2131 11.4457 12.5637 11.79L18.4012 17.525C18.6298 17.139 18.7502 16.6986 18.75 16.25V6.25C18.75 5.58696 18.4866 4.95107 18.0178 4.48223C17.5489 4.01339 16.913 3.75 16.25 3.75ZM16.25 8.125C16.25 8.37123 16.2015 8.61505 16.1073 8.84253C16.013 9.07002 15.8749 9.27672 15.7008 9.45083C15.5267 9.62494 15.32 9.76305 15.0925 9.85727C14.865 9.9515 14.6212 10 14.375 10C14.1288 10 13.885 9.9515 13.6575 9.85727C13.43 9.76305 13.2233 9.62494 13.0492 9.45083C12.8751 9.27672 12.737 9.07002 12.6427 8.84253C12.5485 8.61505 12.5 8.37123 12.5 8.125C12.5 7.62772 12.6975 7.15081 13.0492 6.79917C13.4008 6.44754 13.8777 6.25 14.375 6.25C14.8723 6.25 15.3492 6.44754 15.7008 6.79917C16.0525 7.15081 16.25 7.62772 16.25 8.125ZM15 8.125C15 7.95924 14.9342 7.80027 14.8169 7.68306C14.6997 7.56585 14.5408 7.5 14.375 7.5C14.2092 7.5 14.0503 7.56585 13.9331 7.68306C13.8158 7.80027 13.75 7.95924 13.75 8.125C13.75 8.29076 13.8158 8.44973 13.9331 8.56694C14.0503 8.68415 14.2092 8.75 14.375 8.75C14.5408 8.75 14.6997 8.68415 14.8169 8.56694C14.9342 8.44973 15 8.29076 15 8.125ZM4.985 18.4075C5.36871 18.6321 5.80538 18.7504 6.25 18.75H16.25C16.7125 18.75 17.1437 18.625 17.515 18.4075L11.6875 12.6825C11.5707 12.568 11.4136 12.5038 11.25 12.5038C11.0864 12.5038 10.9293 12.568 10.8125 12.6825L4.985 18.4075Z"
|
||||
fill="#515B73"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ImageIcon;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
export const generateImagePreview = (
|
||||
file: File,
|
||||
setImagePreview: (result: string) => void,
|
||||
) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
setImagePreview(reader.result as string);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { FaStore } from "react-icons/fa";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { statusType } from "../../../../../config/statusType";
|
||||
|
||||
const PersonalDetailsForm = () => {
|
||||
const [t] = useTranslation();
|
||||
return (
|
||||
<div className="PersonalDetailsForm">
|
||||
<header className="header_form">
|
||||
<FaStore />
|
||||
<h4>{t("header.personal_information")}</h4>
|
||||
</header>
|
||||
<main className="main_form_body">
|
||||
<ValidationField
|
||||
name={"first_name"}
|
||||
placeholder={"_"}
|
||||
label={"first_name"}
|
||||
/>
|
||||
<ValidationField
|
||||
name={"last_name"}
|
||||
placeholder={"_"}
|
||||
type="Date"
|
||||
label={"last_name"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"email_address"}
|
||||
placeholder={"_"}
|
||||
label={"email_address"}
|
||||
type="Select"
|
||||
option={statusType}
|
||||
/>
|
||||
<ValidationField
|
||||
name={"username"}
|
||||
placeholder={"_"}
|
||||
label={"username"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"full_name"}
|
||||
placeholder={"_"}
|
||||
label={"Phone Number"}
|
||||
/>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default PersonalDetailsForm;
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { FaStore } from "react-icons/fa";
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
import { nationalities } from "../../../../../types/App";
|
||||
|
||||
const TitleDetailsForm = () => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="TitleDetailsForm">
|
||||
<header className="header_form">
|
||||
<FaStore />
|
||||
<h4>{t("header.address")}</h4>
|
||||
</header>
|
||||
<main className="main_form_body">
|
||||
<ValidationField
|
||||
name={"city_id"}
|
||||
placeholder={"_"}
|
||||
label={"city"}
|
||||
type="Select"
|
||||
option={nationalities}
|
||||
/>
|
||||
<ValidationField name={"address"} placeholder={"_"} label={"address"} />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TitleDetailsForm;
|
||||
13
src/Pages/Admin/Setting/Form/FileSetting/formUtils.ts
Normal file
13
src/Pages/Admin/Setting/Form/FileSetting/formUtils.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import * as Yup from "yup";
|
||||
|
||||
export const getInitialValues = (objectToEdit: Partial<any>) => {
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
name: objectToEdit?.name ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({});
|
||||
};
|
||||
35
src/Pages/Admin/Setting/Form/Notification.tsx
Normal file
35
src/Pages/Admin/Setting/Form/Notification.tsx
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import TabHeader from './TabHeader'
|
||||
import NotificationCard from './Notification/NotificationCard'
|
||||
import { NotificationData } from '../../../../faker/item'
|
||||
import { Form, Formik } from 'formik'
|
||||
import { getInitialValues, getValidationSchema } from './Notification/formUtils'
|
||||
|
||||
const Notification = () => {
|
||||
const handelSubmit = (values: any) => {
|
||||
console.log(values, "values");
|
||||
};
|
||||
return (
|
||||
<div className='notification'>
|
||||
<TabHeader
|
||||
name='notification'
|
||||
description='get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time'
|
||||
>
|
||||
</TabHeader>
|
||||
<Formik
|
||||
initialValues={getInitialValues({})}
|
||||
validationSchema={getValidationSchema}
|
||||
onSubmit={handelSubmit}
|
||||
>
|
||||
<Form className="Form_details_container">
|
||||
<div className='setting_notification_body'>
|
||||
{NotificationData?.map((not: any) => (
|
||||
<NotificationCard name={not.label} description={not?.value} />
|
||||
))}
|
||||
</div>
|
||||
</Form>
|
||||
</Formik>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Notification
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import { useTranslation } from "react-i18next"
|
||||
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
|
||||
|
||||
const NotificationCard = ({
|
||||
name,
|
||||
description,
|
||||
}:{
|
||||
name:string,
|
||||
description:string,
|
||||
}) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='notification_card'>
|
||||
<div>
|
||||
<h5>{t(`${name}`)}</h5>
|
||||
<p>{t(`${description}`)}</p>
|
||||
</div>
|
||||
<div>
|
||||
<ValidationField type="Checkbox" name="name" label="empty"/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default NotificationCard
|
||||
13
src/Pages/Admin/Setting/Form/Notification/formUtils.ts
Normal file
13
src/Pages/Admin/Setting/Form/Notification/formUtils.ts
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import * as Yup from "yup";
|
||||
|
||||
export const getInitialValues = (objectToEdit: Partial<any>) => {
|
||||
return {
|
||||
id: objectToEdit?.id ?? null,
|
||||
name: objectToEdit?.name ?? null,
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = () => {
|
||||
// validate input
|
||||
return Yup.object().shape({});
|
||||
};
|
||||
26
src/Pages/Admin/Setting/Form/SecuritySetting.tsx
Normal file
26
src/Pages/Admin/Setting/Form/SecuritySetting.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import TabHeader from './TabHeader'
|
||||
import SecurityCard from './SecuritySetting/SecurityCard'
|
||||
import { SecurityData } from './SecuritySetting/SecurityData'
|
||||
import { SettingType } from '../../../../types/Setting'
|
||||
|
||||
const SecuritySetting = () => {
|
||||
return (
|
||||
<div className='security_setting'>
|
||||
<TabHeader
|
||||
name='security_setting'
|
||||
description='upload_your_photo_and_personal_data_here'
|
||||
>
|
||||
</TabHeader>
|
||||
<div className='security_setting_body'>
|
||||
{SecurityData?.map((e:SettingType)=>(
|
||||
<SecurityCard
|
||||
name={e?.name}
|
||||
description={e?.description}
|
||||
children={e?.children}/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SecuritySetting
|
||||
|
|
@ -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"),
|
||||
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { useTranslation } from "react-i18next"
|
||||
import { SettingType } from "../../../../../types/Setting";
|
||||
|
||||
const SecurityCard = ({
|
||||
name,
|
||||
description,
|
||||
children}:SettingType) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='security_card'>
|
||||
<div>
|
||||
<h5>{t(`practical.${name}`)}</h5>
|
||||
<p>{t(`practical.${description}`)}</p>
|
||||
</div>
|
||||
<div>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SecurityCard
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
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:<SecuritySettingButton name="تغيير كلمة المرور"/>,
|
||||
},
|
||||
{
|
||||
name:"two_factors",
|
||||
description:"Receive codes via SMS or email every time you log in",
|
||||
children:<SwitchButton />,
|
||||
},
|
||||
{
|
||||
name:"verify_phone_number",
|
||||
description:"The phone number associated with the account",
|
||||
children:<VerifyPhone/>,
|
||||
},
|
||||
{
|
||||
name:"email_address",
|
||||
description:"The email address associated with the account",
|
||||
children:<EmailAddress/>,
|
||||
},
|
||||
{
|
||||
name:"device_management",
|
||||
description:"Devices associated with the account",
|
||||
children:<SecuritySettingButton name="إدارة"/>,
|
||||
},
|
||||
{
|
||||
name:"account_activity",
|
||||
description:"account_activities",
|
||||
children:<SecuritySettingButton name="عرض"/>,
|
||||
|
||||
},
|
||||
{
|
||||
name:"deactivate_the_account",
|
||||
description:"This will close your account. Your account will be interactive when you log in again",
|
||||
children:<SecuritySettingButton name="الغاء تنشيط"/>,
|
||||
|
||||
},
|
||||
{
|
||||
name:"delete_account",
|
||||
description:"Your account will be permanently deleted",
|
||||
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
|
||||
49
src/Pages/Admin/Setting/Form/SettingTabs.tsx
Normal file
49
src/Pages/Admin/Setting/Form/SettingTabs.tsx
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import React, { lazy, useState } from 'react';
|
||||
import type { TabsProps } from 'antd';
|
||||
import { Tabs } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useWindowResize } from '../../../../Hooks/useWindowResize';
|
||||
const FileSetting = lazy(() => import("./FileSetting"));
|
||||
const SecuritySetting = lazy(() => import("./SecuritySetting"));
|
||||
const Notification = lazy(() => import("./Notification"));
|
||||
|
||||
type TabPosition = 'left' | 'right' | 'top' | 'bottom';
|
||||
|
||||
const SettingTabs: React.FC = () => {
|
||||
const {windowWidth} = useWindowResize()
|
||||
const {t} = useTranslation();
|
||||
const [tabPosition, setTabPosition] = useState<TabPosition>(windowWidth < 800 ? 'top' : 'left');
|
||||
const items: TabsProps['items'] = [
|
||||
|
||||
{
|
||||
key: '1',
|
||||
label: t('table.file_setting'),
|
||||
children: <FileSetting />,
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: t('table.security_setting'),
|
||||
children: <SecuritySetting/>,
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: t('table.notification'),
|
||||
children: <Notification/>,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
tabPosition={tabPosition}
|
||||
addIcon
|
||||
items={items}
|
||||
className='setting_tabs'
|
||||
defaultActiveKey='1'
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SettingTabs;
|
||||
29
src/Pages/Admin/Setting/Form/TabHeader.tsx
Normal file
29
src/Pages/Admin/Setting/Form/TabHeader.tsx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import { ReactElement } from 'react';
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const TabHeader = ({
|
||||
name,
|
||||
description,
|
||||
children
|
||||
}:{
|
||||
name:string,
|
||||
description:string,
|
||||
children?:ReactElement
|
||||
}) => {
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
return (
|
||||
<div className='setting_tab_header'>
|
||||
<div>
|
||||
<h5>{t(`table.${name}`)}</h5>
|
||||
<p>{t(`table.${description}`)}</p>
|
||||
</div>
|
||||
<div>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TabHeader
|
||||
28
src/Pages/Admin/Setting/Page.tsx
Normal file
28
src/Pages/Admin/Setting/Page.tsx
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { useTranslation } from "react-i18next";
|
||||
import { Suspense } from "react";
|
||||
import { Spin } from "antd";
|
||||
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
|
||||
import PageHeader from "../../../Layout/Dashboard/PageHeader";
|
||||
import SettingTabs from "./Form/SettingTabs";
|
||||
|
||||
const TableHeader = () => {
|
||||
const [t] = useTranslation();
|
||||
|
||||
useSetPageTitle([
|
||||
{name:`${t(`page_header.home`)}`, path:"/"},
|
||||
{name:`${t(`page_header.setting`)}`, path:"setting"}
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="TableWithHeader">
|
||||
<Suspense fallback={<Spin />}>
|
||||
<PageHeader
|
||||
pageTitle="setting"
|
||||
/>
|
||||
<SettingTabs/>
|
||||
</Suspense>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TableHeader;
|
||||
|
|
@ -18,24 +18,43 @@ const PersonalDetailsForm = () => {
|
|||
</header>
|
||||
<main className="main_form_body">
|
||||
<ValidationField
|
||||
name={"first_name"}
|
||||
name={"id_number"}
|
||||
placeholder={"_"}
|
||||
label={"first_name"}
|
||||
label={"ID Number"}
|
||||
/>
|
||||
<ValidationField
|
||||
name={"last_name"}
|
||||
name={"addition_date"}
|
||||
placeholder={"_"}
|
||||
type="Date"
|
||||
label={"last_name"}
|
||||
label={"Addition Date"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"email_address"}
|
||||
name={"status"}
|
||||
placeholder={"_"}
|
||||
label={"email_address"}
|
||||
label={"status"}
|
||||
type="Select"
|
||||
option={statusType}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"full_name"}
|
||||
placeholder={"_"}
|
||||
label={"Full Name"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"phone_number"}
|
||||
placeholder={"_"}
|
||||
label={"phone_number"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"mobile_number"}
|
||||
placeholder={"_"}
|
||||
label={"Mobile Number"}
|
||||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"username"}
|
||||
placeholder={"_"}
|
||||
|
|
@ -43,11 +62,10 @@ const PersonalDetailsForm = () => {
|
|||
/>
|
||||
|
||||
<ValidationField
|
||||
name={"full_name"}
|
||||
name={"seller_percentage"}
|
||||
placeholder={"_"}
|
||||
label={"Phone Number"}
|
||||
label={"Seller Percentage"}
|
||||
/>
|
||||
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -37,10 +37,11 @@ const User = React.lazy(() => import("./Pages/Admin/User/Page"));
|
|||
const QuestionBank = React.lazy(() => import("./Pages/Admin/QuestionBank/Page"));
|
||||
const Notifications = React.lazy(() => import("./Pages/Admin/Notifications/Page"));
|
||||
const Profile = React.lazy(() => import("./Pages/Admin/Profile/Page"));
|
||||
const Setting = React.lazy(() => import("./Pages/Admin/Setting/Page"));
|
||||
|
||||
|
||||
const Roles = React.lazy(() => import("./Pages/Admin/Roles/Page"));
|
||||
const Permissions = React.lazy(() => import("./Pages/Admin/Roles/Permissions/Page"));
|
||||
|
||||
const Roles = React.lazy(() => import("./Pages/Admin/Roles/Page"));
|
||||
const Report = React.lazy(() => import("./Pages/Admin/Report/Page"));
|
||||
const Param = React.lazy(() => import("./Pages/Admin/Param/Page"));
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ export const menuItems: TMenuItem[] = [
|
|||
element: <ProfileReSeller />,
|
||||
icon: <FaSellcast />,
|
||||
text: "sidebar.profile",
|
||||
path: `//${ABILITIES_ENUM?.PROFILE}`,
|
||||
path: `/${ABILITIES_ENUM?.PROFILE}`,
|
||||
abilities: ABILITIES_ENUM?.Profile_RE_SELLER,
|
||||
abilities_value: ABILITIES_VALUES_ENUM.INDEX,
|
||||
prevPath: 0,
|
||||
|
|
@ -338,6 +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,
|
||||
// },
|
||||
//// RE_SELLER
|
||||
{
|
||||
header: "page_header.notifications",
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@
|
|||
@import './InfoCard.scss';
|
||||
@import './notifications.scss';
|
||||
@import './profile.scss';
|
||||
@import './collections.scss'
|
||||
@import './collections.scss';
|
||||
@import './setting.scss';
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@
|
|||
gap: 20px;
|
||||
background: var(--bg);
|
||||
padding: 40px 10px;
|
||||
.ValidationField{
|
||||
label{
|
||||
font-weight: 600;
|
||||
font-size: 16px !important;
|
||||
color: var(--secondary) !important;
|
||||
}
|
||||
}
|
||||
> * {
|
||||
// max-width: 30%;
|
||||
flex-basis: 31%;
|
||||
|
|
@ -21,7 +28,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.resellerButton {
|
||||
.resellerButton,.file_setting_buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
|
|
|
|||
197
src/Styles/Pages/setting.scss
Normal file
197
src/Styles/Pages/setting.scss
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
.setting_tabs {
|
||||
border-top: 1px solid var(--border-color-2);
|
||||
|
||||
.ant-tabs-nav {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.ant-tabs-nav-list {
|
||||
width: 100% !important;
|
||||
border-left: 1px solid var(--border-color-2);
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.ant-tabs-tab {
|
||||
margin-top: 10px;
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
.ant-tabs-tab-active {
|
||||
background: #3D5EE11A !important;
|
||||
border-radius: 8px 0 0 8px;
|
||||
border-right: 1px solid #3D5EE11A;
|
||||
margin-left: 0 !important;
|
||||
}
|
||||
|
||||
.ant-tabs-content-holder {
|
||||
padding: 20px 0 !important;
|
||||
}
|
||||
|
||||
.ant-tabs-content-holder {
|
||||
border: none;
|
||||
margin-right: 20px;
|
||||
padding-top: 20px !important;
|
||||
padding-left: 0 !important;
|
||||
|
||||
}
|
||||
|
||||
.ant-tabs-tabpane-active {
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
.notification {
|
||||
.setting_notification_body {
|
||||
padding: 10px 20px;
|
||||
box-shadow: 0px 0px 32px 0px #080F3414;
|
||||
border: 1.5px solid #E9EDF4;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.setting_tab_header,
|
||||
.notification_card,
|
||||
.security_card {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--border-color-2);
|
||||
padding-block: 10px 20px;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
|
||||
h5 {
|
||||
color: var(--secondary);
|
||||
font-size: 1.4vw;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 1.1vw;
|
||||
color: var(--value);
|
||||
}
|
||||
|
||||
.file_setting_buttons {
|
||||
display: flex !important;
|
||||
flex-direction: row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting_tab_header {
|
||||
width: 100%;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.notification_card{
|
||||
&:nth-last-child(1) {
|
||||
border: none;
|
||||
}
|
||||
h5 {
|
||||
font-size: 1.2vw !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: .9vw !important;
|
||||
}
|
||||
.ant-form-item,
|
||||
.ant-form-item-control-input-content {
|
||||
height: 3vh;
|
||||
gap: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
.ant-checkbox .ant-checkbox-inner {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
border: 2px solid var(--border-color-2);
|
||||
}
|
||||
}
|
||||
.security_card{
|
||||
padding: 20px 20px;
|
||||
box-shadow: 0px 0px 32px 0px #080F3414;
|
||||
border: 1.5px solid #E9EDF4;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
margin-block: 20px ;
|
||||
h5 {
|
||||
font-size: 1.2vw !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: .9vw !important;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.security_setting_button{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
outline: none;
|
||||
border: 2px solid var(--primary);
|
||||
border-radius: 7px;
|
||||
padding: 22px 15px !important;
|
||||
color: var(--primary);
|
||||
gap: 5px;
|
||||
&:hover{
|
||||
border: 2px solid var(--primary) !important;
|
||||
background: var(--primary) !important;
|
||||
color: var(--white) !important;
|
||||
}
|
||||
}
|
||||
.security_setting_button_danger{
|
||||
border-color:var(--warning);
|
||||
color: var(--warning);
|
||||
&:hover{
|
||||
border: 2px solid var(--warning) !important;
|
||||
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",
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,10 @@ export enum ABILITIES_ENUM {
|
|||
NOTIFICATIONS_RE_SELLER = "notification_re_seller" ,
|
||||
Profile_RE_SELLER = "profile_re_seller" ,
|
||||
Sales = "sales",
|
||||
Collections = "collections"
|
||||
|
||||
Collections = "collections",
|
||||
SETTING = "setting",
|
||||
Email = "email",
|
||||
Phone = "phone"
|
||||
////
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,13 @@ export const CollectionData = [
|
|||
{label:"تم تحصيله",value:"2.000.000"},
|
||||
{label:"المتبقي",value:"2.000.000"},
|
||||
]
|
||||
|
||||
|
||||
export const NotificationData = [
|
||||
{label:"إشعارات البريد الإلكتروني",value:"يمكن أن ترسل لك Substance إشعارات عبر البريد الإلكتروني لأي رسائل مباشرة جديدة"},
|
||||
{label:"إشعارات البريد الإلكتروني",value:"يمكن أن ترسل لك Substance إشعارات عبر البريد الإلكتروني لأي رسائل مباشرة جديدة"},
|
||||
{label:"إشعارات البريد الإلكتروني",value:"يمكن أن ترسل لك Substance إشعارات عبر البريد الإلكتروني لأي رسائل مباشرة جديدة"},
|
||||
{label:"إشعارات البريد الإلكتروني",value:"يمكن أن ترسل لك Substance إشعارات عبر البريد الإلكتروني لأي رسائل مباشرة جديدة"},
|
||||
{label:"إشعارات البريد الإلكتروني",value:"يمكن أن ترسل لك Substance إشعارات عبر البريد الإلكتروني لأي رسائل مباشرة جديدة"},
|
||||
|
||||
]
|
||||
|
|
@ -144,6 +144,7 @@
|
|||
"sales":"المبيعات",
|
||||
"hide_hint":"اخفاء الشرح",
|
||||
"show_hint":"عرض الشرح",
|
||||
"setting":"الإعدادات",
|
||||
"past_your_MMl_text":"ضع نص MMl الخاص بك",
|
||||
"add_MML":"إضافة MML",
|
||||
"show_preview":"عرض المعاينة",
|
||||
|
|
@ -289,7 +290,23 @@
|
|||
"sorry_something_went_wrong": "عفوا ، حدث خطأ ما",
|
||||
"error_404_Page_not_found._Sorry,_the_page_you_are_looking_for_does_not_exist": "خطأ 404 لم يتم العثور على الصفحة. عذرا الصفحة التي تبحث عنها غير موجودة ",
|
||||
"return_to_the_dashboard": "العودة إلى لوحة القيادة",
|
||||
"save_changes":"حفظ التغييرات"
|
||||
"save_changes":"حفظ التغييرات",
|
||||
"password":"كلمة المرور",
|
||||
"two_factors":"عاملان",
|
||||
"verify_phone_number":"التحقق من رقم الهاتف",
|
||||
"email_address":"عنوان البريد الإلكتروني",
|
||||
"device_management":"إدارة الأجهزة",
|
||||
"account_activity":"نشاط الحساب",
|
||||
"deactivate_the_account":"إلغاء تنشيط الحساب",
|
||||
"delete_account":"حذف الحساب",
|
||||
"Set a unique password to protect the account":"تعيين كلمة مرور فريدة لحماية الحساب",
|
||||
"Receive codes via SMS or email every time you log in":"تلقي الرموز عبر الرسائل القصيرة أو البريد الإلكتروني في كل مرة تقوم فيها بتسجيل الدخول",
|
||||
"The phone number associated with the account":"رقم الهاتف المرتبط بالحساب",
|
||||
"The email address associated with the account":"عنوان البريد الإلكتروني المرتبط بالحساب",
|
||||
"Devices associated with the account":"الأجهزة المرتبطة بالحساب",
|
||||
"account_activities":"أنشطة الحساب",
|
||||
"This will close your account. Your account will be interactive when you log in again":"سيؤدي هذا إلى إغلاق حسابك. سيكون حسابك تفاعليا عند تسجيل الدخول مرة أخرى",
|
||||
"Your account will be permanently deleted":"سيتم حذف حسابك نهائيا"
|
||||
},
|
||||
"Table": {
|
||||
"header": "",
|
||||
|
|
@ -368,7 +385,9 @@
|
|||
"managers":"مدراء",
|
||||
"manager":"مدير",
|
||||
"sale":"عملية بيع",
|
||||
"collections": "التحصيلات"
|
||||
"collections": "التحصيلات",
|
||||
"phone_number":"رقم الهاتف",
|
||||
"email_address":"عنوان البريد الإلكتروني"
|
||||
},
|
||||
"education_class_actions": {
|
||||
"Student_Records": "سجلات الطلاب",
|
||||
|
|
@ -496,7 +515,8 @@
|
|||
"empty":"",
|
||||
"role":"الدور",
|
||||
"submit_password":"تأكيد كلمة المرور",
|
||||
"join_date":"تاريخ الانضمام"
|
||||
"join_date":"تاريخ الانضمام",
|
||||
"verify":"التحقق"
|
||||
},
|
||||
"select": {
|
||||
"enums": {
|
||||
|
|
@ -876,7 +896,8 @@
|
|||
"add_manager":"إضافة مدير",
|
||||
"collections": "التحصيلات",
|
||||
"sales":"المبيعات",
|
||||
"edit_manager":"تعديل مدير"
|
||||
"edit_manager":"تعديل مدير",
|
||||
"setting":"الإعدادات"
|
||||
},
|
||||
"page_header": {
|
||||
"home": "لوحة القيادة",
|
||||
|
|
@ -922,7 +943,8 @@
|
|||
"permissions":"اذونات",
|
||||
"managers":"مدراء",
|
||||
"collections": "التحصيلات",
|
||||
"sales":"المبيعات"
|
||||
"sales":"المبيعات",
|
||||
"setting":"الإعدادات"
|
||||
},
|
||||
"table": {
|
||||
"student": "قائمة الطلاب",
|
||||
|
|
@ -933,7 +955,13 @@
|
|||
"managers":"مدراء",
|
||||
"managers_list":"قائمة المدراء",
|
||||
"sales":"المبيعات",
|
||||
"collections": "التحصيلات"
|
||||
"collections": "التحصيلات",
|
||||
"setting":"الإعدادات",
|
||||
"file_setting":"إعدادات الملف",
|
||||
"security_setting":"إعدادات الأمان",
|
||||
"notification":"الاشعارات",
|
||||
"upload_your_photo_and_personal_data_here":"قم بتحميل صورتك وبياناتك الشخصية هنا",
|
||||
"get_notified_of_whats_happening_now_you_can_turn_it_off_at_any_time":"احصل على إشعار بما يحدث الآن ، يمكنك إيقاف تشغيله في أي وقت"
|
||||
},
|
||||
"alphabet": {
|
||||
"A": "A",
|
||||
|
|
|
|||
7
src/types/Setting.ts
Normal file
7
src/types/Setting.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { ReactElement } from "react";
|
||||
|
||||
export type SettingType = {
|
||||
name:string;
|
||||
description:string;
|
||||
children?:ReactElement;
|
||||
}
|
||||
|
|
@ -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