Done
This commit is contained in:
parent
6ec649308d
commit
8c6c1fd6cb
|
|
@ -7,5 +7,5 @@
|
|||
```bash
|
||||
git clone https://repos.point-dev.net/Karimaldeen/hijabi-dashboard.git
|
||||
cd hijabi-dashboard
|
||||
npm install
|
||||
npm start
|
||||
pnpm install
|
||||
pnpm start
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ const TableActions = ({ onDelete=()=>{} , objectToEdit,onEdit=()=>{},onView,sh
|
|||
}} className="cursor-pointer m-2" size={20} />}
|
||||
{showView && <FaEye onClick={onView} className="cursor-pointer m-2" size={25} />}
|
||||
|
||||
|
||||
{showDelete && (
|
||||
<FaTrash
|
||||
onClick={() =>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder
|
|||
|
||||
const { errorMsg, isError, t, formik } = useFormField(name, props)
|
||||
const onCalendarChange = (value: any) => {
|
||||
|
||||
console.log(value,"value");
|
||||
formik.setFieldValue(name, value)
|
||||
|
||||
};
|
||||
|
|
@ -31,7 +31,7 @@ const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder
|
|||
size="large"
|
||||
onChange={onChange || onCalendarChange}
|
||||
disabled={isDisabled}
|
||||
format={Format ?? ""}
|
||||
format={Format}
|
||||
/>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
|
|||
import useFormField from '../../../Hooks/useFormField';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, isMulti, onChange, className, props }: any) => {
|
||||
const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, isMulti, onChange, className, loading,props }: any) => {
|
||||
const { errorMsg, isError, t, formik } = useFormField(name, props);
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
const location = useLocation()
|
||||
|
|
@ -55,6 +55,7 @@ const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, i
|
|||
showSearch
|
||||
optionFilterProp="label"
|
||||
onSearch={SearchHandleChange}
|
||||
loading={loading}
|
||||
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const SelectField = ({ name, label, placeholder, isDisabled,option,isMulti,onCha
|
|||
options={option}
|
||||
size="large"
|
||||
className={`${className} w-100`}
|
||||
defaultValue={formik.values?.name}
|
||||
defaultValue={formik.values[name]}
|
||||
allowClear
|
||||
{...(isMulti && { mode: "multiple" })}
|
||||
onChange={onChange || SelecthandleChange}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
option: any[];
|
||||
isMulti?: boolean;
|
||||
searchBy:string;
|
||||
loading?:boolean;
|
||||
|
||||
}
|
||||
export interface ValidationFieldPropsDataRange {
|
||||
|
|
|
|||
67
src/Layout/Dashboard/FormikForm.tsx
Normal file
67
src/Layout/Dashboard/FormikForm.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { Formik, Form } from 'formik';
|
||||
import React, { ReactNode } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Button } from "reactstrap";
|
||||
import * as Yup from 'yup';
|
||||
|
||||
interface FormValues {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface FormikFormProps {
|
||||
handleSubmit: (values: any) => void
|
||||
initialValues: FormValues;
|
||||
validationSchema: any;
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
ButtonName?:string
|
||||
}
|
||||
const FormikForm: React.FC<FormikFormProps> = ({ children, handleSubmit, initialValues, validationSchema, title = "Add New Item" ,ButtonName="إضافة"}) => {
|
||||
const [t]= useTranslation()
|
||||
|
||||
return (
|
||||
<>
|
||||
<Formik
|
||||
initialValues={initialValues}
|
||||
validationSchema={validationSchema}
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
{formik => (
|
||||
<Form >
|
||||
<div className="Card">
|
||||
{children}
|
||||
|
||||
</div>
|
||||
|
||||
</Form>
|
||||
)}
|
||||
</Formik>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FormikForm;
|
||||
|
||||
|
||||
|
||||
{/* <FormikForm
|
||||
handleSubmit={() => {
|
||||
|
||||
}}
|
||||
initialValues={() => {
|
||||
return {
|
||||
id: null,
|
||||
name: "",
|
||||
|
||||
}
|
||||
}}
|
||||
validationSchema={() => {
|
||||
return Yup.object().shape({
|
||||
name: Yup.string().required('required'),
|
||||
|
||||
});
|
||||
}}
|
||||
|
||||
>
|
||||
|
||||
</FormikForm> */}
|
||||
|
|
@ -26,9 +26,9 @@ const Header = () => {
|
|||
const [t] = useTranslation();
|
||||
const navigate = useNavigate()
|
||||
|
||||
// const { logout , user} = useAuthState()
|
||||
const { logout , user} = useAuthState()
|
||||
const handelClick = () => {
|
||||
// logout()
|
||||
logout()
|
||||
navigate('/auth', { replace: true })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const OnSuccess = ()=>{
|
|||
|
||||
return (
|
||||
<div className='LoginForm'>
|
||||
<img className='Logo' src="/Layout/etaxlogo.svg" alt="Logo" />
|
||||
<img className='Logo' src="/Logo.png" alt="Logo" />
|
||||
|
||||
<nav className='Login_Nav'>
|
||||
<h5> {t("Login")} </h5>
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ export const TabsContainer= ({parentKey}:any) => {
|
|||
setActiveKey(newKey);
|
||||
|
||||
const originalValues = values?.Attribute[parentKey].AttributeValue[targetKey];
|
||||
setFieldValue(`Attribute[${parentKey}].AttributeValue[${newKey}]`, originalValues);
|
||||
setFieldValue(`Attribute[${parentKey}].AttributeValue[${newKey}]`, {...originalValues,id:null});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
87
src/Pages/Categories/View/Add/fn/isvalidation.ts
Normal file
87
src/Pages/Categories/View/Add/fn/isvalidation.ts
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import { toast } from 'react-toastify';
|
||||
|
||||
|
||||
export const isvalidation = (attributes: any[] | undefined, t: any) => {
|
||||
const validationResults: boolean[] = [];
|
||||
let previousNames: { [key: string]: string } = {};
|
||||
|
||||
attributes?.slice(1)?.forEach((item: any, index: number) => {
|
||||
if (item && Object.keys(item).length > 0) {
|
||||
const itemName = t('name');
|
||||
const itemNumber = index + 1;
|
||||
|
||||
const currentItemNames = {
|
||||
name_ar: item.name_ar,
|
||||
name_en: item.name_en,
|
||||
name_de: item.name_de,
|
||||
};
|
||||
|
||||
if (
|
||||
previousNames.name_ar === currentItemNames.name_ar ||
|
||||
previousNames.name_en === currentItemNames.name_en ||
|
||||
previousNames.name_de === currentItemNames.name_de
|
||||
) {
|
||||
toast.error(`${itemName} ${t('unique_error_names')}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
|
||||
previousNames = currentItemNames;
|
||||
|
||||
// Check for other validation rules
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(`${t('required_name')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (!item?.type) {
|
||||
toast.error(`${t('required_type')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (item?.type === "image") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem.image === null) {
|
||||
toast.error(`${t('required_image')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de) {
|
||||
toast.error(`${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "color") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
const hexColorRegex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
if (attrItem && !hexColorRegex.test(attrItem?.value_en)) {
|
||||
toast.error(`${t('required_color')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "text") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem && (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de)) {
|
||||
toast.error(` ${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return validationResults;
|
||||
};
|
||||
|
|
@ -11,21 +11,20 @@ import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
|
|||
import { useAddAttribute } from '../../../api/attribute';
|
||||
import { TabsContainer } from './Add/AttributeTab/TabsContainer';
|
||||
import { useAddAttributeValue } from '../../../api/attributeValue';
|
||||
import { useFormikContext } from 'formik';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
|
||||
import { isvalidation } from './Add/fn/isvalidation';
|
||||
|
||||
const AddcategoriesPage = () => {
|
||||
|
||||
const { setObjectToEdit, objectToEdit } = usePageState()
|
||||
|
||||
const {mutate , isLoading,isSuccess,data } = useAddCategories()
|
||||
const {isSuccess : isSuccessAttribute,data:AttributeData, mutateAsync} = useAddAttribute()
|
||||
const {mutate:AddAttributeValue,isSuccess : isSuccessAttributeValue} = useAddAttributeValue()
|
||||
const {mutate ,isSuccess,data } = useAddCategories()
|
||||
const {mutateAsync} = useAddAttribute()
|
||||
const {mutate:AddAttributeValue } = useAddAttributeValue()
|
||||
|
||||
const [Attribute , setAttribute] = useState<any[]>([])
|
||||
const [AttributeValues , setAttributeValues] = useState<any[]>([])
|
||||
const formik = useFormikContext()
|
||||
|
||||
|
||||
const handleSubmit = (values:any)=>{
|
||||
|
|
@ -38,7 +37,6 @@ const AddcategoriesPage = () => {
|
|||
|
||||
});
|
||||
|
||||
|
||||
setAttributeValues(values?.Attribute?.slice(1)?.map((item:any)=>{
|
||||
if (item && Object.keys(item).length > 0){
|
||||
return item?.AttributeValue
|
||||
|
|
@ -55,87 +53,7 @@ const AddcategoriesPage = () => {
|
|||
}
|
||||
mutate(CategoriesValues)
|
||||
}
|
||||
const validationResults: boolean[] = [];
|
||||
let previousNames: any = {};
|
||||
|
||||
values?.Attribute?.slice(1)?.forEach((item: any, index: any) => {
|
||||
if (item && Object.keys(item).length > 0) {
|
||||
const itemName = t('name');
|
||||
const itemNumber = index + 1;
|
||||
|
||||
// Check if the names are unique across items
|
||||
const currentItemNames = {
|
||||
name_ar: item?.name_ar,
|
||||
name_en: item?.name_en,
|
||||
name_de: item?.name_de,
|
||||
};
|
||||
|
||||
if (
|
||||
previousNames.name_ar === currentItemNames.name_ar ||
|
||||
previousNames.name_en === currentItemNames.name_en ||
|
||||
previousNames.name_de === currentItemNames.name_de
|
||||
) {
|
||||
toast.error(`${itemName} ${t('unique_error_names')}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
|
||||
previousNames = currentItemNames;
|
||||
|
||||
// Check for other validation rules
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(`${t('required_name')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (!item?.type) {
|
||||
toast.error(`${t('required_type')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (item?.type === "image") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem.image === null) {
|
||||
toast.error(`${t('required_image')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de) {
|
||||
toast.error(`${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "color") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
const hexColorRegex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
if (attrItem && !hexColorRegex.test(attrItem?.value_en)) {
|
||||
toast.error(`${t('required_color')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "text") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem && (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de)) {
|
||||
toast.error(` ${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
const validationResults = isvalidation(values?.Attribute, t);
|
||||
|
||||
if (validationResults.every((result) => result)) {
|
||||
isValid();
|
||||
|
|
@ -196,31 +114,6 @@ const AddcategoriesPage = () => {
|
|||
},[isSuccess])
|
||||
|
||||
|
||||
// useEffect(()=>{
|
||||
|
||||
// if(isSuccessAttribute){
|
||||
// const AttributeId = (AttributeData as any )?.id ;
|
||||
|
||||
// AttributeValues?.slice(1)?.map((dataToSend:any , index:number)=>{
|
||||
// console.log(dataToSend,"dataToSend");
|
||||
|
||||
// const AttributeValues = dataToSend
|
||||
// const NewAttributeValues = {
|
||||
// value:{
|
||||
// en:AttributeValues?.value_en,
|
||||
// ar:AttributeValues?.value_ar,
|
||||
// de:AttributeValues?.value_de
|
||||
// },
|
||||
// image:AttributeValues?.main_photo,
|
||||
// attribute_id:AttributeId,
|
||||
// }
|
||||
// AddAttributeValue(NewAttributeValues)
|
||||
|
||||
// })
|
||||
|
||||
// }
|
||||
// },[isSuccessAttribute])
|
||||
|
||||
const {t} = useTranslation();
|
||||
|
||||
useNavigateOnSuccess(isSuccess , '/categories' )
|
||||
|
|
@ -266,18 +159,3 @@ const AddcategoriesPage = () => {
|
|||
|
||||
export default AddcategoriesPage
|
||||
|
||||
|
||||
function changeShapeInfo(originalObject: any) {
|
||||
const transformedObject: any = {};
|
||||
|
||||
for (const key in originalObject) {
|
||||
if (originalObject.hasOwnProperty(key)) {
|
||||
const index = key.split('.')[0]; // Extract index from key
|
||||
const attribute = key.split('.')[1]; // Extract attribute from key
|
||||
|
||||
transformedObject[originalObject[`${index}.key`]] = originalObject[`${index}.Description`];
|
||||
}
|
||||
}
|
||||
|
||||
return transformedObject
|
||||
}
|
||||
|
|
@ -74,6 +74,7 @@ const initialItemShape: any = {
|
|||
const originalValues = values?.Attribute?.[parentKey]?.AttributeValue?.[targetKey];
|
||||
|
||||
setFieldValue(`Attribute.${parentKey}.AttributeValue.${newKey}`, {...originalValues,id:null});
|
||||
console.log({...originalValues,id:null},"{...originalValues,id:null}");
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ import { TabsContainer } from './Edit/AttributeTab/TabsContainer';
|
|||
import { useAddAttribute, useGetSingleAttribute } from '../../../api/attribute';
|
||||
import { useDeleteAttribute, useUpdateAttribute } from '../../../api/attribute';
|
||||
import { useAddAttributeValue, useDeleteAttributeValue, useUpdateAttributeValue } from '../../../api/attributeValue';
|
||||
import { toast } from 'react-toastify';
|
||||
import Form from './Add/AddForm';
|
||||
import filterUndefinedAndEmpty from '../../../utils/Array/filterUndefinedAndEmpty';
|
||||
import { isvalidation } from './Add/fn/isvalidation';
|
||||
|
||||
const EditPage = () => {
|
||||
const { setObjectToEdit, objectToEdit } = usePageState()
|
||||
|
|
@ -48,16 +49,19 @@ const EditPage = () => {
|
|||
const [OldDataValues, setOldDataValues] = useState([])
|
||||
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
console.log(values,"values");
|
||||
const handleSubmit = (values: any
|
||||
) => {
|
||||
|
||||
function isValid() {
|
||||
const attributes = values?.Attribute?.slice(1);
|
||||
|
||||
setremovedAttribute(values?.removedAttribute)
|
||||
setremovedAttributeValue(values?.removedAttributeValue)
|
||||
console.log(attributes, "attributes");
|
||||
|
||||
if (attributes) {
|
||||
attributes.forEach((item: any, index: number) => {
|
||||
if (item.id && item.id !== null) {
|
||||
if (item?.id && item?.id !== null) {
|
||||
setEditAttribute((prevEditAttribute) => [...prevEditAttribute, item]);
|
||||
console.log(item, "item");
|
||||
if (item?.AttributeValue) {
|
||||
|
|
@ -70,8 +74,10 @@ const EditPage = () => {
|
|||
} else {
|
||||
setAddAttribute((prevAddAttribute) => [...prevAddAttribute, item]);
|
||||
if (item?.AttributeValue) {
|
||||
item.AttributeValue.slice(1).forEach((attrValueItem: any) => {
|
||||
if (attrValueItem && Object.keys(attrValueItem).length > 0) { // Check if attrValueItem is defined and not empty
|
||||
item?.AttributeValue?.slice(1)?.forEach((attrValueItem: any) => {
|
||||
console.log(attrValueItem, "attrValueItemadd");
|
||||
|
||||
if (attrValueItem && Object.keys(attrValueItem)?.length > 0) { // Check if attrValueItem is defined and not empty
|
||||
setAddAttributeValue((prevEditAttributeValue) => [...prevEditAttributeValue, [index, attrValueItem]]);
|
||||
}
|
||||
});
|
||||
|
|
@ -80,8 +86,6 @@ const EditPage = () => {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
const EditedCategory = {
|
||||
name: {
|
||||
en: values?.name_en,
|
||||
|
|
@ -98,89 +102,11 @@ const EditPage = () => {
|
|||
delete EditedCategory['photo']
|
||||
}
|
||||
|
||||
console.log(EditedCategory, "EditedCategory");
|
||||
|
||||
mutate(EditedCategory)
|
||||
}
|
||||
const validationResults: boolean[] = [];
|
||||
let previousNames: any = {};
|
||||
|
||||
values?.Attribute?.slice(1)?.forEach((item: any, index: any) => {
|
||||
if (item && Object.keys(item).length > 0) {
|
||||
const itemName = t('name');
|
||||
const itemNumber = index + 1;
|
||||
|
||||
const currentItemNames = {
|
||||
name_ar: item?.name_ar,
|
||||
name_en: item?.name_en,
|
||||
name_de: item?.name_de,
|
||||
};
|
||||
|
||||
if (
|
||||
previousNames.name_ar === currentItemNames.name_ar ||
|
||||
previousNames.name_en === currentItemNames.name_en ||
|
||||
previousNames.name_de === currentItemNames.name_de
|
||||
) {
|
||||
toast.error(`${itemName} ${t('unique_error_names')}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
|
||||
previousNames = currentItemNames;
|
||||
|
||||
// Check for other validation rules
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(`${t('required_name')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (!item?.type) {
|
||||
toast.error(`${t('required_type')} ${itemNumber}`);
|
||||
validationResults.push(false);
|
||||
} else if (item?.type === "image") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem.image === null) {
|
||||
toast.error(`${t('required_image')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de) {
|
||||
toast.error(`${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "color") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
const hexColorRegex = /^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
||||
if (attrItem && !hexColorRegex.test(attrItem?.value_en)) {
|
||||
toast.error(`${t('required_color')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (item?.type === "text") {
|
||||
if (Array.isArray(item.AttributeValue)) {
|
||||
item?.AttributeValue.slice(1)?.forEach((attrItem: any, index: number) => {
|
||||
if (attrItem && Object.keys(attrItem).length > 0) {
|
||||
if (attrItem && (!attrItem?.value_ar || !attrItem?.value_en || !attrItem?.value_de)) {
|
||||
toast.error(` ${t('required_text')} ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
const validationResults = isvalidation(values?.Attribute, t);
|
||||
|
||||
if (validationResults.every((result) => result)) {
|
||||
isValid();
|
||||
|
|
@ -199,11 +125,14 @@ const EditPage = () => {
|
|||
useEffect(() => {
|
||||
|
||||
if (isSuccess) {
|
||||
console.log(isSuccess, "isSuccess");
|
||||
|
||||
|
||||
const categoryId = id;
|
||||
console.log(EditAttribute, "EditAttribute");
|
||||
const filteredEditAttribute = filterUndefinedAndEmpty(EditAttribute);
|
||||
|
||||
EditAttribute?.map((dataToSend: any, index: number) => {
|
||||
filteredEditAttribute?.map((dataToSend: any, index: number) => {
|
||||
|
||||
console.log(index, "index");
|
||||
|
||||
|
|
@ -260,8 +189,9 @@ const EditPage = () => {
|
|||
}
|
||||
const result: [number, any][] = filterByIndex(index, EditAttributeValue);
|
||||
console.log(result, "result");
|
||||
const filteredresult = filterUndefinedAndEmpty(result);
|
||||
|
||||
result?.map((dataToSend: any) => {
|
||||
filteredresult?.map((dataToSend: any) => {
|
||||
if (dataToSend?.id && dataToSend.id !== null) {
|
||||
console.log(OldDataValues, "OldDataValues");
|
||||
|
||||
|
|
@ -347,6 +277,12 @@ const EditPage = () => {
|
|||
console.log("mutateAttributeValue");
|
||||
|
||||
const EditAttributeValue = dataToSend
|
||||
const IMages = EditAttributeValue?.id !== null ? {
|
||||
main_photo: EditAttributeValue?.main_photo,
|
||||
image: EditAttributeValue?.image,
|
||||
} : {
|
||||
copied_assets: { image: EditAttributeValue?.image },
|
||||
}
|
||||
const NewEditAttributeValue = {
|
||||
|
||||
value: {
|
||||
|
|
@ -354,7 +290,8 @@ const EditPage = () => {
|
|||
ar: EditAttributeValue?.value_ar,
|
||||
de: EditAttributeValue?.value_de
|
||||
},
|
||||
image: EditAttributeValue?.main_photo,
|
||||
// image: EditAttributeValue?.main_photo,
|
||||
...IMages,
|
||||
// attribute_id:EditAttribute?.id,
|
||||
attribute_id: EditAttribute?.id,
|
||||
}
|
||||
|
|
@ -380,7 +317,10 @@ const EditPage = () => {
|
|||
DeleteAttribute({ id: item })
|
||||
})
|
||||
|
||||
AddAttribute?.map((dataToSend: any, index: number) => {
|
||||
console.log(AddAttribute, "AddAttribute");
|
||||
const filteredAddAttribute = filterUndefinedAndEmpty(AddAttribute);
|
||||
|
||||
filteredAddAttribute?.map((dataToSend: any, index: number) => {
|
||||
|
||||
const AddAttribute = dataToSend
|
||||
|
||||
|
|
@ -435,7 +375,7 @@ const EditPage = () => {
|
|||
|
||||
|
||||
|
||||
// useNavigateOnSuccess(isSuccess, '/categories')
|
||||
useNavigateOnSuccess(isSuccess, '/categories')
|
||||
|
||||
|
||||
|
||||
|
|
@ -458,7 +398,7 @@ const EditPage = () => {
|
|||
}))
|
||||
console.log(OldDataValues, "OldDataValues");
|
||||
|
||||
}, [data?.category, Atrribute?.data]);
|
||||
}, [data?.category, Atrribute?.data, isRefetching, AttributeisRefetching]);
|
||||
|
||||
|
||||
const getValidationSchema = () => {
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ function Form() {
|
|||
const coupon_type_discount_flat = [{ lable: "general", value: "general" }]
|
||||
|
||||
const discount_type = [{ lable: "percentage", value: "percentage" },{ lable: "flat", value: "flat" }]
|
||||
const { data: CategoriesData} = useGetCategories()
|
||||
const { data: ProductData } = useGetProduct()
|
||||
const { data: CategoriesData,isLoading:CategoriesLoading} = useGetCategories()
|
||||
const { data: ProductData ,isLoading:ProductLoading} = useGetProduct()
|
||||
|
||||
const SelectCategoriesData = useFormatToSelect(CategoriesData?.categories)
|
||||
const SelectProductData = useFormatToSelect(ProductData?.BaseProducts)
|
||||
|
|
@ -51,8 +51,8 @@ function Form() {
|
|||
<ValidationField name="discount_type" type="Select" option={discount_type} />
|
||||
<ValidationField name="coupon_type" type="Select" option={values?.discount_type !== 'flat' ? coupon_type :coupon_type_discount_flat } />
|
||||
{/* <ValidationField name="itemable_type" label='coupon_item_type' type="Select" option={itemable_type} isDisabled={values?.coupon_type !== "specified"} isMulti/> */}
|
||||
<ValidationField name="product_attr" label='product_item' type="Search" option={SelectProductData} searchBy={"name"} isDisabled={values?.coupon_type !== "specified"}isMulti />
|
||||
<ValidationField name="category_attr" label='categories_item_name' type="Search" option={SelectCategoriesData} searchBy={"name"} isDisabled={values?.coupon_type !== "specified"}isMulti />
|
||||
<ValidationField name="product_attr" label='product_item' type="Search" option={SelectProductData} searchBy={"name"} isDisabled={values?.coupon_type !== "specified"}isMulti loading={ProductLoading} />
|
||||
<ValidationField name="category_attr" label='categories_item_name' type="Search" option={SelectCategoriesData} searchBy={"name"} isDisabled={values?.coupon_type !== "specified"}isMulti loading={CategoriesLoading} />
|
||||
<ValidationField name="status" type='Checkbox' label='status' />
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any>
|
|||
name: Yup.string().required('Required'),
|
||||
code: Yup.string().required('Required'),
|
||||
coupon_value: Yup.string().required('Required'),
|
||||
status: Yup.string().required('Required'),
|
||||
active: Yup.mixed().required('Required'),
|
||||
discount_type: Yup.string().required('Required'),
|
||||
coupon_type: Yup.string().required('Required'),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import Actions from "../../Components/Ui/tables/Actions";
|
|||
import ColumnsImage from "../../Components/Columns/ColumnsImage";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDeleteCoupon } from "../../api/Coupon";
|
||||
import { MdEmail } from "react-icons/md";
|
||||
import { useModalState } from "../../zustand/Modal";
|
||||
|
||||
function fnDelete(props :any ){}
|
||||
|
||||
|
|
@ -12,8 +14,7 @@ const useTableColumns :any = () => {
|
|||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteCoupon()
|
||||
const navigate = useNavigate()
|
||||
const language = localStorage.getItem("language") ?? "en"
|
||||
|
||||
const {setIsOpen} = useModalState(state=>state)
|
||||
return useMemo(
|
||||
() => [
|
||||
|
||||
|
|
@ -58,7 +59,8 @@ const useTableColumns :any = () => {
|
|||
onEdit={()=> navigate(`/coupon/${row.id}`) }
|
||||
showView={false}
|
||||
onDelete={() => deleteMutation.mutate({ id: row.id })}
|
||||
/>
|
||||
>
|
||||
</Actions>
|
||||
),
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
import React from 'react'
|
||||
import DataTable, { TableColumn } from "react-data-table-component";
|
||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||
import useTableColumns from './useTableColumn';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LoadingButton } from '../../../../Components/Ui/LoadingButton';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
|
||||
export default function LastOrderTable({ latest_Orders }:any) {
|
||||
|
||||
const columns = useTableColumns();
|
||||
const {t} = useTranslation();
|
||||
const navigate = useNavigate()
|
||||
return (
|
||||
<Card>
|
||||
<div className="primary" style={{display:"flex" , justifyContent:"space-between" , padding:"20px", marginTop:"10px"}}>
|
||||
|
||||
{t("latest_orders")}
|
||||
<LoadingButton color="primary" onClick={() => navigate("/order",{replace:true})}>
|
||||
{t("show_all_orders")}
|
||||
</LoadingButton>
|
||||
</div>
|
||||
|
||||
<CardBody>
|
||||
<DataTable
|
||||
columns={columns as any}
|
||||
data={latest_Orders}
|
||||
noDataComponent={<h6 className="my-4">{t("no_records")}</h6>}
|
||||
noHeader
|
||||
/>
|
||||
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import React, { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { GrView } from "react-icons/gr";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
const useTableColumns = () => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
const navigate = useNavigate()
|
||||
return useMemo(
|
||||
() => [
|
||||
|
||||
{
|
||||
name: t("order_code"),
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell:(row:any)=>{
|
||||
console.log(row);
|
||||
|
||||
return (row?.order_code)
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
name: t("order_total"),
|
||||
sortable: true,
|
||||
center: true,
|
||||
cell:(row)=>row["order_total"]
|
||||
},
|
||||
{
|
||||
name: t("order_status"),
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell:(row:any)=><span style={{
|
||||
padding:8, color:'black',borderRadius:10,fontSize:10}}>{t(row.order_status)}</span>
|
||||
|
||||
},
|
||||
{
|
||||
name: "#",
|
||||
selector: "action",
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell: (row:any) => (
|
||||
<GrView
|
||||
onClick={() => navigate(`/order/${row?.id}`, {replace:true})}
|
||||
size={22}
|
||||
style={{ cursor: "pointer" }}
|
||||
/>
|
||||
),
|
||||
},
|
||||
|
||||
|
||||
],
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export default useTableColumns;
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
import React from 'react'
|
||||
import DataTable from 'react-data-table-component';
|
||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||
import useTableColumns from './useTableColumn';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { LoadingButton } from '../../../../Components/Ui/LoadingButton';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
export default function LastUserTable({ most_driver_rate }:any) {
|
||||
const columns = useTableColumns();
|
||||
const {t} = useTranslation();
|
||||
const navigate = useNavigate()
|
||||
// console.log(most_driver_rate);
|
||||
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className='primary' style={{display:"flex" , justifyContent:"space-between" , padding:"20px", marginTop:"10px"}}>
|
||||
{t("last_users")}
|
||||
|
||||
{/* <LoadingButton color="primary" onClick={() => navigate("/user" , {replace:true})}>
|
||||
{t("show_all_users")}
|
||||
</LoadingButton> */}
|
||||
</div>
|
||||
<CardBody>
|
||||
|
||||
<DataTable
|
||||
columns={columns as any }
|
||||
|
||||
data={most_driver_rate}
|
||||
noDataComponent={<h6 className="my-4">{t("no_records")}</h6>}
|
||||
noHeader
|
||||
/>
|
||||
</CardBody>
|
||||
</Card>
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
import React from "react";
|
||||
import { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { GrView } from "react-icons/gr";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Rating } from "react-simple-star-rating";
|
||||
|
||||
|
||||
interface RowData {
|
||||
name:string ,
|
||||
phone:string ,
|
||||
email:string ,
|
||||
id:number
|
||||
}
|
||||
|
||||
const useTableColumns = () => {
|
||||
const navigate = useNavigate()
|
||||
const {t} = useTranslation();
|
||||
|
||||
return useMemo(() => {
|
||||
const columns = [
|
||||
{
|
||||
name: t("full_name"),
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell: (row: RowData) => row?.name,
|
||||
},
|
||||
{
|
||||
name: t("email"),
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell: (row: RowData) => row?.email,
|
||||
},
|
||||
{
|
||||
name: t("phone"),
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell: (row: RowData) => row?.phone,
|
||||
},
|
||||
// {
|
||||
// name: "#",
|
||||
// selector: "action",
|
||||
// sortable: false,
|
||||
// center: true,
|
||||
// cell: (row: RowData) => (
|
||||
// <GrView
|
||||
// onClick={() => navigate(`/user/${row?.id}`, {replace:true})}
|
||||
// size={22}
|
||||
// style={{ cursor: "pointer" }}
|
||||
// />
|
||||
// ),
|
||||
// },
|
||||
];
|
||||
|
||||
return columns;
|
||||
}, [t]);
|
||||
};
|
||||
|
||||
export default useTableColumns;
|
||||
46
src/Pages/Notifcation/Page.tsx
Normal file
46
src/Pages/Notifcation/Page.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
import React from 'react'
|
||||
import DashBody from '../../Layout/Dashboard/DashBody'
|
||||
import DashHeader from '../../Layout/Dashboard/DashHeader'
|
||||
import LyTable from '../../Layout/Dashboard/LyTable'
|
||||
import useTableColumns from './useTableColumns'
|
||||
import { QueryStatusEnum } from '../../config/QueryStatus'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import AddButton from '../../Layout/Dashboard/AddButton/AddButton'
|
||||
import SearchField from '../../Layout/Dashboard/SearchField'
|
||||
import { useGetNotification } from '../../api/notification'
|
||||
|
||||
function Page() {
|
||||
|
||||
const column =useTableColumns()
|
||||
const {data ,status } = useGetNotification()
|
||||
const [t] = useTranslation()
|
||||
const navigate = useNavigate()
|
||||
const totalRows = data?.meta?.total;
|
||||
|
||||
return (
|
||||
// Pass Status to Layout
|
||||
<DashBody status={status as QueryStatusEnum} >
|
||||
|
||||
<DashHeader showAddButton={false} title={'notification'}>
|
||||
<div className='RightSide d-flex gap-2 align-center '>
|
||||
<SearchField searchBy={"name"} />
|
||||
|
||||
<AddButton onClick={()=>navigate('/notification/add')}></AddButton>
|
||||
</div>
|
||||
</DashHeader>
|
||||
<LyTable
|
||||
data={data?.data}
|
||||
isLoading={false}
|
||||
columns={column}
|
||||
total={totalRows}
|
||||
is_pagination={true}
|
||||
/>
|
||||
|
||||
</DashBody>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page
|
||||
|
||||
42
src/Pages/Notifcation/View/AddForm.tsx
Normal file
42
src/Pages/Notifcation/View/AddForm.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
import { Col, Row } from 'reactstrap';
|
||||
import ValidationField from '../../../Components/ValidationField/ValidationField';
|
||||
|
||||
function Form() {
|
||||
const type = [{ lable: "other", value: "other" },{ lable: "product", value: "product"},{ lable: "order", value: "order" }]
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
||||
<Col>
|
||||
<ValidationField name="body_en" />
|
||||
<ValidationField name="body_ar" />
|
||||
<ValidationField name="body_de" />
|
||||
{/* <ValidationField name="meta" /> */}
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="title_en" />
|
||||
<ValidationField name="title_ar" />
|
||||
<ValidationField name="title_de" />
|
||||
|
||||
{/* <ValidationField name="type" type="Select" option={type} /> */}
|
||||
|
||||
|
||||
|
||||
|
||||
</Col>
|
||||
|
||||
|
||||
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
||||
|
||||
|
||||
|
||||
80
src/Pages/Notifcation/View/AddPage.tsx
Normal file
80
src/Pages/Notifcation/View/AddPage.tsx
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { getInitialValuesForAdd as getInitialValues, getValidationSchema, getDataToSend } from './formUtil'
|
||||
import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs'
|
||||
import 'react-tabs/style/react-tabs.css';
|
||||
import { MdLanguage } from 'react-icons/md'
|
||||
import ViewPage from '../../../Layout/Dashboard/ViewPage';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
|
||||
import { useAddUsers } from '../../../api/users';
|
||||
import Form from './AddForm';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useAddNotification } from '../../../api/notification';
|
||||
|
||||
const AddPage = () => {
|
||||
|
||||
|
||||
const { mutate, isLoading, isSuccess } = useAddNotification()
|
||||
const {id} = useParams()
|
||||
const handleSubmit = (values: any) => {
|
||||
|
||||
const body = {
|
||||
en: values.body_en,
|
||||
ar: values.body_ar,
|
||||
du: values.body_de
|
||||
}
|
||||
const meta = {}
|
||||
const title = {
|
||||
en: values.title_en,
|
||||
ar: values.title_ar,
|
||||
du: values.title_de
|
||||
}
|
||||
const dataToSend = {
|
||||
body: JSON.stringify(body),
|
||||
meta: JSON.stringify(meta),
|
||||
title:JSON.stringify(title),
|
||||
user_ids: [id],
|
||||
type: "other",
|
||||
|
||||
};
|
||||
|
||||
|
||||
mutate(dataToSend);
|
||||
};
|
||||
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useNavigateOnSuccess(isSuccess, '/users')
|
||||
|
||||
|
||||
|
||||
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
|
||||
|
||||
|
||||
return (
|
||||
<div className='ViewPage'>
|
||||
|
||||
<ViewPage {...ViewProps}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("BasicInfo")}</h6></div></Tab>
|
||||
|
||||
|
||||
|
||||
</TabList>
|
||||
<TabBody >
|
||||
<div className=" mt-4"><Form /></div>
|
||||
</TabBody>
|
||||
|
||||
</Tabs>
|
||||
</ViewPage>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default AddPage
|
||||
72
src/Pages/Notifcation/View/formUtil.ts
Normal file
72
src/Pages/Notifcation/View/formUtil.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
import * as Yup from "yup";
|
||||
import { buildFormData } from "../../../api/helper/buildFormData";
|
||||
import moment from 'moment';
|
||||
import * as dayjs from 'dayjs'
|
||||
|
||||
|
||||
export const getInitialValues = (objectToEdit: any | null = null): any => {
|
||||
//@ts-ignore
|
||||
return {
|
||||
id: objectToEdit?.id ,
|
||||
name: objectToEdit?.name ,
|
||||
email: objectToEdit?.email ,
|
||||
type: objectToEdit?.type ,
|
||||
avatar: objectToEdit?.avatar ,
|
||||
|
||||
};
|
||||
};
|
||||
export const getInitialValuesForAdd = (objectToEdit: any | null = null): any => {
|
||||
return {
|
||||
body_en: "" ,
|
||||
body_ar: "" ,
|
||||
body_de: "" ,
|
||||
meta: "" ,
|
||||
title_en: "" ,
|
||||
title_ar: "" ,
|
||||
title_de: "" ,
|
||||
user_ids:[],
|
||||
type: "" ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any> => {
|
||||
// Validate input
|
||||
return Yup.object().shape({
|
||||
body_en: Yup.string().required('Required'),
|
||||
body_ar: Yup.string().required('Required'),
|
||||
body_de: Yup.string().required('Required'),
|
||||
// meta: Yup.string().required('Required'),
|
||||
|
||||
title_en: Yup.string().required('Required'),
|
||||
title_ar: Yup.string().required('Required'),
|
||||
title_de: Yup.string().required('Required'),
|
||||
// type: Yup.string().required('Required'),
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const getDataToSend = (values: any): FormData => {
|
||||
const data = { ...values };
|
||||
|
||||
|
||||
const formData = new FormData();
|
||||
buildFormData(formData, data);
|
||||
return formData;
|
||||
};
|
||||
|
||||
export const ChangeDataToPrint = (data: any) => {
|
||||
|
||||
let new_array = data
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
new_array[i]['status'] = !data[i]['deleted_at'] ? 'available' : 'unavailable'
|
||||
delete new_array[i]['deleted_at']
|
||||
}
|
||||
return new_array
|
||||
}
|
||||
67
src/Pages/Notifcation/useTableColumns.tsx
Normal file
67
src/Pages/Notifcation/useTableColumns.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
|
||||
import React, { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Actions from "../../Components/Ui/tables/Actions";
|
||||
import ColumnsImage from "../../Components/Columns/ColumnsImage";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDeleteNotification } from "../../api/notification";
|
||||
import { Switch } from "antd";
|
||||
import { MdEmail } from "react-icons/md";
|
||||
import { useModalState } from "../../zustand/Modal";
|
||||
|
||||
|
||||
const useTableColumns: any = () => {
|
||||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteNotification()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { setIsOpen } = useModalState(state => state)
|
||||
|
||||
const language = localStorage.getItem("language") ?? "en"
|
||||
|
||||
return useMemo(
|
||||
() => [
|
||||
|
||||
{
|
||||
name: t("name"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.user?.name
|
||||
},
|
||||
{
|
||||
name: t("title"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.title[language]
|
||||
},
|
||||
{
|
||||
name: t("body"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.body[language]
|
||||
},
|
||||
|
||||
// {
|
||||
// name: "#",
|
||||
// sortable: false,
|
||||
// center: true,
|
||||
// cell: (row: any) => (
|
||||
// <Actions
|
||||
// objectToEdit={row}
|
||||
// showEdit={false}
|
||||
// onEdit={() => navigate(`/notification/${row.id}`)}
|
||||
// showView={false}
|
||||
// onDelete={() => deleteMutation.mutate({ id: row.id })}
|
||||
// >
|
||||
|
||||
// </Actions>
|
||||
// ),
|
||||
// },
|
||||
|
||||
],
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export default useTableColumns;
|
||||
|
||||
|
|
@ -11,7 +11,8 @@ import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
|
|||
import { useAddProduct, useAddProductVariation } from '../../../api/product';
|
||||
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
|
||||
import { TabsContainer } from './FormikTab/TabsContainer';
|
||||
import { toast } from 'react-toastify';
|
||||
import { isvalidation } from './Addfn/isvalidation';
|
||||
import { AddNewVariation } from './Addfn/AddNewVariation';
|
||||
// import AttributeInfo from './AttributeInfo';
|
||||
|
||||
const AddProductPage = () => {
|
||||
|
|
@ -21,7 +22,6 @@ const AddProductPage = () => {
|
|||
const { mutate: AddVariation, isSuccess: SuccessVariation } = useAddProductVariation()
|
||||
|
||||
const [IsValed, setIsValed] = useState(false)
|
||||
const [infotaps, setInfoTaps] = useState<any[]>([])
|
||||
|
||||
const [Varibletaps, setVaribleTaps] = useState<any[]>([])
|
||||
|
||||
|
|
@ -29,108 +29,35 @@ const AddProductPage = () => {
|
|||
|
||||
function isValid() {
|
||||
|
||||
setInfoTaps(values?.info?.slice(1)?.map((taps: any) => {
|
||||
return (changeShapeInfo(taps));
|
||||
}));
|
||||
setVaribleTaps(values?.variable?.slice(1))
|
||||
mutate({
|
||||
|
||||
const new_category = {
|
||||
name: {
|
||||
en: values?.name_en,
|
||||
ar: values?.name_ar,
|
||||
de: values?.name_de
|
||||
},
|
||||
category_id: 1
|
||||
})
|
||||
}
|
||||
mutate(new_category)
|
||||
}
|
||||
|
||||
const validationResults: boolean[] = [];
|
||||
|
||||
values?.variable?.slice(1)?.forEach((item: any, index: any) => {
|
||||
if (item && Object.keys(item).length > 0) { // Check if attrValueItem is defined and not empty
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(t('required_name') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
else if (!item?.description_ar || !item?.description_en || !item?.description_de) {
|
||||
toast.error(t('required_description') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (item.main_photo === null || !item?.main_photo ) {
|
||||
toast.error(t('required_main_photo') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
else if (item.price === null || !item?.price) {
|
||||
toast.error(t('required_price') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
|
||||
}
|
||||
else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
const validationResults = isvalidation(values.variable, t);
|
||||
|
||||
if (validationResults.every((result) => result)) {
|
||||
isValid();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
useEffect(() => {
|
||||
|
||||
if (isSuccess) {
|
||||
const baseProductId = (data as any)?.id;
|
||||
console.log(infotaps);
|
||||
console.log(Varibletaps);
|
||||
|
||||
Varibletaps?.map((dataToSend: any, index: number) => {
|
||||
|
||||
const varible = dataToSend
|
||||
const info = varible?.info
|
||||
const convertedArray = info.reduce((acc:any, obj:any) => {
|
||||
acc[obj.Description] = obj.key;
|
||||
return acc;
|
||||
}, {});
|
||||
const jsonString = JSON.stringify(convertedArray);
|
||||
|
||||
|
||||
const Newproduct = {
|
||||
name: {
|
||||
en: varible?.name_en,
|
||||
ar: varible?.name_ar,
|
||||
de: varible?.name_de
|
||||
},
|
||||
description: {
|
||||
en: varible?.description_en,
|
||||
ar: varible?.description_ar,
|
||||
de: varible?.description_de
|
||||
},
|
||||
quantity: varible?.quantity,
|
||||
main_photo: varible?.main_photo,
|
||||
images: varible?.images,
|
||||
info: jsonString,
|
||||
price : varible?.price,
|
||||
|
||||
|
||||
product_attributes: varible?.attribute?.map((item: any, index: any) => {
|
||||
return { attribute_value_id: item?.value, attribute_id: item?.id }
|
||||
}),
|
||||
|
||||
base_product_id: baseProductId
|
||||
}
|
||||
console.log(Newproduct);
|
||||
|
||||
AddVariation(Newproduct)
|
||||
})
|
||||
|
||||
AddNewVariation(Varibletaps, data, AddVariation);
|
||||
}
|
||||
}, [isSuccess])
|
||||
|
||||
|
||||
const { setObjectToEdit, objectToEdit } = usePageState()
|
||||
const { setObjectToEdit } = usePageState()
|
||||
|
||||
useEffect(() => {
|
||||
setObjectToEdit([]);
|
||||
|
|
@ -155,8 +82,6 @@ const AddProductPage = () => {
|
|||
|
||||
<Tab ><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><BsInfoCircle size={20} /></span> <h6 className='SingleInfo'>{t("VarianInfo")}</h6></div></Tab>
|
||||
|
||||
{/* <Tab ><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><BsInfoCircle size={20} /></span> <h6 className='SingleInfo'>{t("AttributeInfo")}</h6></div></Tab> */}
|
||||
|
||||
|
||||
</TabList>
|
||||
<TabBody >
|
||||
|
|
@ -165,9 +90,6 @@ const AddProductPage = () => {
|
|||
<TabBody >
|
||||
<div className=" mt-4"><TabsContainer /></div>
|
||||
</TabBody>
|
||||
<TabBody >
|
||||
{/* <div className=" mt-4"><AttributeInfo /></div> */}
|
||||
</TabBody>
|
||||
</Tabs>
|
||||
</ViewPage>
|
||||
|
||||
|
|
@ -180,18 +102,3 @@ const AddProductPage = () => {
|
|||
|
||||
export default AddProductPage
|
||||
|
||||
|
||||
function changeShapeInfo(originalObject: any) {
|
||||
const transformedObject: any = {};
|
||||
|
||||
for (const key in originalObject) {
|
||||
if (originalObject.hasOwnProperty(key)) {
|
||||
const index = key.split('.')[0]; // Extract index from key
|
||||
const attribute = key.split('.')[1]; // Extract attribute from key
|
||||
|
||||
transformedObject[originalObject[`${index}.key`]] = originalObject[`${index}.Description`];
|
||||
}
|
||||
}
|
||||
|
||||
return transformedObject
|
||||
}
|
||||
43
src/Pages/Products/View/Addfn/AddNewVariation.ts
Normal file
43
src/Pages/Products/View/Addfn/AddNewVariation.ts
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Function to process variable taps when success is true
|
||||
export function AddNewVariation(Varibletaps: any[], data: any, AddVariation: any) {
|
||||
const baseProductId = data?.id;
|
||||
Varibletaps?.forEach((dataToSend: any) => {
|
||||
const varible = dataToSend;
|
||||
const info = varible?.info;
|
||||
const convertedArray = info?.reduce((acc: any, obj: any) => {
|
||||
acc[obj.Description] = obj.key;
|
||||
return acc;
|
||||
}, {});
|
||||
const jsonString = JSON.stringify(convertedArray);
|
||||
const IMages = varible?.id !== null ? {
|
||||
main_photo: varible?.main_photo,
|
||||
images: varible?.images,
|
||||
} : {
|
||||
copied_assets: { main_photo: varible?.main_photo, images: varible?.images },
|
||||
}
|
||||
|
||||
const Newproduct = {
|
||||
name: {
|
||||
en: varible?.name_en,
|
||||
ar: varible?.name_ar,
|
||||
de: varible?.name_de
|
||||
},
|
||||
description: {
|
||||
en: varible?.description_en,
|
||||
ar: varible?.description_ar,
|
||||
de: varible?.description_de
|
||||
},
|
||||
// quantity: varible?.quantity,
|
||||
...IMages,
|
||||
info: jsonString,
|
||||
price: varible?.price,
|
||||
product_attributes: varible?.attribute?.map((item: any, index: any) => {
|
||||
return { attribute_value_id: item?.value, attribute_id: item?.id };
|
||||
}),
|
||||
base_product_id: baseProductId
|
||||
};
|
||||
console.log(Newproduct);
|
||||
AddVariation(Newproduct);
|
||||
});
|
||||
}
|
||||
|
||||
27
src/Pages/Products/View/Addfn/isvalidation.ts
Normal file
27
src/Pages/Products/View/Addfn/isvalidation.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { toast } from "react-toastify";
|
||||
|
||||
// Function to validate variable items
|
||||
export function isvalidation(variableItems: any[], t: any) {
|
||||
const validationResults: boolean[] = [];
|
||||
variableItems.slice(1).forEach((item: any, index: any) => {
|
||||
if (item && Object.keys(item).length > 0) { // Check if item is defined and not empty
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(t('required_name') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (!item?.description_ar || !item?.description_en || !item?.description_de) {
|
||||
toast.error(t('required_description') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (item.main_photo === null || !item?.main_photo) {
|
||||
toast.error(t('required_main_photo') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (item.price === null || !item?.price) {
|
||||
toast.error(t('required_price') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
return validationResults;
|
||||
}
|
||||
|
||||
|
|
@ -10,11 +10,12 @@ import LoadingPage from '../../../Layout/app/LoadingPage';
|
|||
import { useTranslation } from 'react-i18next';
|
||||
import { BsInfoCircle } from 'react-icons/bs';
|
||||
import { useAddProductVariation, useDeleteProductVariation, useGetOneProduct, useUpdateProduct, useUpdateProductVariation } from '../../../api/product';
|
||||
import { changeShapeInfo } from '../../../utils/Array/changeShapeInfo';
|
||||
import { Spin } from 'antd';
|
||||
import BasicInfo from './BasicInfo';
|
||||
import { TabsContainer } from './FormikTab/TabsContainer';
|
||||
import { toast } from 'react-toastify';
|
||||
import { isvalidation } from './Addfn/isvalidation';
|
||||
import filterUndefinedAndEmpty from '../../../utils/Array/filterUndefinedAndEmpty';
|
||||
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
|
||||
|
||||
const ViewProduct = () => {
|
||||
const { setObjectToEdit, objectToEdit } = usePageState()
|
||||
|
|
@ -34,13 +35,10 @@ const ViewProduct = () => {
|
|||
|
||||
const [Variant, setVariant] = useState<any>([])
|
||||
|
||||
const [InfoTaps, setInfoTaps] = useState<any>([])
|
||||
|
||||
|
||||
|
||||
const handleSubmit = (values: any) => {
|
||||
// Update removedVarianteValues state
|
||||
console.log(values, "values");
|
||||
console.log(values?.removedVariant, "values?.removedVariant");
|
||||
function isValid() {
|
||||
setremovedVariant(values?.removedVariant);
|
||||
const variables = values?.variable?.slice(1);
|
||||
|
|
@ -58,41 +56,9 @@ const ViewProduct = () => {
|
|||
category_id: values?.category_id
|
||||
};
|
||||
|
||||
// Uncomment this line to perform the mutation
|
||||
mutate(newData);
|
||||
}
|
||||
|
||||
const validationResults: boolean[] = [];
|
||||
|
||||
values?.variable?.slice(1)?.forEach((item: any, index: any) => {
|
||||
if (item && Object.keys(item).length > 0) { // Check if attrValueItem is defined and not empty
|
||||
if (!item?.name_ar || !item?.name_en || !item?.name_de) {
|
||||
toast.error(t('required_name') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
else if (!item?.description_ar || !item?.description_en || !item?.description_de) {
|
||||
toast.error(t('required_description') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
} else if (item.main_photo === null || !item?.main_photo ) {
|
||||
toast.error(t('required_main_photo') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
}
|
||||
else if (item.price === null || !item?.price) {
|
||||
toast.error(t('required_price') + ` ${index + 1}`);
|
||||
validationResults.push(false);
|
||||
|
||||
}
|
||||
else {
|
||||
validationResults.push(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const validationResults = isvalidation(values.variable, t);
|
||||
if (validationResults.every((result) => result)) {
|
||||
isValid();
|
||||
}
|
||||
|
|
@ -108,14 +74,13 @@ const ViewProduct = () => {
|
|||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
const baseProductId = id;
|
||||
const filtered_Variant = filterUndefinedAndEmpty(Variant);
|
||||
|
||||
Variant?.map((dataToSend: any, index: number) => {
|
||||
filtered_Variant?.map((dataToSend: any, index: number) => {
|
||||
console.log(dataToSend, "dataToSend");
|
||||
const varible = dataToSend
|
||||
|
||||
if (varible?.id && varible?.id !== null) {
|
||||
const foundObject = OldData.find((item: any) => item.id === varible?.id) as any;
|
||||
|
||||
const info = varible?.info
|
||||
console.log(info, "info");
|
||||
|
||||
|
|
@ -138,7 +103,7 @@ const ViewProduct = () => {
|
|||
ar: varible?.description_ar,
|
||||
de: varible?.description_de
|
||||
},
|
||||
quantity: varible?.quantity,
|
||||
// quantity: varible?.quantity,
|
||||
main_photo: varible?.main_photo,
|
||||
images: varible?.images,
|
||||
info: jsonString,
|
||||
|
|
@ -198,6 +163,7 @@ const ViewProduct = () => {
|
|||
// Check if the number of keys is the same
|
||||
if (editedInfoKeys.length === foundInfoKeys.length) {
|
||||
// Check if all keys and their corresponding values are the same
|
||||
|
||||
const keysAreEqual = editedInfoKeys.every((key: any) => {
|
||||
//@ts-ignore
|
||||
console.log(convertedArray[key], "convertedArray[key] ");
|
||||
|
|
@ -212,6 +178,10 @@ const ViewProduct = () => {
|
|||
delete Editedproduct.info;
|
||||
}
|
||||
}
|
||||
if (Object.keys(Editedproduct.info).length === 0) {
|
||||
//@ts-ignore
|
||||
delete Editedproduct.info;
|
||||
}
|
||||
}
|
||||
if (Object.keys(Editedproduct).length > 0) {
|
||||
//@ts-ignore
|
||||
|
|
@ -234,6 +204,13 @@ const ViewProduct = () => {
|
|||
}, {});
|
||||
const jsonString = JSON.stringify(convertedArray);
|
||||
|
||||
const IMages = varible?.id !== null ? {
|
||||
main_photo: varible?.main_photo,
|
||||
images: varible?.images,
|
||||
} : {
|
||||
copied_assets: { main_photo: varible?.main_photo, images: varible?.images },
|
||||
}
|
||||
|
||||
const Newproduct = {
|
||||
name: {
|
||||
en: varible?.name_en,
|
||||
|
|
@ -245,13 +222,15 @@ const ViewProduct = () => {
|
|||
ar: varible?.description_ar,
|
||||
de: varible?.description_de
|
||||
},
|
||||
quantity: varible?.quantity,
|
||||
main_photo: varible?.main_photo,
|
||||
images: varible?.images,
|
||||
// quantity: varible?.quantity,
|
||||
|
||||
info: jsonString,
|
||||
price: varible?.price,
|
||||
base_product_id: id,
|
||||
|
||||
...IMages,
|
||||
|
||||
|
||||
|
||||
product_attributes: varible?.attribute?.map((item: any, index: any) => {
|
||||
return { attribute_value_id: item?.value, attribute_id: item?.id }
|
||||
|
|
@ -265,7 +244,9 @@ const ViewProduct = () => {
|
|||
})
|
||||
|
||||
console.log(removedVariant);
|
||||
removedVariant?.map((item: any) => {
|
||||
const filtered_removedVariant = filterUndefinedAndEmpty(removedVariant);
|
||||
|
||||
filtered_removedVariant?.map((item: any) => {
|
||||
return DeleteVariation({ id: item })
|
||||
})
|
||||
}
|
||||
|
|
@ -273,14 +254,14 @@ const ViewProduct = () => {
|
|||
|
||||
|
||||
|
||||
// useNavigateOnSuccess(UpdetedSuccessVariation || AddedSuccessVariation, '/products')
|
||||
useNavigateOnSuccess(isSuccess , '/products')
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
// refetch()
|
||||
setObjectToEdit(data?.data);
|
||||
setOldData(data?.data?.products)
|
||||
}, [data, id, isRefetching]);
|
||||
}, [data, data?.data, id, isRefetching]);
|
||||
|
||||
const getValidationSchema = () => {
|
||||
return null
|
||||
|
|
@ -294,7 +275,7 @@ const ViewProduct = () => {
|
|||
|
||||
return (
|
||||
<div className='ViewPage'>
|
||||
{objectToEdit && data ?
|
||||
{objectToEdit && data?.data && objectToEdit ?
|
||||
<ViewPage {...ViewProps}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
|
|
@ -308,7 +289,7 @@ const ViewProduct = () => {
|
|||
<div className=" mt-4"><BasicInfo /></div>
|
||||
</TabBody>
|
||||
<TabBody >
|
||||
<div className=" mt-4"> {isLoading ? <Spin /> : <TabsContainer />} </div>
|
||||
<div className=" mt-4"> {isLoading && objectToEdit ? <Spin /> : <TabsContainer />} </div>
|
||||
</TabBody>
|
||||
|
||||
</Tabs>
|
||||
|
|
|
|||
|
|
@ -50,11 +50,17 @@ export const VariableTabs: React.FC<VariableTabsProps> = ({ tabKey }) => {
|
|||
onChange={handleFieldChange('name_de')}
|
||||
|
||||
/>
|
||||
<FormItem
|
||||
{/* <FormItem
|
||||
label={t(`quantity`)}
|
||||
value={FormikName("quantity")}
|
||||
onChange={handleFieldChange('quantity')}
|
||||
type="number"
|
||||
/> */}
|
||||
<FormItem
|
||||
label={t(`price`)}
|
||||
value={FormikName("price")}
|
||||
onChange={handleFieldChange('price')}
|
||||
type="number"
|
||||
/>
|
||||
|
||||
{values?.category_id &&
|
||||
|
|
@ -79,12 +85,7 @@ export const VariableTabs: React.FC<VariableTabsProps> = ({ tabKey }) => {
|
|||
value={FormikName("description_de")}
|
||||
onChange={handleFieldChange('description_de')}
|
||||
/>
|
||||
<FormItem
|
||||
label={t(`price`)}
|
||||
value={FormikName("price")}
|
||||
onChange={handleFieldChange('price')}
|
||||
type="number"
|
||||
/>
|
||||
|
||||
<File tabKey={tabKey} />
|
||||
<MaltyFile tabKey={tabKey} />
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -5,17 +5,18 @@ import { ImageBaseURL } from "../../api/config";
|
|||
|
||||
|
||||
export const getInitialValues = (objectToEdit: any) => {
|
||||
if (!objectToEdit || !objectToEdit.products) {
|
||||
if (!objectToEdit || !objectToEdit?.products) {
|
||||
return {};
|
||||
}
|
||||
const products = objectToEdit?.products.map((item: any) => {
|
||||
if (!item || !item.info) {
|
||||
return {};
|
||||
}
|
||||
const formattedData = Object.entries(item?.info).map(([key, value]) => ({
|
||||
[`Description`]: key,
|
||||
[`key`]: value,
|
||||
}));
|
||||
const products = objectToEdit?.products?.map((item: any) => {
|
||||
console.log(item,"item");
|
||||
|
||||
|
||||
const formattedData = item?.info ? Object.entries(item?.info).map(([key, value], index) => ({
|
||||
[`${index}.Description`]: key,
|
||||
[`${index}.key`]: value,
|
||||
})) : [];
|
||||
|
||||
|
||||
return ({
|
||||
|
||||
|
|
@ -41,6 +42,9 @@ export const getInitialValues = (objectToEdit: any) => {
|
|||
[`${index}.Description`]: key,
|
||||
[`${index}.key`]: value,
|
||||
}));
|
||||
console.log(products,"products");
|
||||
console.log(objectToEdit,"objectToEdit");
|
||||
|
||||
|
||||
return {
|
||||
id:objectToEdit?.id,
|
||||
|
|
|
|||
46
src/Pages/Users/Page.tsx
Normal file
46
src/Pages/Users/Page.tsx
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
import React from 'react'
|
||||
import DashBody from '../../Layout/Dashboard/DashBody'
|
||||
import DashHeader from '../../Layout/Dashboard/DashHeader'
|
||||
import LyTable from '../../Layout/Dashboard/LyTable'
|
||||
import useTableColumns from './useTableColumns'
|
||||
import { QueryStatusEnum } from '../../config/QueryStatus'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import AddButton from '../../Layout/Dashboard/AddButton/AddButton'
|
||||
import { useGetUsers } from '../../api/users'
|
||||
import SearchField from '../../Layout/Dashboard/SearchField'
|
||||
|
||||
function Page() {
|
||||
|
||||
const column =useTableColumns()
|
||||
const {data ,status } = useGetUsers()
|
||||
const [t] = useTranslation()
|
||||
const navigate = useNavigate()
|
||||
const totalRows = data?.meta?.total;
|
||||
|
||||
return (
|
||||
// Pass Status to Layout
|
||||
<DashBody status={status as QueryStatusEnum} >
|
||||
|
||||
<DashHeader showAddButton={false} title={'users'}>
|
||||
<div className='RightSide d-flex gap-2 align-center '>
|
||||
<SearchField searchBy={"name"} />
|
||||
|
||||
{/* <AddButton onClick={()=>navigate('/users/add')}></AddButton> */}
|
||||
</div>
|
||||
</DashHeader>
|
||||
<LyTable
|
||||
data={data?.data}
|
||||
isLoading={false}
|
||||
columns={column}
|
||||
total={totalRows}
|
||||
is_pagination={true}
|
||||
/>
|
||||
|
||||
</DashBody>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page
|
||||
|
||||
42
src/Pages/Users/SendNotifcation/View/AddForm.tsx
Normal file
42
src/Pages/Users/SendNotifcation/View/AddForm.tsx
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
import { Col, Row } from 'reactstrap';
|
||||
import ValidationField from '../../../../Components/ValidationField/ValidationField';
|
||||
|
||||
function Form() {
|
||||
const type = [{ lable: "other", value: "other" },{ lable: "product", value: "product"},{ lable: "order", value: "order" }]
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
||||
<Col>
|
||||
<ValidationField name="body_en" />
|
||||
<ValidationField name="body_ar" />
|
||||
<ValidationField name="body_de" />
|
||||
{/* <ValidationField name="meta" /> */}
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="title_en" />
|
||||
<ValidationField name="title_ar" />
|
||||
<ValidationField name="title_de" />
|
||||
|
||||
{/* <ValidationField name="type" type="Select" option={type} /> */}
|
||||
|
||||
|
||||
|
||||
|
||||
</Col>
|
||||
|
||||
|
||||
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
||||
|
||||
|
||||
|
||||
79
src/Pages/Users/SendNotifcation/View/AddPage.tsx
Normal file
79
src/Pages/Users/SendNotifcation/View/AddPage.tsx
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { getInitialValuesForAdd as getInitialValues, getValidationSchema, getDataToSend } from '../formUtil'
|
||||
import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs'
|
||||
import 'react-tabs/style/react-tabs.css';
|
||||
import { MdLanguage } from 'react-icons/md'
|
||||
import ViewPage from '../../../../Layout/Dashboard/ViewPage';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useNavigateOnSuccess from '../../../../Hooks/useNavigateOnSuccess';
|
||||
import { useAddUsers } from '../../../../api/users';
|
||||
import Form from './AddForm';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useAddNotification } from '../../../../api/notification';
|
||||
|
||||
const AddPage = () => {
|
||||
|
||||
|
||||
const { mutate, isLoading, isSuccess } = useAddNotification()
|
||||
const {id} = useParams()
|
||||
const handleSubmit = (values: any) => {
|
||||
|
||||
const body = {
|
||||
en: values.body_en,
|
||||
ar: values.body_ar,
|
||||
du: values.body_de
|
||||
}
|
||||
const meta = {}
|
||||
const title = {
|
||||
en: values.title_en,
|
||||
ar: values.title_ar,
|
||||
du: values.title_de
|
||||
}
|
||||
const dataToSend = {
|
||||
body: JSON.stringify(body),
|
||||
meta: JSON.stringify(meta),
|
||||
title:JSON.stringify(title),
|
||||
user_ids: [id],
|
||||
type: "other",
|
||||
|
||||
};
|
||||
|
||||
|
||||
mutate(dataToSend);
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useNavigateOnSuccess(isSuccess, '/users')
|
||||
|
||||
|
||||
|
||||
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
|
||||
|
||||
|
||||
return (
|
||||
<div className='ViewPage'>
|
||||
|
||||
<ViewPage {...ViewProps}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("BasicInfo")}</h6></div></Tab>
|
||||
|
||||
|
||||
|
||||
</TabList>
|
||||
<TabBody >
|
||||
<div className=" mt-4"><Form /></div>
|
||||
</TabBody>
|
||||
|
||||
</Tabs>
|
||||
</ViewPage>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default AddPage
|
||||
73
src/Pages/Users/SendNotifcation/formUtil.ts
Normal file
73
src/Pages/Users/SendNotifcation/formUtil.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
|
||||
import * as Yup from "yup";
|
||||
import { buildFormData } from "../../../api/helper/buildFormData";
|
||||
import moment from 'moment';
|
||||
import * as dayjs from 'dayjs'
|
||||
|
||||
|
||||
export const getInitialValues = (objectToEdit: any | null = null): any => {
|
||||
//@ts-ignore
|
||||
return {
|
||||
id: objectToEdit?.id ,
|
||||
name: objectToEdit?.name ,
|
||||
email: objectToEdit?.email ,
|
||||
type: objectToEdit?.type ,
|
||||
avatar: objectToEdit?.avatar ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getInitialValuesForAdd = (objectToEdit: any | null = null): any => {
|
||||
return {
|
||||
body_en: "" ,
|
||||
body_ar: "" ,
|
||||
body_de: "" ,
|
||||
// meta: "" ,
|
||||
title_en: "" ,
|
||||
title_ar: "" ,
|
||||
title_de: "" ,
|
||||
user_ids:[],
|
||||
// type: "" ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any> => {
|
||||
// Validate input
|
||||
return Yup.object().shape({
|
||||
body_en: Yup.string().required('Required'),
|
||||
body_ar: Yup.string().required('Required'),
|
||||
body_de: Yup.string().required('Required'),
|
||||
// meta: Yup.string().required('Required'),
|
||||
|
||||
title_en: Yup.string().required('Required'),
|
||||
title_ar: Yup.string().required('Required'),
|
||||
title_de: Yup.string().required('Required'),
|
||||
// type: Yup.string().required('Required'),
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const getDataToSend = (values: any): FormData => {
|
||||
const data = { ...values };
|
||||
|
||||
|
||||
const formData = new FormData();
|
||||
buildFormData(formData, data);
|
||||
return formData;
|
||||
};
|
||||
|
||||
export const ChangeDataToPrint = (data: any) => {
|
||||
|
||||
let new_array = data
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
new_array[i]['status'] = !data[i]['deleted_at'] ? 'available' : 'unavailable'
|
||||
delete new_array[i]['deleted_at']
|
||||
}
|
||||
return new_array
|
||||
}
|
||||
31
src/Pages/Users/View/AddForm.tsx
Normal file
31
src/Pages/Users/View/AddForm.tsx
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
import { Col, Row } from 'reactstrap';
|
||||
import ValidationField from '../../../Components/ValidationField/ValidationField';
|
||||
|
||||
function Form() {
|
||||
|
||||
return (
|
||||
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
||||
<Col>
|
||||
<ValidationField name="name" />
|
||||
<ValidationField name="avatar" type="File" />
|
||||
|
||||
|
||||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="type" />
|
||||
<ValidationField name="email" />
|
||||
|
||||
</Col>
|
||||
|
||||
|
||||
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
|
||||
export default Form
|
||||
|
||||
|
||||
|
||||
|
||||
57
src/Pages/Users/View/AddPage.tsx
Normal file
57
src/Pages/Users/View/AddPage.tsx
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
import React, { useEffect, useState } from 'react'
|
||||
import { getInitialValuesForAdd as getInitialValues, getValidationSchema, getDataToSend } from '../formUtil'
|
||||
import { Tab, TabList, TabPanel as TabBody, Tabs } from 'react-tabs'
|
||||
import 'react-tabs/style/react-tabs.css';
|
||||
import { MdLanguage } from 'react-icons/md'
|
||||
import ViewPage from '../../../Layout/Dashboard/ViewPage';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
|
||||
import { useAddUsers } from '../../../api/users';
|
||||
import Form from './AddForm';
|
||||
|
||||
const AddPage = () => {
|
||||
|
||||
|
||||
const { mutate, isLoading, isSuccess } = useAddUsers()
|
||||
const handleSubmit = (values: any) => {
|
||||
|
||||
|
||||
mutate(values)
|
||||
|
||||
};
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useNavigateOnSuccess(isSuccess, '/users')
|
||||
|
||||
|
||||
|
||||
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
|
||||
|
||||
|
||||
return (
|
||||
<div className='ViewPage'>
|
||||
|
||||
<ViewPage {...ViewProps}>
|
||||
<Tabs>
|
||||
<TabList>
|
||||
<Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("BasicInfo")}</h6></div></Tab>
|
||||
|
||||
|
||||
|
||||
</TabList>
|
||||
<TabBody >
|
||||
<div className=" mt-4"><Form /></div>
|
||||
</TabBody>
|
||||
|
||||
</Tabs>
|
||||
</ViewPage>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default AddPage
|
||||
60
src/Pages/Users/formUtil.ts
Normal file
60
src/Pages/Users/formUtil.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
import * as Yup from "yup";
|
||||
import { buildFormData } from "../../api/helper/buildFormData";
|
||||
import moment from 'moment';
|
||||
import * as dayjs from 'dayjs'
|
||||
|
||||
|
||||
export const getInitialValues = (objectToEdit: any | null = null): any => {
|
||||
//@ts-ignore
|
||||
return {
|
||||
id: objectToEdit?.id ,
|
||||
name: objectToEdit?.name ,
|
||||
email: objectToEdit?.email ,
|
||||
type: objectToEdit?.type ,
|
||||
avatar: objectToEdit?.avatar ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getInitialValuesForAdd = (objectToEdit: any | null = null): any => {
|
||||
return {
|
||||
name: null ,
|
||||
email: null ,
|
||||
type: null ,
|
||||
avatar: null ,
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any> => {
|
||||
// Validate input
|
||||
return Yup.object().shape({
|
||||
name: Yup.string().required('Required'),
|
||||
email: Yup.string().required('Required'),
|
||||
type: Yup.string().required('Required'),
|
||||
avatar: Yup.string().required('Required'),
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const getDataToSend = (values: any): FormData => {
|
||||
const data = { ...values };
|
||||
|
||||
|
||||
const formData = new FormData();
|
||||
buildFormData(formData, data);
|
||||
return formData;
|
||||
};
|
||||
|
||||
export const ChangeDataToPrint = (data: any) => {
|
||||
|
||||
let new_array = data
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
new_array[i]['status'] = !data[i]['deleted_at'] ? 'available' : 'unavailable'
|
||||
delete new_array[i]['deleted_at']
|
||||
}
|
||||
return new_array
|
||||
}
|
||||
99
src/Pages/Users/useTableColumns.tsx
Normal file
99
src/Pages/Users/useTableColumns.tsx
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
|
||||
import React, { useMemo } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Actions from "../../Components/Ui/tables/Actions";
|
||||
import ColumnsImage from "../../Components/Columns/ColumnsImage";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDeleteUsers, useUpdateUsers } from "../../api/users";
|
||||
import { Switch } from "antd";
|
||||
import { MdEmail } from "react-icons/md";
|
||||
import { useModalState } from "../../zustand/Modal";
|
||||
|
||||
|
||||
const useTableColumns: any = () => {
|
||||
const [t] = useTranslation();
|
||||
const deleteMutation = useDeleteUsers()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const { mutate: update_status } = useUpdateUsers("put")
|
||||
const onChange = (checked: boolean, row: any) => {
|
||||
console.log(`switch to ${checked}`);
|
||||
update_status({
|
||||
id: row.id,
|
||||
status: checked ? "active" : "suspended"
|
||||
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
return useMemo(
|
||||
() => [
|
||||
|
||||
|
||||
{
|
||||
name: t("avatar"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => {
|
||||
let str = row?.avatar;
|
||||
str = str?.replace(`public`, "/storage") ?? "";
|
||||
return <ColumnsImage src={str} />
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
name: t("name"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.name
|
||||
},
|
||||
{
|
||||
name: t("email"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.email
|
||||
},
|
||||
{
|
||||
name: t("type"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => row?.type
|
||||
},
|
||||
{
|
||||
name: t("status"),
|
||||
sortable: false,
|
||||
center: "true",
|
||||
cell: (row: any) => {
|
||||
let status = row?.status;
|
||||
return <Switch checked={status === "active"} onChange={(value: any) => onChange(value, row)} />;
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
{
|
||||
name: "#",
|
||||
sortable: false,
|
||||
center: true,
|
||||
cell: (row: any) => (
|
||||
<Actions
|
||||
objectToEdit={row}
|
||||
showEdit={false}
|
||||
onEdit={() => navigate(`/users/${row.id}`)}
|
||||
showView={false}
|
||||
// onDelete={() => deleteMutation.mutate({ id: row.id })}
|
||||
showDelete={false}
|
||||
>
|
||||
<MdEmail onClick={() => navigate(`/users/${row.id}`)} className="cursor-pointer m-2" size={25} />
|
||||
|
||||
</Actions>
|
||||
),
|
||||
},
|
||||
|
||||
],
|
||||
[t]
|
||||
);
|
||||
};
|
||||
|
||||
export default useTableColumns;
|
||||
|
||||
|
|
@ -28,7 +28,7 @@ function Form() {
|
|||
</Col>
|
||||
<Col>
|
||||
<ValidationField name="admin_note" />
|
||||
<ValidationField name="deliviration_estimated_time" Format="YYYY-MM-DD HH:MM:SS" type='Date' />
|
||||
<ValidationField name="deliviration_estimated_time" Format="YYYY/MM/DD" type='Date' />
|
||||
|
||||
</Col>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,12 @@ const EditPage = () => {
|
|||
const { id } = useParams();
|
||||
const { data, isLoading } = useGetOneOrder({id: id })
|
||||
const handleSubmit = (values:any)=>{
|
||||
return mutate(values);
|
||||
|
||||
console.log(values?.deliviration_estimated_time?.format('YYYY-MM-DD HH:mm:ss'));
|
||||
return mutate({
|
||||
...values,
|
||||
deliviration_estimated_time:values?.deliviration_estimated_time?.format('YYYY-MM-DD HH:mm:ss')
|
||||
});
|
||||
}
|
||||
|
||||
useNavigateOnSuccess(isSuccess , '/order')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ReactNode } from "react";
|
||||
|
||||
// Icons Import
|
||||
import { FaCartArrowDown, FaHome, FaProductHunt, FaRegImages } from "react-icons/fa"
|
||||
import { FaCartArrowDown, FaHome, FaProductHunt, FaRegImages, FaUser } from "react-icons/fa"
|
||||
import { BiSolidCategory } from "react-icons/bi";
|
||||
import { BiSolidCoupon } from "react-icons/bi";
|
||||
|
||||
|
|
@ -30,6 +30,15 @@ import SliderPage from "./Pages/Slider/Page";
|
|||
import AddSliderPage from "./Pages/Slider/View/AddPage";
|
||||
import EditSlider from "./Pages/Slider/View/EditPage";
|
||||
|
||||
import UsersPage from "./Pages/Users/Page";
|
||||
import AddUsersPage from "./Pages/Users/View/AddPage";
|
||||
|
||||
import AddUsersNotifactionPage from "./Pages/Users/SendNotifcation/View/AddPage";
|
||||
|
||||
import NotificationPage from "./Pages/Notifcation/Page";
|
||||
import AddNotificationPage from "./Pages/Notifcation/View/AddPage";
|
||||
import { MdEmail } from "react-icons/md";
|
||||
|
||||
|
||||
|
||||
interface RoutesLinksType {
|
||||
|
|
@ -143,7 +152,35 @@ export const RoutesLinks: RoutesLinksType[] = [
|
|||
hidden:true
|
||||
},
|
||||
|
||||
{
|
||||
name: "users",
|
||||
element: <UsersPage />,
|
||||
icon: <FaUser />,
|
||||
href: "/users",
|
||||
},
|
||||
{
|
||||
href: "/users/add",
|
||||
element: <AddUsersPage />,
|
||||
hidden:true
|
||||
},
|
||||
|
||||
{
|
||||
href: "/users/:id",
|
||||
element: <AddUsersNotifactionPage />,
|
||||
hidden:true
|
||||
}
|
||||
|
||||
, {
|
||||
name: "notification",
|
||||
element: <NotificationPage />,
|
||||
icon: <MdEmail />,
|
||||
href: "/notification",
|
||||
},
|
||||
{
|
||||
href: "/notification/add",
|
||||
element: <AddNotificationPage />,
|
||||
hidden:true
|
||||
},
|
||||
|
||||
|
||||
]
|
||||
|
|
@ -26,7 +26,7 @@ function useAddMutation(key: string, url: string): UseMutationResult<AxiosRespon
|
|||
{
|
||||
onSuccess: (data) => {
|
||||
queryClient.invalidateQueries([key]);
|
||||
toast.success(data.message || t("Add Successful"));
|
||||
toast.success(data.message || t("added_uccessful"));
|
||||
},
|
||||
onError: (error:any) => {
|
||||
const message = error?.response?.data?.message || t("failed_to_add_data");
|
||||
|
|
|
|||
23
src/api/notification.ts
Normal file
23
src/api/notification.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
import useGetQueryPagination from "./helper/ueGetPagination";
|
||||
import useAddMutation from "./helper/useAddMutation"
|
||||
import useDeleteMutation from "./helper/useDeleteMutation"
|
||||
import useGetOneQuery from "./helper/useGetOneQuery";
|
||||
|
||||
const API = {
|
||||
ADD: `notification`,
|
||||
GET_ALL: `notification`,
|
||||
DELETE: `notification`,
|
||||
|
||||
};
|
||||
const KEY = "notification"
|
||||
|
||||
|
||||
export const useGetNotification = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params);
|
||||
export const useGetOnenotification = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params);
|
||||
|
||||
export const useAddNotification = () => useAddMutation(KEY, API.ADD);
|
||||
|
||||
export const useDeleteNotification = () =>useDeleteMutation(KEY, API.DELETE);
|
||||
|
||||
|
||||
|
|
@ -5,12 +5,13 @@ import useDeleteMutation from "./helper/useDeleteMutation"
|
|||
import useGetOneQuery from "./helper/useGetOneQuery";
|
||||
import useGetQuery from "./helper/useGetQuery"
|
||||
import useUpdateMutation from "./helper/useUpdateMutation";
|
||||
import useUpdateMutationById from "./helper/useUpdateMutationById";
|
||||
|
||||
const API = {
|
||||
ADD: `user`,
|
||||
GET_ALL: `user`,
|
||||
GET_ALL: `user?notOfType=admin`,
|
||||
DELETE: `user`,
|
||||
UPDATE: `user`,
|
||||
UPDATE: `user/updateStatus`,
|
||||
|
||||
};
|
||||
const KEY = "User"
|
||||
|
|
@ -20,6 +21,8 @@ export const useGetUsers = (params?:any) => useGetQueryPagination(KEY, API.GET_A
|
|||
export const useGetOneUser = (params?:any) => useGetOneQuery(KEY, API.GET_ALL,params);
|
||||
|
||||
export const useAddUsers = () => useAddMutation(KEY, API.ADD);
|
||||
export const useUpdateUsers = () => useUpdateMutation(KEY, API.UPDATE);
|
||||
export const useUpdateUsers = (method?:string) => useUpdateMutationById(KEY, API.UPDATE,true,method);
|
||||
|
||||
export const useDeleteUsers = () =>useDeleteMutation(KEY, API.DELETE);
|
||||
|
||||
|
||||
|
|
|
|||
69
src/lib/state mangment/dist/AuthState.js
vendored
69
src/lib/state mangment/dist/AuthState.js
vendored
|
|
@ -1,69 +0,0 @@
|
|||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
exports.__esModule = true;
|
||||
var zustand_1 = require("zustand");
|
||||
var AppKey_1 = require("../../config/AppKey");
|
||||
var useAuthState = zustand_1.create(function (set) {
|
||||
var storedUser = localStorage.getItem(AppKey_1.USER_KEY);
|
||||
var storedToken = localStorage.getItem(AppKey_1.TOKEN_KEY);
|
||||
var initialUser = (storedUser && storedUser !== 'undefined') ? JSON.parse(storedUser) : null;
|
||||
return {
|
||||
user: initialUser,
|
||||
isAuthenticated: !!storedToken,
|
||||
token: storedToken,
|
||||
login: function (userData) { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
console.log(userData);
|
||||
localStorage.setItem(AppKey_1.TOKEN_KEY, userData.token);
|
||||
localStorage.setItem(AppKey_1.USER_KEY, JSON.stringify(userData.admin));
|
||||
set(function (state) { return ({ user: userData.admin, isAuthenticated: true, token: userData.token }); });
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); },
|
||||
logout: function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
localStorage.removeItem(AppKey_1.TOKEN_KEY);
|
||||
localStorage.removeItem(AppKey_1.TOKEN_KEY_SOCKET);
|
||||
localStorage.removeItem(AppKey_1.USER_KEY);
|
||||
set(function (state) { return ({ user: null, isAuthenticated: false, token: null }); });
|
||||
return [2 /*return*/];
|
||||
});
|
||||
}); }
|
||||
};
|
||||
});
|
||||
exports["default"] = useAuthState;
|
||||
23
src/lib/state mangment/dist/LayoutPagestate.js
vendored
23
src/lib/state mangment/dist/LayoutPagestate.js
vendored
|
|
@ -1,23 +0,0 @@
|
|||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.usePageState = void 0;
|
||||
var zustand_1 = require("zustand");
|
||||
exports.usePageState = zustand_1.create(function (set) { return ({
|
||||
isOpenAddModel: false,
|
||||
isOpenEditModel: false,
|
||||
objectToEdit: null,
|
||||
isThemChanged: false,
|
||||
setThemChange: function () {
|
||||
return set(function (state) { return ({ isThemChanged: !state.isThemChanged }); });
|
||||
},
|
||||
setIsOpenAddModel: function () {
|
||||
return set(function (state) { return ({ isOpenAddModel: !state.isOpenAddModel }); });
|
||||
},
|
||||
setIsOpenEditModel: function () {
|
||||
return set(function (state) { return ({ isOpenEditModel: !state.isOpenEditModel }); });
|
||||
},
|
||||
CloseAllModal: function () {
|
||||
return set(function (state) { return ({ isOpenAddModel: false, isOpenEditModel: false }); });
|
||||
},
|
||||
setObjectToEdit: function (data) { return set(function () { return ({ objectToEdit: data }); }); }
|
||||
}); });
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.useCommonModelState = void 0;
|
||||
var zustand_1 = require("zustand");
|
||||
exports.useCommonModelState = zustand_1.create(function (set) { return ({
|
||||
isOpenBlock: false,
|
||||
isOpenGift: false,
|
||||
isOpenUnBlock: false,
|
||||
setIsopenBlock: function () {
|
||||
return set(function (state) { return ({ isOpenBlock: !state.isOpenBlock }); });
|
||||
},
|
||||
setIsopenUnBlock: function () {
|
||||
return set(function (state) { return ({ isOpenUnBlock: !state.isOpenUnBlock }); });
|
||||
},
|
||||
setIsopenGift: function () {
|
||||
return set(function (state) { return ({ isOpenGift: !state.isOpenGift }); });
|
||||
},
|
||||
setObjectId: function (data) {
|
||||
return set(function (state) { return ({ objectID: data }); });
|
||||
},
|
||||
objectID: 0
|
||||
}); });
|
||||
|
|
@ -128,9 +128,22 @@
|
|||
"unique_error_names": "اسم فريد لكل سمة مطلوب",
|
||||
"deliviration_estimated_time": "الوقت المقدر للتسليم",
|
||||
"delivery_link": "رابط التسليم",
|
||||
"failed_to_add_data": "فشل في إضافة البيانات",
|
||||
"delete_are_you_sure": "هل أنت متأكد أنك تريد الحذف؟",
|
||||
"yes_delete_it": "نعم، احذفه"
|
||||
"yes_delete_it": "نعم، احذفه",
|
||||
"notification": "إشعار",
|
||||
"users": "المستخدمون",
|
||||
"body": "جسم",
|
||||
"body_en": "الجسم (الإنجليزية)",
|
||||
"body_ar": "الجسم (العربية)",
|
||||
"body_de": "الجسم (الألمانية)",
|
||||
"title_en": "العنوان (الإنجليزية)",
|
||||
"title_ar": "العنوان (العربية)",
|
||||
"title_de": "العنوان (الألمانية)",
|
||||
"avatar": "الصورة الرمزية",
|
||||
"added_successful": "تمت الإضافة بنجاح",
|
||||
"failed_to_add_data": "فشلت عملية الإضافة",
|
||||
"deleted_successfully": "تم الحذف بنجاح",
|
||||
"updated_successfully": "تم التحديث بنجاح"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -124,10 +124,23 @@
|
|||
"unique_error_names": "Einzigartiger Name für jede Eigenschaft ist erforderlich",
|
||||
"deliviration_estimated_time": "Voraussichtliche Lieferzeit",
|
||||
"delivery_link": "Lieferlink",
|
||||
"failed_to_add_data": "Fehler beim Hinzufügen von Daten",
|
||||
"delete_are_you_sure": "Möchten Sie wirklich löschen?",
|
||||
"yes_delete_it": "Ja, löschen",
|
||||
"cancel": "Abbrechen"
|
||||
"cancel": "Abbrechen",
|
||||
"notification": "Benachrichtigung",
|
||||
"users": "Benutzer",
|
||||
"body": "Körper",
|
||||
"body_en": "Körper (Englisch)",
|
||||
"body_ar": "Körper (Arabisch)",
|
||||
"body_de": "Körper (Deutsch)",
|
||||
"title_en": "Titel (Englisch)",
|
||||
"title_ar": "Titel (Arabisch)",
|
||||
"title_de": "Titel (Deutsch)",
|
||||
"avatar": "Avatar",
|
||||
"added_successful": "Erfolgreich hinzugefügt",
|
||||
"failed_to_add_data": "Daten konnten nicht hinzugefügt werden",
|
||||
"deleted_successfully": "Erfolgreich gelöscht",
|
||||
"updated_successfully": "Erfolgreich aktualisiert"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -124,11 +124,24 @@
|
|||
"unique_error_names": "Unique name for each attribute is required",
|
||||
"deliviration_estimated_time": "Delivery Estimated Time",
|
||||
"delivery_link": "Delivery Link",
|
||||
"failed_to_add_data": "Failed to add data",
|
||||
"delete_are_you_sure": "Are you sure you want to delete?",
|
||||
"yes_delete_it": "Yes, delete it",
|
||||
"cancel": "Cancel",
|
||||
"required_error":"required_error"
|
||||
"required_error":"required_error",
|
||||
"notification": "Notification",
|
||||
"users": "Users",
|
||||
"body": "Body",
|
||||
"body_en": "Body (English)",
|
||||
"body_ar": "Body (Arabic)",
|
||||
"body_de": "Body (German)",
|
||||
"title_en": "Title (English)",
|
||||
"title_ar": "Title (Arabic)",
|
||||
"title_de": "Title (German)",
|
||||
"avatar": "Avatar",
|
||||
"added_successful": "added successful",
|
||||
"failed_to_add_data": "Failed to add data",
|
||||
"deleted_successfully": "deleted successfully",
|
||||
"updated_successfully": "updated successfully"
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
BasicInfo
|
||||
attributes
|
||||
Add New Attribute
|
||||
{
|
||||
added_uccessful
|
||||
failed_to_add_data
|
||||
deleted_successfully
|
||||
updated_successfully
|
||||
}
|
||||
5
src/utils/Array/filterUndefinedAndEmpty.ts
Normal file
5
src/utils/Array/filterUndefinedAndEmpty.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
const filterUndefinedAndEmpty = (array:any) => {
|
||||
return array.filter((data:any) => data !== undefined && Object.keys(data).length !== 0);
|
||||
};
|
||||
|
||||
export default filterUndefinedAndEmpty;
|
||||
15
src/zustand/Modal.ts
Normal file
15
src/zustand/Modal.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import {create} from 'zustand'
|
||||
|
||||
interface ModalState {
|
||||
isOpen: boolean;
|
||||
setIsOpen: (value:boolean) => void;
|
||||
|
||||
}
|
||||
|
||||
|
||||
export const useModalState = create<ModalState>((set) => ({
|
||||
isOpen: false,
|
||||
setIsOpen: () =>
|
||||
set((state) => ({ isOpen: !state.isOpen })),
|
||||
|
||||
}));
|
||||
Loading…
Reference in New Issue
Block a user