This commit is contained in:
KarimAldeen 2024-03-05 11:35:35 +03:00
parent 7fa5a79391
commit c47ea73fdb
114 changed files with 2067 additions and 2860 deletions

View File

@ -3,7 +3,7 @@ import React from 'react'
import useFormField from '../../../Hooks/useFormField';
import dayjs from 'dayjs';
const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder ,className}: any) => {
const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder ,className,Format}: any) => {
const { errorMsg, isError, t, formik } = useFormField(name, props)
const onCalendarChange = (value: any) => {
@ -15,7 +15,7 @@ const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder
<div className='ValidationField'>
<label htmlFor={name} className="text">
{t(`${label}`)}
{t(`${label ? label : name}`)}
</label>
<Form.Item
hasFeedback
@ -31,6 +31,7 @@ const Date = ({ name, label,picker="date" ,isDisabled,props,onChange,placeholder
size="large"
onChange={onChange || onCalendarChange}
disabled={isDisabled}
format={Format ?? ""}
/>

View File

@ -1,11 +1,13 @@
import { Form, Select } from 'antd';
import React, { useEffect, useState } from 'react';
import useFormField from '../../../Hooks/useFormField';
import { useNavigate } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, isMulti, onChange, className, props }: any) => {
const { errorMsg, isError, t, formik } = useFormField(name, props);
const [searchQuery, setSearchQuery] = useState<string>('');
const location = useLocation()
const navigate = useNavigate()
useEffect(() => {
const searchParams = new URLSearchParams(window?.location?.search);
@ -17,9 +19,16 @@ const SearchField = ({ name, label, placeholder, isDisabled, searchBy, option, i
const SelecthandleChange = (value: { value: string; label: React.ReactNode }) => {
formik?.setFieldValue(name, value);
console.log(value);
};
const SearchHandleChange = (value:any) => {
if (value || value !== "") {
navigate(`${window?.location?.pathname}?${searchBy}=${value}`, { replace: true });
} else {
const params = new URLSearchParams(location.search);
params.delete(searchBy ?? "search");
navigate(`${window?.location.pathname}?${params.toString()}`, { replace: true });
}
};

View File

@ -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}

View File

@ -33,7 +33,7 @@
label?: string;
className?: string;
isDisabled?: boolean;
onChange?: (value: any) => void;
onChange?:any;
dir?:'ltr' | "rtl";
option: any[];
isMulti?: boolean;
@ -75,6 +75,8 @@
onChange?: (value: any) => void;
dir?:'ltr' | "rtl"
picker?: "data" | "week" | "month" | "quarter" | "year";
Format?: "YYYY/MM/DD" | "MM/DD" | "YYYY/MM" | "YYYY-MM-DD HH:mm:ss.SSS" | "YYYY-MM-DD HH:MM:SS";
}

View File

@ -0,0 +1,13 @@
export async function fetchImage(imageUrl:any) {
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`);
}
const blob = await response.blob();
return new File([blob], 'image.png', { type: 'image/png' });
} catch (error) {
console.error('Error fetching image:', error);
return null;
}
}

View File

@ -1,9 +1,11 @@
const useFormatToSelect = (Data : any) => {
const format = (data :any) => {
if (!data) return [];
const language = localStorage.getItem("language") ?? "en";
return data.map((item :any) => ({
value: item?.id,
label: item?.name,
label: item?.name[language],
}));
};

View File

@ -5,24 +5,33 @@ import { useTranslation } from 'react-i18next';
import { useLocation, useNavigate, useSearchParams } from 'react-router-dom';
const { Search } = Input;
const SearchField = ({searchBy } : any) => {
const SearchField = ({ searchBy }: any) => {
const navigate = useNavigate()
const [searchParams,] = useSearchParams();
const location =useLocation()
const {t} = useTranslation();
console.log(searchBy,"searchBy");
const location = useLocation()
const { t } = useTranslation();
const [searchValue, setSearchValue] = useState(searchParams.get('search')|| "");
const [searchValue, setSearchValue] = useState(searchParams.get(searchBy ?? "search") || "");
const onSearch: SearchProps['onSearch'] = (value, _e, info) => {
// console.log(value);
if (value || value !== "") {
navigate(`${location?.pathname}?${searchBy ?? "search"}=${value}`, { replace: true });
} else {
const params = new URLSearchParams(location.search);
params.delete(searchBy ?? "search");
navigate(`${location.pathname}?${params.toString()}`, { replace: true });
}
}
const onChange = (e :any) => {
setSearchValue(e.target.value);
const onChange = (e: any) => {
const value = e.target.value
setSearchValue(e.target.value);
if (value === "") {
const params = new URLSearchParams(location.search);
params.delete(searchBy ?? "search");
navigate(`${location.pathname}?${params.toString()}`, { replace: true });
}
}
@ -33,7 +42,7 @@ const SearchField = ({searchBy } : any) => {
allowClear
enterButton={t("search")}
size="middle"
placeholder={t("search")}
placeholder={t(searchBy ?? "search")}
onSearch={onSearch}
style={{ width: 250 }}
value={searchValue}

View File

@ -28,7 +28,7 @@ export const AttributeTabs: React.FC<AttributeTabsProps> = ({ tabKey }) => {
return (
<>
<h5>{t("Attributes")} {tabKey}</h5>
<h5>{t("Attribute")} {tabKey}</h5>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<FormItem

View File

@ -33,10 +33,8 @@ const File = ({ tabKey}:any) => {
};
return (
<div className="ValidationField">
<label className="text">
<label className="text w-100">
{t(`main_photo`)}
</label>
<Upload
listType="picture"
maxCount={1}
@ -52,6 +50,9 @@ const File = ({ tabKey}:any) => {
</Button>
</Upload>
</label>

View File

@ -13,15 +13,15 @@ const SelectField = ({tabKey}: any) => {
const onChange = (value:any) => {
formik.setFieldValue(Formikname,value)
console.log(value);
console.log(formik?.errors,"errors");
}
const Data = [{label: "color",value :"color"},{label: "text",value :"text"},{label: "image",value :"image"}]
return (
<div className='ValidationField'>
<label className="text">
<label className="text w-100">
{t(`${"type"}`)}
</label>
<Select
placeholder={t(`${"type"}`)}
options={Data}
@ -30,10 +30,10 @@ const SelectField = ({tabKey}: any) => {
defaultValue={FormikValue}
allowClear
onChange={onChange}
/>
</label>
</div>
)
}

View File

@ -6,56 +6,103 @@ import { toast } from 'react-toastify';
import { FormikValues, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { AttributeTabs } from './AttributeTabs';
import { AttributeTabs as AddAttributeTabs} from '../../Add/AttributeTab/AttributeTabs';
const { TabPane } = Tabs;
const initialItemShape: any = {
label: 'Attribute 1',
key: '1',
closable: true,
};
export const TabsContainer: React.FC = () => {
const [activeKey, setActiveKey] = useState('1');
const [items, setItems] = useState([initialItemShape]);
const { setFieldValue } = useFormikContext();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const [width, setWidth] = useState(window.innerWidth);
const [t] = useTranslation()
const initialItemShape: any = {
label: `${t(`Attribute`)} 1`,
key: '1',
closable: true,
};
const varianCount = values?.Attribute?.slice(1)?.map((item:any,index:any)=>{
return {
label: `${t(`Attribute`)}`+ `${index+1}`,
key: index+1,
closable: true,
}
})?? initialItemShape
const [items, setItems] = useState(varianCount ?? [initialItemShape]); // Ensure items is always an array
useEffect(() => {
// Set the active key to the first tab key when the component mounts or items change
if (items.length > 0) {
setActiveKey(items[0].key);
}
}, []);
const findFirstMissingKey = (itemKeys:string[]) => {
const keysAsNumbers = itemKeys.map(Number); // Convert strings to numbers
for (let i = 1; i <= keysAsNumbers.length + 1; i++) {
if (!keysAsNumbers.includes(i)) {
return i;
}
}
};
const [nextKey, setNextKey] = useState<any>(items.map((item: any) => `${item.key}`)); // Initialize the key counter to the length of items + 1
useEffect(() => {
const keys = items.map((item: any) => `${item.key}`);
setNextKey(findFirstMissingKey(keys))
}, [items]);
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `Attribute ${newKey}`, closable: true }]);
const newKey = `${nextKey}`;
setItems([...items, { key: newKey, label: `${t(`Attribute`)} ${newKey}`, closable: true ,Add:true}]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item) => item.key === targetKey);
const targetItem = items.find((item:any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `Attribute ${newKey}` };
const newKey = `${nextKey}`;
const newItem = { ...targetItem, key: newKey, label: `${t(`Attribute`)} ${newKey}`,Add:true };
setItems([...items, newItem]);
setActiveKey(newKey);
setNextKey((prevKey : any) => prevKey + 1);
const originalValues = values?.Attribute?.[targetKey];
setFieldValue(`Attribute.${newKey}`, originalValues);
setFieldValue(`Attribute.${newKey}`, {...originalValues,id:null});
}
};
const [removedAttribute, setRemovedAttribute] = useState<string[]>([]);
useEffect(() => {
setFieldValue(`removedAttribute`, removedAttribute);
}, [removedAttribute]);
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item) => item.key !== targetKey);
if (newItems.length > 0) {
const newItems = items.filter((item:any) => item.key !== targetKey);
const removedItem = values?.Attribute[targetKey] as any;
if (removedItem?.id) {
setRemovedAttribute((prevRemovedAttribute) => [...prevRemovedAttribute, removedItem.id]);
}
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
setFieldValue(`Attribute.${targetKey}`, undefined);
} else {
toast.error("Cannot close the last tab");
}
};
useEffect(() => {
@ -72,31 +119,27 @@ useEffect(() => {
const tabPosition = width > 1000 ? 'left' : 'top';
return (
<Tabs
<div className=''>
<Tabs
type="editable-card"
onChange={setActiveKey}
activeKey={activeKey}
onEdit={(targetKey:any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
onEdit={(targetKey: any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
tabPosition={tabPosition}
items={items.map((item: any) => ({
label: <Space>{t(`${item.label}`)} <CopyOutlined onClick={() => handleDuplicate(item.key)} /></Space>,
// children: item?.Add ? <AddAttributeTabs tabKey={item.key} /> : <AttributeTabs tabKey={item.key} />,
children: <AddAttributeTabs tabKey={item.key}/>,
key: item.key,
closable: item.closable,
}))}
>
{items.map((item :any) =>{
return (
<TabPane
key={item?.key}
tab={
<Space>
{t(`${item.label}`)}
<CopyOutlined onClick={() => handleDuplicate(item.key)} />
</Space>
}
closable={item.closable}
>
<AttributeTabs tabKey={item?.key} />
</TabPane>
)
})}
</Tabs>
{ items.length === 0 && (
<h6 className='AddNewTabText'>{t("Add New Attribute")}</h6>
)}
</div>
);
};

View File

@ -1,5 +1,5 @@
// AttributeValueTabs.tsx
import React from 'react';
import React, { useEffect, useState } from 'react';
import { Col, Row } from 'reactstrap';
import { FormItem } from './Field/FormItem';
import { useFormikContext, FormikValues } from 'formik';
@ -8,13 +8,14 @@ import { useTranslation } from 'react-i18next';
interface AttributeValueTabsProps {
tabKey: string;
parentKey:string
parentKey: string
}
export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKey,tabKey }) => {
export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKey, tabKey }) => {
const { t } = useTranslation();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const [valuesChanged, setvaluesChanged] = useState(values?.Attribute[parentKey]?.type)
const handleFieldChange = (fieldName: string) => (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | any
@ -23,13 +24,18 @@ export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKe
};
const FormikName = (FormikFieldname: any) => values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.[FormikFieldname];
useEffect(() => {
setvaluesChanged(values?.Attribute[parentKey]?.type)
}, [values?.Attribute[parentKey]?.type])
return (
<>
<h5>{t("Values")} {tabKey}</h5>
<h5>{t("Value")} {tabKey}</h5>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
{valuesChanged !== "color" ?
<>
<FormItem
label={t(`value_en`)}
value={FormikName("value_en")}
@ -40,10 +46,26 @@ export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKe
value={FormikName("value_ar")}
onChange={handleFieldChange('value_ar')}
/>
</>
:
<>
<FormItem
label={t(`Value`)}
value={FormikName("value_en")}
onChange={handleFieldChange('value_en')}
/>
</>
}
</Col>
<Col>
{valuesChanged !== "color" ?
<>
<FormItem
label={t(`value_de`)}
@ -51,6 +73,16 @@ export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKe
onChange={handleFieldChange('value_de')}
/>
</>
:
<>
</>
}
<File parentKey={parentKey} tabKey={tabKey} />
</Col>

View File

@ -10,8 +10,8 @@ import { useFormikContext } from 'formik';
const File = ({ parentKey,tabKey}:any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `Attribute.[${parentKey}].AttributeValue[${tabKey}].${"main_photo"}`;
const imageUrl = formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["main_photo"] ? URL.createObjectURL(formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["main_photo"]) : "" ;
const name = `Attribute.[${parentKey}].AttributeValue[${tabKey}].${"image"}`;
const imageUrl = formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["image"] ? URL.createObjectURL(formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["image"]) : "" ;
const fileList: UploadFile[] = [
@ -34,7 +34,7 @@ const File = ({ parentKey,tabKey}:any) => {
return (
<div className="ValidationField">
<label className="text">
{t(`main_photo`)}
{t(`image`)}
</label>
<Upload

View File

@ -0,0 +1,18 @@
import { ColorPicker } from 'antd'
import React from 'react'
import { Label } from 'reactstrap'
const Hex = ({ label, value, onChange }:any) => {
return (
<Label className="tabstext">
{label}
<ColorPicker onChange={onChange} defaultValue={value} size="small" />
</Label>
)
}
export default Hex

View File

@ -9,76 +9,92 @@ import { AttributeValueTabs } from './AttributeTabs';
const { TabPane } = Tabs;
const initialItemShape: any = {
label: 'Value 1',
key: '1',
closable: true,
};
export const TabsContainer= ({parentKey}:any) => {
const [activeKey, setActiveKey] = useState('1');
const [t] = useTranslation()
const { setFieldValue } = useFormikContext();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const [width, setWidth] = useState(window.innerWidth);
const { values } = formikContext;
const initialItemShape: any = {
label: `${t(`Value`)} 1`,
key: '1',
closable: true,
};
const varianCount = values?.Attribute[parentKey]?.AttributeValue?.slice(1)?.map((item:any,index:any)=>{
return {
label: `${t(`Value`)}`+ `${index+1}`,
key: index+1,
key: `${index+1}`,
closable: true,
}
})?? initialItemShape
const [items, setItems] = useState(Array.isArray(varianCount) ? varianCount : [initialItemShape]); // Ensure items is always an array
useEffect(() => {
if (items.length > 0) {
setActiveKey(items[0].key);
}
}, []);
const findFirstMissingKey = (itemKeys:string[]) => {
const keysAsNumbers = itemKeys.map(Number); // Convert strings to numbers
for (let i = 1; i <= keysAsNumbers.length + 1; i++) {
if (!keysAsNumbers.includes(i)) {
return i;
}
}
};
const [nextKey, setNextKey] = useState<any>(items.map((item: any) => `${item.key}`)); // Initialize the key counter to the length of items + 1
useEffect(() => {
const keys = items.map((item: any) => `${item.key}`);
setNextKey(findFirstMissingKey(keys))
}, [items]);
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `Value ${newKey}`, closable: true }]);
const newKey = `${nextKey}`;
setItems([...items, { key: newKey, label: `${t(`Value`)} ${newKey}`, closable: true }]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item:any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `Value ${newKey}` };
const newKey = `${nextKey}`;
const newItem = { ...targetItem, key: newKey, label: `${t(`Value`)} ${newKey}` };
setItems([...items, newItem]);
setActiveKey(newKey);
const originalValues = values?.Attribute?.[parentKey]?.AttributeValue?.[targetKey];
setFieldValue(`Attribute.${parentKey}.AttributeValue.${newKey}`, originalValues);
const originalValues = values?.Attribute[parentKey].AttributeValue[targetKey];
setFieldValue(`Attribute[${parentKey}].AttributeValue[${newKey}]`, originalValues);
}
};
const [removedAttributeValue, setremovedAttributeValue] = useState<string[]>([]);
useEffect(() => {
setFieldValue(`removedAttributeValue`, removedAttributeValue);
}, [removedAttributeValue]);
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item:any) => item.key !== targetKey);
if (newItems.length > 0) {
const newItems = items.filter((item:any) => item?.key !== targetKey);
console.log(newItems,"newItems",targetKey,"targetKey");
const removedItem = values?.Attribute[parentKey]?.AttributeValue[targetKey] as any;
if (removedItem?.id) {
console.log(removedItem?.id,"removedItem?.id");
setremovedAttributeValue((prevremovedAttributeValue) => [...prevremovedAttributeValue, removedItem.id]);
}
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
setFieldValue(`Attribute.${parentKey}.AttributeValue.${targetKey}`, undefined);
} else {
toast.error("Cannot close the last tab");
}
};
useEffect(() => {
const handleResize = () => {
setWidth(window.innerWidth);
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
const tabPosition ='top';
return (

View File

@ -5,31 +5,45 @@ 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 { BsInfoCircle } from 'react-icons/bs';
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
import { useAddCategories } from '../../../api/Categories';
import Form from './Add/AddForm';
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';
const AddcategoriesPage = () => {
const { setObjectToEdit, objectToEdit } = usePageState()
const {mutate , isLoading,isSuccess,data } = useAddCategories()
const {mutate:AddAttribute, isSuccess : isSuccessAttribute,data:AttributeData} = useAddAttribute()
const {isSuccess : isSuccessAttribute,data:AttributeData, mutateAsync} = useAddAttribute()
const {mutate:AddAttributeValue,isSuccess : isSuccessAttributeValue} = useAddAttributeValue()
const [Attribute , setAttribute] = useState<any[]>([])
const [AttributeValues , setAttributeValues] = useState<any[]>([])
const formik = useFormikContext()
const handleSubmit = (values:any)=>{
console.log(values,"values");
function isValid(){
values?.Attribute?.slice(1)?.forEach((item:any) => {
if (item && Object.keys(item).length > 0){
setAttribute((prevAddAttributeValue) => [...prevAddAttributeValue, item]);
}
});
setAttribute(values?.Attribute?.slice(1))
setAttributeValues(values?.Attribute?.slice(1)?.map((item:any)=>{
if (item && Object.keys(item).length > 0){
return item?.AttributeValue
}
}))
const CategoriesValues = {
name: {
en:values?.name_en,
@ -40,7 +54,92 @@ const AddcategoriesPage = () => {
photo:values?.photo,
}
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);
}
}
});
if (validationResults.every((result) => result)) {
isValid();
}
@ -53,10 +152,7 @@ const AddcategoriesPage = () => {
Attribute?.map((dataToSend:any , index:number)=>{
const Attribute = dataToSend
setAttributeValues((prev) => ([
...prev,
...Attribute?.AttributeValue,
]));
const NewAttribute = {
name:{
en:Attribute?.name_en,
@ -67,39 +163,67 @@ const AddcategoriesPage = () => {
category_id:categoryId,
}
AddAttribute(NewAttribute)
mutateAsync(NewAttribute).then((data)=>{
const AttributeId = (data as any )?.id ;
console.log(AttributeValues[0]?.slice(1),"AttributeValues");
AttributeValues[index]?.slice(1)?.map((dataToSend:any , index:number)=>{
const AttributeValue = dataToSend
const NewAttributeValues = {
value:{
en:AttributeValue?.value_en,
ar:AttributeValue?.value_ar,
de:AttributeValue?.value_de
},
image:AttributeValue?.main_photo,
attribute_id:AttributeId,
}
if (NewAttribute.type === "color") {
NewAttributeValues["value"] = {
en: AttributeValue?.value_en,
ar: AttributeValue?.value_en,
de: AttributeValue?.value_en
}
}
AddAttributeValue(NewAttributeValues)
})
})
})
}
},[isSuccess])
useEffect(()=>{
// useEffect(()=>{
if(isSuccessAttribute){
const AttributeId = (AttributeData as any )?.id ;
// if(isSuccessAttribute){
// const AttributeId = (AttributeData as any )?.id ;
AttributeValues?.slice(1)?.map((dataToSend:any , index:number)=>{
// 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)
// 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])
// }
// },[isSuccessAttribute])
const {t} = useTranslation();
useNavigateOnSuccess(isSuccessAttributeValue , '/categories' )
useNavigateOnSuccess(isSuccess , '/categories' )
useEffect(() => {

View File

@ -25,11 +25,10 @@ export const AttributeTabs: React.FC<AttributeTabsProps> = ({ tabKey }) => {
const FormikName = (FormikFieldname: any) => values?.Attribute[tabKey]?.[FormikFieldname];
console.log(values?.Attribute,"value");
return (
<>
<h5>{t("Attributes")} {tabKey}</h5>
<h5>{t("Attribute")} {tabKey}</h5>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<FormItem

View File

@ -13,8 +13,10 @@ export const FormItem: React.FC<FormItemProps> = ({ label, value, onChange ,type
return (
<>
<Label className="tabstext">{label}</Label>
<Input value={value} type={type} onChange={onChange} />
<Label className="tabstext w-100">
{label}
<Input className='w-100' value={value} type={type} onChange={onChange} />
</Label>
</>
);
};

View File

@ -18,10 +18,8 @@ const SelectField = ({tabKey}: any) => {
const Data = [{label: "color",value :"color"},{label: "text",value :"text"},{label: "image",value :"image"}]
return (
<div className='ValidationField'>
<label className="text">
<label className="text w-100">
{t(`${"type"}`)}
</label>
<Select
placeholder={t(`${"type"}`)}
options={Data}
@ -30,10 +28,10 @@ const SelectField = ({tabKey}: any) => {
defaultValue={FormikValue}
allowClear
onChange={onChange}
/>
</label>
</div>
)
}

View File

@ -6,14 +6,11 @@ import { toast } from 'react-toastify';
import { FormikValues, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { AttributeTabs } from './AttributeTabs';
import { AttributeTabs as AddAttributeTabs} from '../../Add/AttributeTab/AttributeTabs';
const { TabPane } = Tabs;
const initialItemShape: any = {
label: 'Attribute 1',
key: '1',
closable: true,
};
export const TabsContainer: React.FC = () => {
const [activeKey, setActiveKey] = useState('1');
const { setFieldValue } = useFormikContext();
@ -23,6 +20,12 @@ export const TabsContainer: React.FC = () => {
const [t] = useTranslation()
const initialItemShape: any = {
label: `${t(`Attribute`)} 1`,
key: '1',
closable: true,
};
const varianCount = values?.Attribute?.slice(1)?.map((item:any,index:any)=>{
return {
label: `${t(`Attribute`)}`+ `${index+1}`,
@ -32,42 +35,75 @@ export const TabsContainer: React.FC = () => {
})?? initialItemShape
const [items, setItems] = useState(varianCount ?? [initialItemShape]); // Ensure items is always an array
useEffect(() => {
if (items.length > 0) {
setActiveKey(items[0].key);
}
}, []);
const findFirstMissingKey = (itemKeys:string[]) => {
const keysAsNumbers = itemKeys.map(Number); // Convert strings to numbers
for (let i = 1; i <= keysAsNumbers.length + 1; i++) {
if (!keysAsNumbers.includes(i)) {
return i;
}
}
};
const [nextKey, setNextKey] = useState<any>(items.map((item: any) => `${item.key}`)); // Initialize the key counter to the length of items + 1
useEffect(() => {
const keys = items.map((item: any) => `${item.key}`);
setNextKey(findFirstMissingKey(keys))
}, [items]);
console.log(values,"items");
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `Attribute ${newKey}`, closable: true }]);
const newKey = `${nextKey}`;
setItems([...items, { key: newKey, label: `${t(`Attribute`)} ${newKey}`, closable: true ,Add:true}]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item:any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `Attribute ${newKey}` };
const newKey = `${nextKey}`;
const newItem = { ...targetItem, key: newKey, label: `${t(`Attribute`)} ${newKey}`,Add:true };
setItems([...items, newItem]);
setActiveKey(newKey);
setNextKey((prevKey : any) => prevKey + 1);
const originalValues = values?.Attribute?.[targetKey];
setFieldValue(`Attribute.${newKey}`, originalValues);
setFieldValue(`Attribute.${newKey}`, {...originalValues,id:null});
}
};
const [removedAttribute, setRemovedAttribute] = useState<string[]>([]);
useEffect(() => {
setFieldValue(`removedAttribute`, removedAttribute);
}, [removedAttribute]);
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item:any) => item.key !== targetKey);
if (newItems.length > 0) {
const removedItem = values?.Attribute[targetKey] as any;
if (removedItem?.id) {
setRemovedAttribute((prevRemovedAttribute) => [...prevRemovedAttribute, removedItem.id]);
}
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
setFieldValue(`Attribute.${targetKey}`, undefined);
} else {
toast.error("Cannot close the last tab");
}
};
useEffect(() => {
@ -84,31 +120,27 @@ useEffect(() => {
const tabPosition = width > 1000 ? 'left' : 'top';
return (
<Tabs
<>
<Tabs
type="editable-card"
onChange={setActiveKey}
activeKey={activeKey}
onEdit={(targetKey:any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
onEdit={(targetKey: any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
tabPosition={tabPosition}
items={items.map((item: any) => ({
label: <Space>{t(`${item.label}`)} <CopyOutlined onClick={() => handleDuplicate(item.key)} /></Space>,
// children: item?.Add ? <AddAttributeTabs tabKey={item.key} /> : <AttributeTabs tabKey={item.key} />,
children: <AddAttributeTabs tabKey={item.key}/>,
key: item.key,
closable: item.closable,
}))}
>
{items.map((item :any) =>{
return (
<TabPane
key={item?.key}
tab={
<Space>
{t(`${item.label}`)}
<CopyOutlined onClick={() => handleDuplicate(item.key)} />
</Space>
}
closable={item.closable}
>
<AttributeTabs tabKey={item?.key} />
</TabPane>
)
})}
</Tabs>
{ items.length === 0 && (
<h6 className='AddNewTabText'>{t("Add New Attribute")}</h6>
)}
</>
);
};

View File

@ -27,7 +27,7 @@ export const AttributeValueTabs: React.FC<AttributeValueTabsProps> = ({ parentKe
return (
<>
<h5>{t("Values")} {tabKey}</h5>
<h5>{t("Value")} {tabKey}</h5>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<FormItem

View File

@ -10,8 +10,8 @@ import { useFormikContext } from 'formik';
const File = ({ parentKey,tabKey}:any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `Attribute.[${parentKey}].AttributeValue[${tabKey}].${"main_photo"}`;
const imageUrl = formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["main_photo"] ? URL.createObjectURL(formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["main_photo"]) : "" ;
const name = `Attribute.[${parentKey}].AttributeValue[${tabKey}].${"image"}`;
const imageUrl = formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["image"] ? URL.createObjectURL(formik?.values?.Attribute?.[parentKey]?.AttributeValue?.[tabKey]?.["image"]) : "" ;
const fileList: UploadFile[] = [
@ -34,7 +34,7 @@ const File = ({ parentKey,tabKey}:any) => {
return (
<div className="ValidationField">
<label className="text">
{t(`main_photo`)}
{t(`image`)}
</label>
<Upload

View File

@ -12,8 +12,10 @@ interface FormItemProps {
export const FormItem: React.FC<FormItemProps> = ({ label, value, onChange ,type = "text"}) => {
return (
<>
<Label className="tabstext">{label}</Label>
<Input value={value} type={type} onChange={onChange} />
<Label className="tabstext w-100" >
{label}
<Input className='w-100' value={value} type={type} onChange={onChange} />
</Label>
</>
);
};

View File

@ -7,14 +7,9 @@ import { FormikValues, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { AttributeValueTabs } from './AttributeTabs';
const { TabPane } = Tabs;
import { AttributeValueTabs as AddAttributeValueTabs } from '../../Add/AttributeValueTab/AttributeTabs';
const initialItemShape: any = {
label: 'Value 1',
key: '1',
closable: true,
};
export const TabsContainer= ({parentKey}:any) => {
export const TabsContainer = ({ parentKey }: any) => {
const [activeKey, setActiveKey] = useState('1');
const [t] = useTranslation()
@ -23,51 +18,87 @@ export const TabsContainer= ({parentKey}:any) => {
const { values, handleChange } = formikContext;
const [width, setWidth] = useState(window.innerWidth);
const varianCount = values?.Attribute[parentKey]?.AttributeValue?.slice(1)?.map((item:any,index:any)=>{
const initialItemShape: any = {
label: `${t(`Value`)} 1`,
key: '1',
closable: true,
};
const varianCount = values?.Attribute[parentKey]?.AttributeValue?.slice(1)?.map((item: any, index: any) => {
return {
label: `${t(`Value`)}`+ `${index+1}`,
key: index+1,
label: `${t(`Value`)}` + `${index + 1}`,
key: index + 1,
closable: true,
}
})?? initialItemShape
}) ?? initialItemShape
const [items, setItems] = useState(Array.isArray(varianCount) ? varianCount : [initialItemShape]); // Ensure items is always an array
const findFirstMissingKey = (itemKeys:string[]) => {
const keysAsNumbers = itemKeys.map(Number); // Convert strings to numbers
for (let i = 1; i <= keysAsNumbers.length + 1; i++) {
if (!keysAsNumbers.includes(i)) {
return i;
}
}
};
const [nextKey, setNextKey] = useState<any>(items.map((item: any) => `${item.key}`)); // Initialize the key counter to the length of items + 1
useEffect(() => {
// Set the active key to the first tab key when the component mounts or items change
if (items.length > 0) {
setActiveKey(items[0].key);
}
}, []);
useEffect(() => {
const keys = items.map((item: any) => `${item.key}`);
setNextKey(findFirstMissingKey(keys))
}, [items]);
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `Value ${newKey}`, closable: true }]);
const newKey = `${nextKey}`;
setItems([...items, { key: newKey, label: `${t(`Value`)} ${newKey}`, closable: true,Add:true }]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item:any) => item.key === targetKey);
const targetItem = items.find((item: any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `Value ${newKey}` };
const newKey = `${nextKey}`;
const newItem = { ...targetItem, key: newKey, label: `${t(`Value`)} ${newKey}`,Add:true };
setItems([...items, newItem]);
setActiveKey(newKey);
setNextKey((prevKey : any) => prevKey + 1);
const originalValues = values?.Attribute?.[parentKey]?.AttributeValue?.[targetKey];
setFieldValue(`Attribute.${parentKey}.AttributeValue.${newKey}`, originalValues);
setFieldValue(`Attribute.${parentKey}.AttributeValue.${newKey}`, {...originalValues,id:null});
}
};
const [removedAttributeValues, setRemovedAttributeValues] = useState<string[]>([]);
useEffect(() => {
setFieldValue(`removedAttributeValues`, removedAttributeValues);
}, [removedAttributeValues]);
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item:any) => item.key !== targetKey);
if (newItems.length > 0) {
const newItems = items?.filter((item: any) => item.key !== targetKey) as any;
const removedItem = values?.Attribute?.[parentKey]?.AttributeValue?.[targetKey] as any;
if (removedItem?.id) {
setRemovedAttributeValues((prevRemovedAttributeValues) => [...prevRemovedAttributeValues, removedItem.id]);
}
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
setFieldValue(`Attribute.${parentKey}.AttributeValue.${targetKey}`, undefined);
} else {
toast.error("Cannot close the last tab");
};
}
};
useEffect(() => {
useEffect(() => {
const handleResize = () => {
setWidth(window.innerWidth);
};
@ -77,35 +108,35 @@ useEffect(() => {
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
const tabPosition ='top';
}, []);
const tabPosition = 'top';
return (
<>
<Tabs
type="editable-card"
onChange={setActiveKey}
activeKey={activeKey}
onEdit={(targetKey:any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
onEdit={(targetKey: any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
tabPosition={tabPosition}
items={
items.map((item: any) => ({
label: <Space>{t(`${item.label}`)} <CopyOutlined onClick={() => handleDuplicate(item.key)} /></Space>,
// children: item?.Add ? <AddAttributeValueTabs parentKey={parentKey} tabKey={item.key} /> : <AttributeValueTabs parentKey={parentKey} tabKey={item.key} />,
children: <AddAttributeValueTabs parentKey={parentKey} tabKey={item.key} /> ,
>
{items.map((item :any) =>{
return (
<TabPane
key={item?.key}
tab={
<Space>
{t(`${item.label}`)}
<CopyOutlined onClick={() => handleDuplicate(item.key)} />
</Space>
key: item.key,
closable: item.closable,
}))
}
closable={item.closable}
>
<AttributeValueTabs parentKey={parentKey} tabKey={item?.key} />
</TabPane>
)
})}
</Tabs>
{ items.length === 0 && (
<h6>{t("Add_New_value")}</h6>
)}
</>
);
};

View File

@ -22,15 +22,17 @@ function Form() {
return (
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<ValidationField name="name" />
<ValidationField name="parent_id" type="Search" option={SelectData} searchBy={"search"} />
<ValidationField name="name_ar" />
<ValidationField name="name_en" />
<ValidationField name="name_de" />
</Col>
<Col>
<ValidationField name="parent_id" type="Search" option={SelectData} searchBy={"search"} />
<ValidationField name="photo" type="File" />
</Col>
</Row>
)
}

View File

@ -3,48 +3,462 @@ import { getInitialValues, 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 { FaSadCry } from 'react-icons/fa'
import ViewPage from '../../../Layout/Dashboard/ViewPage';
import { Rate, Spin } from 'antd';
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
import { useParams } from 'react-router-dom';
import LoadingPage from '../../../Layout/app/LoadingPage';
import { useTranslation } from 'react-i18next';
import { BsInfoCircle } from 'react-icons/bs';
import { useGetOneCategories, useUpdateCategories } from '../../../api/Categories';
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
import Form from './Edit/Form';
import { changeShapeInfo } from '../../../utils/Array/changeShapeInfo';
import { TabsContainer } from './Edit/AttributeTab/TabsContainer';
import { useGetSingleAttribute } from '../../../api/attribute';
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';
const EditPage = () => {
const { setObjectToEdit, objectToEdit } = usePageState()
const {t} = useTranslation();
const { data ,isLoading } = useGetOneCategories()
const {id} = useParams()
const { t } = useTranslation();
const { data, isLoading, isRefetching } = useGetOneCategories()
const { id } = useParams()
const { data: Atrribute, isLoading: isLoadingAtrribute, isRefetching: AttributeisRefetching } = useGetSingleAttribute({ name: "category_id", id: id }, {})
const { mutate, isError, isSuccess } = useUpdateCategories()
const { mutateAsync, isSuccess: isSuccessAddAttribute, data: AttributeData, isError: isErrorAddAttribute } = useAddAttribute()
const { mutate: mutateAttributeValue, isSuccess: isSuccessAddAttributeValue, data: AttributeValueData, isError: isErrorAddAttributeValue } = useAddAttributeValue()
const { mutate: UpdateAttribute, isSuccess: isSuccessAttribute, isError: isErrorUpdateAttribute } = useUpdateAttribute("put")
const { mutate: UpdateAttributeValue, isSuccess: isSuccessAttributeValue, isError: isErrorUpdateAttributeValue } = useUpdateAttributeValue()
const { mutate: DeleteAttributeValue, isError: isErrorDeleteAttributeValue } = useDeleteAttributeValue()
const { mutate: DeleteAttribute, isError: isErrorDeleteAttribute } = useDeleteAttribute()
const [removedAttribute, setremovedAttribute] = useState<any[]>([])
const [removedAttributeValue, setremovedAttributeValue] = useState<any[]>([])
const [AddAttribute, setAddAttribute] = useState<any[]>([])
const [EditAttribute, setEditAttribute] = useState<any[]>([])
const [AddAttributeValue, setAddAttributeValue] = useState<any[]>([])
const [EditAttributeValue, setEditAttributeValue] = useState<any[]>([])
const [OldData, setOldData] = useState(Atrribute?.data)
const [OldDataValues, setOldDataValues] = useState([])
const handleSubmit = (values: any) => {
console.log(values,"values");
function isValid(){
const attributes = values?.Attribute?.slice(1);
setremovedAttribute(values?.removedAttribute)
setremovedAttributeValue(values?.removedAttributeValue)
if (attributes) {
attributes.forEach((item: any, index: number) => {
if (item.id && item.id !== null) {
setEditAttribute((prevEditAttribute) => [...prevEditAttribute, item]);
console.log(item, "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
setEditAttributeValue((prevEditAttributeValue) => [...prevEditAttributeValue, [index, attrValueItem]]);
}
});
}
} 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
setAddAttributeValue((prevEditAttributeValue) => [...prevEditAttributeValue, [index, attrValueItem]]);
}
});
}
}
});
}
const EditedCategory = {
name: {
en: values?.name_en,
ar: values?.name_ar,
de: values?.name_de
},
photo: values?.photo,
parent_id: values?.parent_id,
_method:"PUT"
}
const {data : Atrribute,isLoading : isLoadingAtrribute } = useGetSingleAttribute({ name:"category_id", id:id},{})
const {mutate ,isSuccess} = useUpdateCategories("post")
const handleSubmit = (values:any)=>{
const Imagetype = typeof values?.photo
values['attribute'] = changeShapeInfo(values?.attribute)
if(Imagetype === "string") {
delete values['photo']
if (Imagetype === "string") {
delete EditedCategory['photo']
}
mutate(values)
// return mutate(newData);
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);
}
useNavigateOnSuccess(isSuccess , '/categories')
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);
}
}
});
if (validationResults.every((result) => result)) {
isValid();
}
}
function filterByIndex(number: number, array: [number, any][]): any[] {
return array.filter(([index, _]) => index === number).map(([_, item]) => item);
}
useEffect(() => {
setObjectToEdit([data?.category,Atrribute?.data]);
if (isSuccess) {
}, [data?.category,Atrribute?.data]);
const categoryId = id;
console.log(EditAttribute,"EditAttribute");
EditAttribute?.map((dataToSend: any, index: number) => {
console.log(index,"index");
const EditAttribute = dataToSend
const foundObject = OldData.find((item: any) => item.id === EditAttribute?.id) as any;
const UpdatedAttribute = {
name: {
en: EditAttribute?.name_en,
ar: EditAttribute?.name_ar,
de: EditAttribute?.name_de
},
type: EditAttribute?.type,
// category_id:categoryId,
}
if (foundObject) {
Object.keys(UpdatedAttribute).forEach((propName: any) => {
if (foundObject.hasOwnProperty(propName)) {
const foundValue = foundObject[propName];
//@ts-ignore
const editedValue = UpdatedAttribute[propName];
if (foundValue === editedValue) {
//@ts-ignore
delete UpdatedAttribute[propName];
}
}
})
if (foundObject.name &&
foundObject.name.en === UpdatedAttribute.name.en &&
foundObject.name.ar === UpdatedAttribute.name.ar &&
foundObject.name.de === UpdatedAttribute.name.de) {
//@ts-ignore
delete UpdatedAttribute.name;
}
Object.keys(UpdatedAttribute).forEach((key: any) => {
//@ts-ignore
if (UpdatedAttribute[key] === undefined) {
//@ts-ignore
delete UpdatedAttribute[key];
}
});
if (Object.keys(UpdatedAttribute).length > 0) {
//@ts-ignore
// UpdatedAttribute._method = "PUT";
//@ts-ignore
UpdatedAttribute.id = foundObject?.id;
console.log(UpdatedAttribute, "EditAttribute");
UpdateAttribute(UpdatedAttribute)
}
}
const result: [number, any][] = filterByIndex(index, EditAttributeValue);
console.log(result,"result");
result?.map((dataToSend: any) => {
if(dataToSend?.id && dataToSend.id !== null){
console.log(OldDataValues,"OldDataValues");
const foundObjectValue = (OldDataValues[index] as any).find((item: any) => item.id === dataToSend?.id) as any;
console.log(foundObjectValue,"foundObjectValue");
console.log(OldDataValues[index],"OldDataValues[index]");
const EditAttributeValue = dataToSend
console.log(EditAttributeValue);
const NewEditAttributeValue = {
id: EditAttributeValue?.id,
value: {
en: EditAttributeValue?.value_en,
ar: EditAttributeValue?.value_ar,
de: EditAttributeValue?.value_de
},
image: EditAttributeValue?.main_photo,
// attribute_id:EditAttribute?.id,
// id: EditAttributeValue?.id,
}
if (EditAttribute.type === "color") {
NewEditAttributeValue["value"] = {
en: EditAttributeValue?.value_en,
ar: EditAttributeValue?.value_en,
de: EditAttributeValue?.value_en
}
}
if (EditAttributeValue?.main_photo === "string") {
delete NewEditAttributeValue['image']
}
if(foundObjectValue){
console.log(foundObjectValue,"foundObjectValue");
Object.keys(NewEditAttributeValue).forEach((propName: any) => {
if (foundObjectValue.hasOwnProperty(propName)) {
const foundValue = foundObjectValue[propName];
//@ts-ignore
const editedValue = NewEditAttributeValue[propName];
if (foundValue === editedValue) {
//@ts-ignore
delete NewEditAttributeValue[propName];
}
}
})
Object.keys(NewEditAttributeValue).forEach((key: any) => {
//@ts-ignore
if (NewEditAttributeValue[key] === undefined) {
//@ts-ignore
delete NewEditAttributeValue[key];
}
});
if (foundObjectValue.value &&
foundObjectValue.value.en === NewEditAttributeValue.value.en &&
foundObjectValue.value.ar === NewEditAttributeValue.value.ar &&
foundObjectValue.value.de === NewEditAttributeValue.value.de) {
//@ts-ignore
delete NewEditAttributeValue.value;
}
console.log(foundObjectValue.value,"foundObjectValue.value");
console.log(NewEditAttributeValue.value,"NewEditAttributeValue.value");
if (Object.keys(NewEditAttributeValue).length > 0) {
//@ts-ignore
NewEditAttributeValue._method = "PUT";
//@ts-ignore
NewEditAttributeValue.id = foundObjectValue?.id;
console.log(NewEditAttributeValue, "EditAttribute");
UpdateAttributeValue(NewEditAttributeValue)
}
}
}
else{
console.log("mutateAttributeValue");
const EditAttributeValue = dataToSend
const NewEditAttributeValue = {
value: {
en: EditAttributeValue?.value_en,
ar: EditAttributeValue?.value_ar,
de: EditAttributeValue?.value_de
},
image: EditAttributeValue?.main_photo,
// attribute_id:EditAttribute?.id,
attribute_id: EditAttribute?.id,
}
if (EditAttribute.type === "color") {
NewEditAttributeValue["value"] = {
en: EditAttributeValue?.value_en,
ar: EditAttributeValue?.value_en,
de: EditAttributeValue?.value_en
}
}
mutateAttributeValue(NewEditAttributeValue)
}
})
}
)
console.log(removedAttribute,"removedAttribute");
removedAttribute?.map((item:any)=>{
DeleteAttribute({ id: item })
})
AddAttribute?.map((dataToSend: any, index: number) => {
const AddAttribute = dataToSend
const NewAddAttribute = {
name: {
en: AddAttribute?.name_en,
ar: AddAttribute?.name_ar,
de: AddAttribute?.name_de
},
type: AddAttribute?.type,
category_id: categoryId,
}
mutateAsync(NewAddAttribute).then((data: any) => {
const AttributeId = (data as any)?.id;
// console.log(AttributeValues[0]?.slice(1),"AttributeValues");
const result: [number, any][] = filterByIndex(0, AddAttributeValue);
result?.map((dataToSend: any, index: number) => {
const AddAttributeValue = dataToSend
const NewAddAttributeValue = {
value: {
en: AddAttributeValue?.value_en,
ar: AddAttributeValue?.value_ar,
de: AddAttributeValue?.value_de
},
image: AddAttributeValue?.main_photo,
attribute_id: AttributeId,
}
mutateAttributeValue(NewAddAttributeValue)
})
})
})
console.log(removedAttributeValue,"removedAttributeValue");
removedAttributeValue?.map((item:any)=>{
console.log(item,"item");
return DeleteAttributeValue({ id: item })
})
}
}, [isSuccess])
// useNavigateOnSuccess(isSuccess, '/categories')
useEffect(() => {
setObjectToEdit([data?.category, Atrribute?.data]);
setOldData(Atrribute?.data)
setOldDataValues(Atrribute?.data?.map((item:any)=>{
return item?.attribute_value
}))
console.log(OldDataValues,"OldDataValues");
}, [data?.category, Atrribute?.data]);
const getValidationSchema = () => {
@ -54,9 +468,9 @@ const EditPage = () => {
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
if (isLoadingAtrribute || isLoading || !objectToEdit || (Array.isArray(objectToEdit) && objectToEdit.some(item => item === undefined))) {
return <Spin/>
}
if (AttributeisRefetching || isRefetching || isLoadingAtrribute || isLoading || !objectToEdit || (Array.isArray(objectToEdit) && objectToEdit.some(item => item === undefined))) {
return <Spin />
}
return (
@ -65,14 +479,14 @@ const EditPage = () => {
<ViewPage {...ViewProps}>
<Tabs>
<TabList>
{/* <Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("BasicInfo")}</h6></div></Tab> */}
<Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("BasicInfo")}</h6></div></Tab>
<Tab><div className='SignleDriverContainer'><span className='SignleDriverInfoIcon'><MdLanguage size={20} /></span> <h6 className='SingleDriverInfo'>{t("attributes")}</h6></div></Tab>
</TabList>
{/*
<TabBody >
<div className=" mt-4"><Form /></div>
</TabBody> */}
</TabBody>
<TabBody >
<div className=" mt-4"><TabsContainer /></div>

View File

@ -1,47 +1,54 @@
import * as Yup from "yup";
import { buildFormData } from "../../api/helper/buildFormData";
import { ImageBaseURL } from "../../api/config";
import { fetchImage } from "../../Hooks/imageUrlToFile";
import { useState } from "react";
interface formUtilCommon {
number: number,
value: number
}
interface ObjectToEdit extends formUtilCommon {
id?: number,
}
interface InitialValues extends ObjectToEdit {
}
interface ValidateSchema extends formUtilCommon {
}
export const getInitialValues = (objectToEdit: any | null = null): any => {
const Attribute = objectToEdit[1]?.map((item: any) => {
const AttributeValue = item?.attribute_value?.map((item:any)=>({value:item?.value , image : item?.image} )
const AttributeValue = item?.attribute_value?.map((item:any)=>(
{
value_ar: item?.value["ar"],
value_en: item?.value["en"],
value_de: item?.value["de"],
id : item?.id,
image : item?.image,
Edited:false
} )
)
return (
{
name : item?.name,
name_ar: item?.name["ar"],
name_en: item?.name["en"],
name_de: item?.name["de"],
type : item?.type,
id : item?.id,
icon : item?.icon,
category_id : item?.category_id,
AttributeValue : [{},...AttributeValue],
AttributeValue : [{},...AttributeValue ?? {}],
Edited:false
}
)
})
const imageUrl = ImageBaseURL + objectToEdit[0]?.photo?.replace("public", "/storage")
return {
id: objectToEdit[0]?.id ?? 0,
name: objectToEdit[0]?.name ?? "",
name_ar: objectToEdit[0]?.name["ar"],
name_en: objectToEdit[0]?.name["en"],
name_de: objectToEdit[0]?.name["de"],
parent_id: objectToEdit[0]?.parent_id ?? "",
photo: objectToEdit[0]?.photo ?? '',
Attribute: [{},...Attribute],
removedAttribute:[],
removedAttributeValue:[],
};
};
@ -52,7 +59,7 @@ export const getInitialValuesForAdd = (objectToEdit: any | null = null): any =>
name_de: '',
parent_id: null,
photo: '',
Attribute: [{},{AttributeValue:[{},{}]}],
Attribute: [{}],
};
@ -63,17 +70,18 @@ export const getInitialValuesForAdd = (objectToEdit: any | null = null): any =>
export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any> => {
// Validate input
return Yup.object().shape({
// name_ar: Yup.string().required('Required'),
// name_en: Yup.string().required('Required'),
// name_de: Yup.string().required('Required'),
name_ar: Yup.string().required('Required'),
name_en: Yup.string().required('Required'),
name_de: Yup.string().required('Required'),
// parent_id: Yup.string().required('Required'),
// photo: Yup.string().required('Required'),
photo: Yup.string().required('Required'),
});
};
export const getDataToSend = (values: any): FormData => {
const data = { ...values };

View File

@ -12,6 +12,8 @@ const useTableColumns :any = () => {
const [t] = useTranslation();
const deleteMutation = useDeleteCategories()
const navigate = useNavigate()
const language = localStorage.getItem("language") ?? "en"
return useMemo(
() => [
@ -19,7 +21,7 @@ const useTableColumns :any = () => {
name: t("name"),
sortable: false,
center: "true",
cell: (row:any) => row?.name
cell: (row:any) => row?.name[language]
},
{
name: t("image"),

View File

@ -27,7 +27,7 @@ function Page() {
<DashHeader showAddButton={false} title={'coupon'}>
<div className='RightSide d-flex gap-2 align-center '>
<SearchField />
<SearchField searchBy={"name"} />
<AddButton onClick={()=>navigate('/coupon/add')}></AddButton>
</div>

View File

@ -18,11 +18,12 @@ 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: CategoriesData} = useGetCategories()
const { data: ProductData } = useGetProduct()
const SelectCategoriesData = useFormatToSelect(CategoriesData?.categories)
const SelectProductData = useFormatToSelect(ProductData?.BaseProducts)
return (
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
@ -40,7 +41,7 @@ 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={"search"} 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="status" type='Checkbox' label='status' />

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
import { getInitialValues, getValidationSchema, getDataToSend } from '../formUtil'
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'
@ -32,6 +32,7 @@ const category = values?.category_attr?.map((item: any) => {
values['items'] = [...products, ...category];
console.log(values, "values");
mutate(values)

View File

@ -27,7 +27,7 @@ function Form() {
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<ValidationField name="name" />
<ValidationField name="code" />
<ValidationField name="code" isDisabled />
<ValidationField name="active" label='active_from_to' type='DataRange' Format="YYYY/MM/DD" />
<ValidationField name="maximum_number_of_uses" type='number' />
<ValidationField name="maximum_number_of_uses_per_user" type='number' />
@ -40,8 +40,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={"search"} 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 />
<ValidationField name="category_attr" label='categories_item' type="Search" option={SelectCategoriesData} searchBy={"name"} isDisabled={values?.coupon_type !== "specified"}isMulti />
<ValidationField name="status" type='Checkbox' label='status' />

View File

@ -1,11 +1,11 @@
import React, { useEffect, useState } from 'react'
import {getInitialValuesForAdd as getInitialValues, getDataToSend } from '../formUtil'
import { getInitialValues, 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 { FaSadCry } from 'react-icons/fa'
import ViewPage from '../../../Layout/Dashboard/ViewPage';
import { Rate } from 'antd';
import { Rate, Spin } from 'antd';
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
import { useParams } from 'react-router-dom';
import LoadingPage from '../../../Layout/app/LoadingPage';
@ -18,17 +18,9 @@ import Form from './EditForm';
const EditPage = () => {
const { setObjectToEdit, objectToEdit } = usePageState()
const { t } = useTranslation();
const { data } = useGetOneCoupon()
const { data,isLoading,isRefetching } = useGetOneCoupon()
const { mutate, isSuccess } = useUpdateCoupon("put")
const FormatedData = data?.coupon;
const handleSubmit = (values: any) => {
values.active_at = values.active[0].format('YYYY-MM-DD HH:mm:ss.SSS')
values.active_to = values.active[1].format('YYYY-MM-DD HH:mm:ss.SSS')
values.status = values.active ? "active" : "inactive"
const products = values?.product_attr?.map((item: any) => {
return { "itemable_type": "product", "itemable_id": item };
})?.filter((item: any) => item.itemable_id !== "") || [];
@ -37,12 +29,29 @@ const EditPage = () => {
return { "itemable_type": "category", "itemable_id": item };
})?.filter((item: any) => item.itemable_id !== "") || [];
values['items'] = [...products, ...category];
// Create an object to hold the values to be mutated
const mutationData: any = {};
console.log(values, "values");
mutate(values)
if (values?.name !== null) mutationData["name"] = values.name;
if (values?.status !== null) mutationData["status"] = values.status ? "active" : "inactive";
if (values?.minimum_total_to_order !== null) mutationData["minimum_total_to_order"] = values.minimum_total_to_order;
if (values?.maximum_number_of_uses_per_user !== null) mutationData["maximum_number_of_uses_per_user"] = values.maximum_number_of_uses_per_user;
if (values?.maximum_number_of_uses !== null) mutationData["maximum_number_of_uses"] = values.maximum_number_of_uses;
if (values?.coupon_value !== null) mutationData["coupon_value"] = values.coupon_value;
if (values?.coupon_type !== null) mutationData["coupon_type"] = values.coupon_type;
if (values?.discount_type !== null) mutationData["discount_type"] = values.discount_type;
if (values?.active !== null && values?.active.length === 2) {
mutationData["active_at"] = values.active[0].format('YYYY-MM-DD HH:mm:ss.SSS');
mutationData["active_to"] = values.active[1].format('YYYY-MM-DD HH:mm:ss.SSS');
}
if (products.length > 0 || category.length > 0) {
mutationData['items'] = [...products, ...category];
}
// Perform the mutation with the constructed mutationData object
mutate(mutationData);
}
useNavigateOnSuccess(isSuccess, '/Coupon')
@ -51,12 +60,16 @@ const EditPage = () => {
setObjectToEdit(data?.coupon);
}, [data]);
}, [data?.coupon]);
const getValidationSchema = () => {
return null
};
if ( isLoading || !objectToEdit || isRefetching) {
return <Spin />
}
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };

View File

@ -27,30 +27,31 @@ export const getInitialValues = (objectToEdit: any | null = null): any => {
const products = [] as any;
const categories = [] as any;
const language = localStorage.getItem("language") ?? "en"
// Map over the items array and push items into the appropriate array
objectToEdit?.items?.forEach((item: any) => {
if (item?.itemable_type === "product") {
products.push({ value: item?.itemable?.name, label: item?.itemable?.name });
products.push({ value: item?.itemable?.id, label: item?.itemable?.name[language] });
} else if (item?.itemable_type === "category") {
categories.push({ value: item?.itemable?.name, label: item?.itemable?.name });
categories.push({ value: item?.itemable?.id, label: item?.itemable?.name[language] });
}
});
return {
id: objectToEdit?.id ?? 0,
name: objectToEdit?.name ?? "",
code: objectToEdit?.code ?? "",
name: objectToEdit?.name ,
code: objectToEdit?.code ,
//@ts-ignore
active: objectToEdit?.active_to ? [dayjs(objectToEdit?.active_from), dayjs(objectToEdit?.active_to)] : "",
minimum_total_to_order: objectToEdit?.minimum_total_to_order ?? "",
maximum_number_of_uses_per_user: objectToEdit?.maximum_number_of_uses_per_user ?? "",
maximum_number_of_uses: objectToEdit?.maximum_number_of_uses ?? "",
minimum_total_to_order: objectToEdit?.minimum_total_to_order ,
maximum_number_of_uses_per_user: objectToEdit?.maximum_number_of_uses_per_user ,
maximum_number_of_uses: objectToEdit?.maximum_number_of_uses ,
coupon_value: objectToEdit?.coupon_value ?? "",
coupon_type: objectToEdit?.coupon_type ?? "",
discount_type: objectToEdit?.discount_type ?? "",
product_attr: products ?? "",
category_attr: categories ?? "",
coupon_value: objectToEdit?.coupon_value ,
coupon_type: objectToEdit?.coupon_type ,
discount_type: objectToEdit?.discount_type ,
product_attr: products ,
category_attr: categories ,
status: objectToEdit?.status ?? 0,
@ -87,7 +88,6 @@ export const getValidationSchema = (editMode: boolean = false): Yup.Schema<any>
status: Yup.string().required('Required'),
active: Yup.mixed().required('Required'),
discount_type: Yup.string().required('Required'),
coupon_type: Yup.string().required('Required'),
minimum_total_to_order: Yup.number().required('Required'),
maximum_number_of_uses: Yup.number().required('Required'),

View File

@ -12,6 +12,8 @@ const useTableColumns :any = () => {
const [t] = useTranslation();
const deleteMutation = useDeleteCoupon()
const navigate = useNavigate()
const language = localStorage.getItem("language") ?? "en"
return useMemo(
() => [

View File

@ -23,7 +23,7 @@ function ProductsPage() {
<DashBody status={status as QueryStatusEnum} >
<DashHeader showAddButton={false} title={'products'}>
<div className='RightSide d-flex gap-2 align-center '>
<SearchField/>
<SearchField searchBy="name"/>
<AddButton onClick={()=>navigate('/products/add')}></AddButton>
</div>

View File

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
import {getInitialValuesAdd as getInitialValues, getValidationSchema, getDataToSend } from '../formUtil'
import { getInitialValuesAdd 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'
@ -9,72 +9,117 @@ import { useTranslation } from 'react-i18next';
import { BsInfoCircle } from 'react-icons/bs';
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
import { useAddProduct, useAddProductVariation } from '../../../api/product';
import VarianInfo from './VarianInfo';
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
import AttributeInfo from './AttributeInfo';
import { TabsContainer } from './FormikTab/TabsContainer';
import { toast } from 'react-toastify';
// import AttributeInfo from './AttributeInfo';
const AddProductPage = () => {
const { mutate, isLoading , data, isSuccess } = useAddProduct()
const { mutate:AddVariation, isSuccess:SuccessVariation } = useAddProductVariation()
const { mutate, isLoading, data, isSuccess } = useAddProduct()
const { mutate: AddVariation, isSuccess: SuccessVariation } = useAddProductVariation()
const [IsValed, setIsValed] = useState(false)
const [infotaps , setInfoTaps] = useState<any[]>([])
const [infotaps, setInfoTaps] = useState<any[]>([])
const [Varibletaps , setVaribleTaps] = useState<any[]>([])
const [Varibletaps, setVaribleTaps] = useState<any[]>([])
const handleSubmit = (values: any) => {
function isValid() {
setInfoTaps(values?.info?.slice(1)?.map((taps:any) => {
setInfoTaps(values?.info?.slice(1)?.map((taps: any) => {
return (changeShapeInfo(taps));
}));
setVaribleTaps(values?.variable?.slice(1))
mutate({
name:{
en:values?.name_en,
ar:values?.name_ar,
de:values?.name_de
name: {
en: values?.name_en,
ar: values?.name_ar,
de: values?.name_de
},
category_id:1
category_id: 1
})
}
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);
}
useEffect(()=>{
else {
validationResults.push(true);
}
}
});
if(isSuccess){
const baseProductId = (data as any )?.id ;
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)=>{
Varibletaps?.map((dataToSend: any, index: number) => {
const varible = dataToSend
const info = infotaps[index]
const jsonString = JSON.stringify(info);
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
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
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,
product_attributes:[
{attribute_value_id: 1, attribute_id: 1}
],
base_product_id:baseProductId
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);
@ -82,7 +127,7 @@ const AddProductPage = () => {
})
}
},[isSuccess])
}, [isSuccess])
const { setObjectToEdit, objectToEdit } = usePageState()
@ -118,7 +163,7 @@ const AddProductPage = () => {
<div className=" mt-4"><BasicInfo setIsValed={setIsValed} IsValed={IsValed} /></div>
</TabBody>
<TabBody >
<div className=" mt-4"><VarianInfo /></div>
<div className=" mt-4"><TabsContainer /></div>
</TabBody>
<TabBody >
{/* <div className=" mt-4"><AttributeInfo /></div> */}
@ -136,17 +181,17 @@ const AddProductPage = () => {
export default AddProductPage
function changeShapeInfo(originalObject:any){
const transformedObject:any = {};
function changeShapeInfo(originalObject: any) {
const transformedObject: any = {};
for (const key in originalObject) {
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
return transformedObject
}

View File

@ -1,37 +0,0 @@
import React from 'react';
import { useFormikContext } from 'formik';
import ValidationField from '../../../Components/ValidationField/ValidationField';
import { useGetSingleAttribute } from '../../../api/attribute';
const Attribute = () => {
const { values, setFieldValue } = useFormikContext<any>();
const { data: attributeData } = useGetSingleAttribute({ name: "product_id", id: values?.id });
const handleAttributeChange = (name: string, value: any) => {
setFieldValue(`attribute[${name}]`, value);
};
return (
attributeData?.data?.map((item: any) => {
const options = item?.attribute_value?.map((attr: any) => ({
label: attr?.value,
value: attr?.attribute_id
}));
return (
<ValidationField
key={item?.name}
name={`attribute[${item?.name}]`}
label={item?.name}
placeholder={item?.name}
type="Select"
option={options}
onChange={(value: any) => handleAttributeChange(item?.name, value)}
/>
);
})
);
};
export default Attribute;

View File

@ -1,34 +0,0 @@
import React, { useEffect, useState } from 'react'
import { Col, Row } from 'reactstrap'
import ValidationField from '../../../Components/ValidationField/ValidationField'
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { toast } from 'react-toastify';
import { useGetCategories } from '../../../api/Categories';
import useFormatToSelect from '../../../Hooks/useFormatToSelect';
const AttributeInfo = ({ setIsValed, IsValed }: any) => {
const [t] = useTranslation();
const formikContext = useFormikContext();
const Selectdata = [
{ label: "color", value:"color"}]
return (
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<ValidationField name="name_ar" />
<ValidationField name="name_en" />
</Col>
<Col>
<ValidationField name="name_de" />
<ValidationField name="type" type="Select" label='type' placeholder='type' option={Selectdata} />
</Col>
</Row>
)
}
export default AttributeInfo

View File

@ -12,8 +12,14 @@ const BasicInfo = ({ setIsValed, IsValed }: any) => {
const formikContext = useFormikContext();
const { values, isValid } = formikContext;
const { data } = useGetCategories()
const SelectData = useFormatToSelect(data?.categories)
const language = localStorage.getItem("language") ?? "en"
const SelectData = data?.categories?.map((item:any)=>(
{
label : item?.name[language],
value : item?.id
}
))
useEffect(() => {
const { name_ar, name_en, name_de, main_photo, category_id } = values as any;

View File

@ -1,45 +0,0 @@
import React, { useEffect, useState } from 'react'
import { Col, Row } from 'reactstrap'
import ValidationField from '../../../../Components/ValidationField/ValidationField'
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { toast } from 'react-toastify';
import { useGetCategories } from '../../../../api/Categories';
import useFormatToSelect from '../../../../Hooks/useFormatToSelect';
const BasicInfo = ({ setIsValed, IsValed }: any) => {
const [t] = useTranslation();
const formikContext = useFormikContext();
const { values, isValid } = formikContext;
const { data } = useGetCategories()
const SelectData = useFormatToSelect(data?.categories)
useEffect(() => {
const { name_ar, name_en, name_de, main_photo, category_id } = values as any;
if (name_ar && name_en && name_de && main_photo && category_id && IsValed === false) {
toast.success(t("view_information_filed_fill_sucsessfully"));
setIsValed(true)
} else {
// console.log(isValid, "isValid");
}
}, [values]);
return (
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<ValidationField name="name" />
</Col>
<Col>
<ValidationField name="category_id" type="Search" label='category' placeholder='category' option={SelectData} searchBy={"name"} />
</Col>
</Row>
)
}
export default BasicInfo

View File

@ -1,36 +0,0 @@
import React from 'react';
import { useFormikContext } from 'formik';
import ValidationField from '../../../../../../Components/ValidationField/ValidationField';
import { useGetSingleAttribute } from '../../../../../../api/attribute';
const Attribute = ({data,tabKey}:any) => {
const { values, setFieldValue } = useFormikContext<any>();
const handleAttributeChange = (name: string, value: any) => {
setFieldValue(`variable.${tabKey}.attribute"[${name}]`, value);
};
return (
data?.map((item: any) => {
const options = item?.attribute_value?.map((attr: any) => ({
label: attr?.value,
value: attr?.attribute_id
}));
return (
<ValidationField
key={item?.name}
name={`attribute[${item?.name}]`}
label={item?.name}
placeholder={item?.name}
type="Select"
option={options}
onChange={(value: any) => handleAttributeChange(item?.name, value)}
/>
);
})
);
};
export default Attribute;

View File

@ -1,64 +0,0 @@
import { Button, Upload, UploadFile } from 'antd'
import { UploadOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { ImageBaseURL } from '../../../../../../api/config';
const File = ({ tabKey}:any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `variable[${tabKey}].${"main_photo"}`;
const imageUrl = formik?.values?.variable[tabKey]?.main_photo ? ImageBaseURL + formik?.values?.variable[tabKey]?.main_photo : "" ;
console.log(imageUrl);
const fileList: UploadFile[] = [
{
uid: '-1',
name: formik?.values?.variable[tabKey]?.main_photo?.name ?? "",
status: 'done',
url: imageUrl ,
thumbUrl: imageUrl ,
}
];
const FilehandleChange = (value:any) => {
formik.setFieldValue(name, value.file.originFileObj)
};
const customRequest = async ({ onSuccess}: any) => {
onSuccess();
};
return (
<div className="ValidationField">
<label className="text">
{t(`main_photo`)}
</label>
<Upload
listType="picture"
maxCount={1}
defaultFileList={[...fileList]}
onChange={ FilehandleChange}
customRequest={customRequest}
className={`w-100`}
>
<Button className={" w-100"} icon={<UploadOutlined />}>
{ t("upload_image") }
</Button>
</Upload>
</div>
)
}
export default File

View File

@ -1,50 +0,0 @@
import { Button, Upload, UploadFile } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { BaseURL_IMAGE } from '../../../../../../api/config';
const MaltyFile = ({ tabKey }: any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `variable[${tabKey}].Images`;
const imageFiles = formik.values?.variable?.[tabKey]?.Images || [];
const defaultFileList = imageFiles?.map((file: any, index: number) => ({
uid: `-${index}`,
name: file?.name, // Use a default name if file.name is undefined
status: 'done',
url: file ? URL.createObjectURL(file) : BaseURL_IMAGE + file?.path?.replace("public", "/storage"),
thumbUrl: file ?URL.createObjectURL(file):"",
}));
const FilehandleChange = ({ fileList }: { fileList: any }) => {
formik.setFieldValue(name, fileList.map((file: any) => file?.originFileObj));
};
const customRequest = async ({ onSuccess }: any) => {
onSuccess();
};
return (
<div className="ValidationField">
<label className="text">
{t(`Images`)}
</label>
<Upload
listType="picture"
defaultFileList={defaultFileList}
onChange={FilehandleChange}
customRequest={customRequest}
className="w-100"
maxCount={10}
>
<Button className="w-100" icon={<UploadOutlined />}>
{t("upload_image")}
</Button>
</Upload>
</div>
);
}
export default MaltyFile;

View File

@ -1,116 +0,0 @@
import React, { useEffect, useState } from 'react';
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Space, Typography } from 'antd';
import { useFormikContext } from 'formik';
import { objectToArray } from '../../../../../../utils/Array/ArrayToObjectFormik';
import { useTranslation } from 'react-i18next';
const ObjectField = ({tabKey}:any) => {
const [form] = Form.useForm();
const formik = useFormikContext<any>();
const [FieldItems, setFieldItems] = useState<any>(formik?.values?.info[tabKey])
const [t] = useTranslation()
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFieldItems((prevState:any) =>{
formik.setFieldValue(`info.${tabKey}`, {
...prevState,
[name]: value
});
return ({
...prevState,
[name]: value
})
} )
};
useEffect(() => {
if (formik?.values?.info[tabKey]) {
const defaultValues = formik.values.info[tabKey];
console.log(objectToArray( formik?.values?.info[tabKey]));
form.setFieldsValue({
items: [{ list:objectToArray( formik?.values?.info[tabKey])}]
});
}
else {
form.setFieldsValue({
items: [{ list: [{ key: '', Description: '' }] },], });
}
}, []); // Update when tabKey or info[tabKey] changes
return (
<Form
labelCol={{ span: 6 }}
wrapperCol={{ span: 18 }}
form={form}
name="dynamic_form_complex"
style={{ width: '100%' }} // Set width to 100%
autoComplete="off"
>
<Form.List name="items">
{(fields, { add, remove }) => (
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
{fields.map((field, index) => (
<div key={field.key}>
<Typography.Text strong style={{ marginBottom: 8 }}>
{t("Information")}
</Typography.Text>
{/* Nested Form.List for sub-items */}
<Form.Item>
<Form.List name={[field.name, 'list']}>
{(subFields, subOpt) => (
<div style={{ display: 'flex', flexDirection: 'column', rowGap: 16 }}>
{subFields.map((subField) => (
<Space key={subField.key}>
<Form.Item noStyle name={[subField.name, 'key']}>
<Input
placeholder={t("key")}
onChange={handleChange} // Assign onChange handler
name={`${subField.name}.key`} // Ensure proper name for dynamic state update
/>
</Form.Item>
<Form.Item noStyle name={[subField.name, 'Description']}>
<Input
placeholder={t("Description")}
onChange={handleChange} // Assign onChange handler
name={`${subField.name}.Description`} // Ensure proper name for dynamic state update
/>
</Form.Item>
<CloseOutlined
onClick={() => {
subOpt.remove(subField.name);
}}
/>
</Space>
))}
<Button type="dashed" onClick={() => subOpt.add()} block>
{t("+ Add Another Item")}
</Button>
</div>
)}
</Form.List>
</Form.Item>
</div>
))}
</div>
)}
</Form.List>
</Form>
);
};
export default ObjectField

View File

@ -1,60 +0,0 @@
import React from 'react';
import { Select } from 'antd';
import { useTranslation } from 'react-i18next';
interface SearchTabsProps {
value: string;
onChange:any
name:any
}
const SearchTabs: React.FC<SearchTabsProps> = ({ value, onChange ,name}) =>{
const [t] = useTranslation()
return (
<div className='SellectTab'>
<label className="tabstext"> {t(`${name}`)} </label>
<Select
showSearch
style={{ width: "100%" }}
placeholder="Search to Select"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={onChange}
value={value}
options={[
{
value: '1',
label: 'label 1',
},
{
value: '2',
label: 'label 2',
},
{
value: '3',
label: 'label 3',
},
{
value: '4',
label: 'label 4',
},
{
value: '5',
label: 'label 5',
},
{
value: '6',
label: 'label 6',
},
]}
/>
</div>
);
}
export default SearchTabs;

View File

@ -1,41 +0,0 @@
import { Form, Select } from 'antd'
import { useFormikContext } from 'formik';
import React from 'react'
import { useTranslation } from 'react-i18next';
const SelectField = ({tabKey,option,name,id,label}: any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const Formikname = `variable[${tabKey}].${name}`;
const FormikValue = formik?.values?.variable[tabKey]?.[name];
const onChange = (value:any) => {
formik.setFieldValue(Formikname,[ {
attribute_value_id:value,
attribute_id:id
}])
console.log(value);
};
return (
<div className='ValidationField'>
<label className="text">
{t(`${label}`)}
</label>
<Select
placeholder={t(`${label}`)}
options={option}
size="large"
className={` w-100`}
defaultValue={FormikValue?.attribute_value_id}
allowClear
onChange={onChange}
/>
</div>
)
}
export default React.memo(SelectField);

View File

@ -1,20 +0,0 @@
// FormItem.tsx
import React from 'react';
import { Input, Label } from 'reactstrap';
interface FormItemProps {
label: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
type?: any
}
export const FormItem: React.FC<FormItemProps> = ({ label, value, onChange ,type = "text"}) => {
return (
<>
<Label className="tabstext">{label}</Label>
<Input value={value} type={type} onChange={onChange} />
</>
);
};

View File

@ -1,13 +0,0 @@
// TabItem.tsx
import React from 'react';
import { VariableTabs } from './VariableTabs';
interface TabItemProps {
UKey: any;
}
export const TabItem: React.FC<TabItemProps> = ({ UKey }) => {
return (
<VariableTabs tabKey={UKey} />
);
};

View File

@ -1,116 +0,0 @@
// TabsContainer.tsx
import React, { useEffect, useState } from 'react';
import { Tabs, Space } from 'antd';
import { CopyOutlined } from '@ant-design/icons';
import { TabItem } from './TabItem';
import { toast } from 'react-toastify';
import { FormikContext, FormikValues, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
const { TabPane } = Tabs;
const initialItemShape: any = {
label: 'variable 1',
key: '1',
closable: true,
};
export const TabsContainer: React.FC = () => {
const [activeKey, setActiveKey] = useState('1');
// const [items, setItems] = useState<TabItem[]>([]);
const [t] = useTranslation()
const { setFieldValue } = useFormikContext();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const [width, setWidth] = useState(window.innerWidth);
const varianCount = values?.variable?.slice(1).map((item:any,index:any)=>{
return {
label: `${t(`variable`)}`+ `${index+1}`,
key: index+1,
closable: true,
}
})
const [items, setItems] = useState(varianCount);
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `variable ${newKey}`, closable: true }]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item:any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `variable ${newKey}` };
setItems([...items, newItem]);
setActiveKey(newKey);
const originalValues = values?.variable?.[targetKey];
setFieldValue(`variable.${newKey}`, originalValues);
const originalInfo = values?.info?.[targetKey];
console.log(originalInfo);
setFieldValue(`info.${newKey}`, originalInfo);
}
};
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item:any) => item.key !== targetKey);
if (newItems.length > 0) {
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
} else {
toast.error("Cannot close the last tab");
}
};
useEffect(() => {
const handleResize = () => {
setWidth(window.innerWidth);
};
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
const tabPosition = width > 1000 ? 'left' : 'top';
return (
<Tabs
type="editable-card"
onChange={setActiveKey}
activeKey={activeKey}
onEdit={(targetKey:any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
tabPosition={tabPosition}
>
{items.map((item :any) =>{
return (
<TabPane
key={item?.key}
tab={
<Space>
{t(`${item.label}`)}
<CopyOutlined onClick={() => handleDuplicate(item.key)} />
</Space>
}
closable={item.closable}
>
<TabItem UKey={item?.key} />
</TabPane>
)
})}
</Tabs>
);
};

View File

@ -1,71 +0,0 @@
// VariableTabs.tsx
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Col, Row } from 'reactstrap';
import { FormItem } from './FormItem';
import { useFormikContext, FormikValues } from 'formik';
import File from './Field/File';
import MaltyFile from './Field/FileImage';
import Select from './Field/Select';
import ObjectField from './Field/Object';
import Atteibute from './Field/Atteibute';
interface VariableTabsProps {
tabKey: string;
}
export const VariableTabs: React.FC<VariableTabsProps> = ({ tabKey }) => {
const { t } = useTranslation();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const handleFieldChange = (fieldName: string) => (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement> | any
) => {
handleChange(`variable.${tabKey}.${fieldName}`)(e); // Prepend "variable"
};
const FormikName = (FormikFieldname: any) => values?.variable?.[tabKey]?.[FormikFieldname];
return (
<>
<h5>variables {tabKey}</h5>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Col>
<FormItem
label={t(`name`)}
value={FormikName("name")}
onChange={handleFieldChange('name')}
/>
{values?.other_attributes &&
<Atteibute data={values?.other_attributes} tabKey={tabKey} />
}
<ObjectField tabKey={tabKey}/>
</Col>
<Col>
<FormItem
label={t(`description`)}
value={FormikName("description")}
onChange={handleFieldChange('description')}
/>
<FormItem
label={t(`price`)}
value={FormikName("price")}
onChange={handleFieldChange('price')}
type="number"
/>
<File tabKey={tabKey}/>
<MaltyFile tabKey={tabKey}/>
</Col>
</Row>
</>
);
};

View File

@ -1,13 +0,0 @@
import React, { useState } from 'react'
import { TabsContainer } from './FormikTab/TabsContainer'
const VarianInfo = () => {
return (
<div className='VarianInfo'>
<TabsContainer/>
</div>
)
}
export default VarianInfo

View File

@ -4,100 +4,289 @@ 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 BasicInfo from './Edit/BasicInfo';
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
import { useParams } from 'react-router-dom';
import LoadingPage from '../../../Layout/app/LoadingPage';
import { useTranslation } from 'react-i18next';
import { BsInfoCircle } from 'react-icons/bs';
import { useGetOneProduct, useUpdateProduct, useUpdateProductVariation } from '../../../api/product';
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
import VarianInfo from './Edit/VarianInfo';
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';
const ViewProduct = () => {
const { setObjectToEdit, objectToEdit } = usePageState()
const { t } = useTranslation();
const { id } = useParams()
const { data , isLoading,isRefetching} = useGetOneProduct({ id: id })
const [Data, setData] = useState([])
const { mutate, isSuccess } = useUpdateProduct()
const { mutate: AddVariation, isSuccess: SuccessVariation } = useUpdateProductVariation()
const [infotaps, setInfoTaps] = useState<any[]>([])
const { data, isLoading, isRefetching } = useGetOneProduct({ id: id })
const [OldData, setOldData] = useState(data?.data?.products)
const { mutate, isSuccess } = useUpdateProduct('put')
const { mutate: UpdateVariation, isSuccess: UpdetedSuccessVariation } = useUpdateProductVariation()
const { mutate: AddVariation, isSuccess: AddedSuccessVariation, data: ProductVariationData } = useAddProductVariation()
const { mutate: DeleteVariation } = useDeleteProductVariation()
const [removedVariant, setremovedVariant] = useState<any[]>([])
const [Variant, setVariant] = useState<any>([])
const [InfoTaps, setInfoTaps] = useState<any>([])
const [Varibletaps, setVaribleTaps] = useState<any[]>([])
const handleSubmit = (values: any) => {
setInfoTaps(values?.info?.slice(1)?.map((taps: any) => {
return (changeShapeInfo(taps));
}));
setVaribleTaps(values?.variable?.slice(1))
mutate({
name: values?.name,
category_id: 1
// Update removedVarianteValues state
console.log(values, "values");
function isValid() {
setremovedVariant(values?.removedVariant);
const variables = values?.variable?.slice(1);
if (variables) {
variables.forEach((item: any, index: number) => {
setVariant((prevEditAttribute: any) => [...prevEditAttribute, item]);
})
};
const newData = {
name: {
en: values?.name_en,
ar: values?.name_ar,
de: values?.name_de
},
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);
}
}
});
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 baseProductId = id;
Variant?.map((dataToSend: any, index: number) => {
console.log(dataToSend, "dataToSend");
const varible = dataToSend
const info = infotaps[index]
const jsonString = JSON.stringify(info);
const Newproduct : any = {
name: varible?.name,
description: varible?.description,
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");
const convertedArray = info.reduce((acc:any, obj:any) => {
acc[obj.Description] = obj.key;
return acc;
}, {});
const jsonString = JSON.stringify(convertedArray);
console.log(jsonString, "jsonStringinfo");
const Editedproduct = {
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,
product_attributes: [
{ attribute_value_id: 1, attribute_id: 1 }
],
base_product_id: baseProductId
price: varible?.price,
product_attributes: varible?.attribute?.map((item: any, index: any) => {
return { attribute_value_id: item?.value, attribute_id: item?.id }
}),
}
if (data?.product?.images !== varible?.images) {
Newproduct.images = varible?.images ;
if (foundObject) {
Object.keys(Editedproduct).forEach((propName: any) => {
if (foundObject.hasOwnProperty(propName)) {
const foundValue = foundObject[propName];
//@ts-ignore
const editedValue = Editedproduct[propName];
if (foundValue === editedValue) {
//@ts-ignore
delete Editedproduct[propName];
}
if (data?.product?.main_photo?.replace("public", "/storage") !== varible?.main_photo) {
Newproduct.main_photo = varible?.main_photo ;
console.log(data?.product?.main_photo?.replace("public", "/storage"));
}
});
if (foundObject.name &&
foundObject.name.en === Editedproduct.name.en &&
foundObject.name.ar === Editedproduct.name.ar &&
foundObject.name.de === Editedproduct.name.de) {
//@ts-ignore
delete Editedproduct.name;
}
if (foundObject.description &&
foundObject.description.en === Editedproduct.description.en &&
foundObject.description.ar === Editedproduct.description.ar &&
foundObject.description.de === Editedproduct.description.de) {
//@ts-ignore
delete Editedproduct.description;
}
Object.keys(Editedproduct).forEach((key: any) => {
// Check if the property value is undefined
//@ts-ignore
if (Editedproduct[key] === undefined) {
// Remove the property
//@ts-ignore
delete Editedproduct[key];
}
});
if (convertedArray && foundObject.info) {
const editedInfoKeys = Object.keys(convertedArray);
const foundInfoKeys = Object.keys(foundObject.info);
console.log(editedInfoKeys,"editedInfoKeys");
console.log(foundInfoKeys,"foundInfoKeys");
// 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] ");
console.log(foundObject.info[key],"foundObject.info[key]");
return convertedArray[key] === foundObject.info[key];
});
if (keysAreEqual) {
// Remove the info property from Editedproduct
//@ts-ignore
delete Editedproduct.info;
}
}
}
if (Object.keys(Editedproduct).length > 0) {
//@ts-ignore
Editedproduct._method = "PUT";
//@ts-ignore
Editedproduct.id = foundObject?.id;
console.log(Editedproduct, "Editedproduct");
UpdateVariation(Editedproduct)
}
}
} else {
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,
base_product_id: id,
product_attributes: varible?.attribute?.map((item: any, index: any) => {
return { attribute_value_id: item?.value, attribute_id: item?.id }
}),
}
AddVariation(Newproduct)
}
})
console.log(removedVariant);
removedVariant?.map((item: any) => {
return DeleteVariation({ id: item })
})
}
}, [isSuccess])
useNavigateOnSuccess(isSuccess, '/products')
// useNavigateOnSuccess(UpdetedSuccessVariation || AddedSuccessVariation, '/products')
useEffect(() => {
// refetch()
setObjectToEdit(data?.data);
}, [data,id,isRefetching]);
setOldData(data?.data?.products)
}, [data, id, isRefetching]);
const getValidationSchema = () => {
return null
};
if(isRefetching){
return <Spin/>
if (isRefetching) {
return <Spin />
}
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
@ -119,7 +308,7 @@ const ViewProduct = () => {
<div className=" mt-4"><BasicInfo /></div>
</TabBody>
<TabBody >
<div className=" mt-4"> {isLoading ? <Spin/> : <VarianInfo />} </div>
<div className=" mt-4"> {isLoading ? <Spin /> : <TabsContainer />} </div>
</TabBody>
</Tabs>

View File

@ -2,33 +2,58 @@ import React from 'react';
import { useFormikContext } from 'formik';
import ValidationField from '../../../../../Components/ValidationField/ValidationField';
import { useGetSingleAttribute } from '../../../../../api/attribute';
import { Select } from 'antd';
import { useTranslation } from 'react-i18next';
const Attribute = ({tabKey}:any) => {
const Attribute = ({ tabKey }: any) => {
const { values, setFieldValue } = useFormikContext<any>();
const language = localStorage.getItem("language") ?? "en";
const [t] = useTranslation()
const { data: attributeData } = useGetSingleAttribute({ name: "category_id", id: values?.category_id });
const handleAttributeChange = (name: string, value: any) => {
setFieldValue(`variable.${tabKey}.attribute"[${name}]`, value);
const handleAttributeChange = (value: any, option: any) => {
setFieldValue(`variable[${tabKey}].attribute`, option);
};
return (
attributeData?.data?.map((item: any) => {
const options = item?.attribute_value?.map((attr: any) => ({
label: attr?.value,
value: attr?.attribute_id
const uniqueOptionsMap = new Map();
item?.attribute_value.forEach((attr: any) => {
if (!uniqueOptionsMap.has(attr.value[language])) {
uniqueOptionsMap.set(attr.value[language], { attribute_id: attr.attribute_id, id: attr.id });
}
});
const options = Array.from(uniqueOptionsMap.entries()).map(([label, value]) => ({
label,
value: value.attribute_id, // Change value to attribute_id
id: value.id, // Include id in the option
}));
return (
<ValidationField
key={item?.name}
name={`attribute[${item?.name}]`}
label={item?.name}
placeholder={item?.name}
type="Select"
option={options}
onChange={(value: any) => handleAttributeChange(item?.name, value)}
<div className='ValidationField'>
<label htmlFor={item?.name[language]} className="text">
{t(`${item?.name[language]}`)}
<Select
placeholder={t(`${item?.name[language]}`)}
options={options}
size="large"
className={`w-100`}
defaultValue={values?.variable[tabKey]?.attribute}
allowClear
mode={"multiple" }
onChange={handleAttributeChange}
/>
</label>
</div>
);
})
);

View File

@ -12,16 +12,16 @@ const File = ({ tabKey}:any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `variable[${tabKey}].${"main_photo"}`;
const imageUrl = formik?.values?.variable[tabKey]?.main_photo ? URL.createObjectURL(formik?.values?.variable[tabKey]?.main_photo) : "" ;
let FormikName = formik.values?.variable[tabKey]?.main_photo;
const imageUrl = FormikName ? ImageBaseURL + FormikName : '';
const fileList: UploadFile[] = [
{
uid: '-1',
name: formik?.values?.variable[tabKey]?.main_photo?.name ?? "",
name: '',
status: 'done',
url: imageUrl ,
thumbUrl: imageUrl ,
url: imageUrl?.replace("public", "/storage"),
thumbUrl: imageUrl?.replace("public", "/storage")
}
];
const FilehandleChange = (value:any) => {

View File

@ -1,25 +1,34 @@
import { Button, Upload, UploadFile } from 'antd';
import { Button, Upload } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { ImageBaseURL } from '../../../../../api/config';
const MaltyFile = ({ tabKey }: any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const name = `variable[${tabKey}].images`;
const name = `variable[${tabKey}].${"images"}`;
const imageFiles = formik.values?.variable?.[tabKey]?.images || [];
const defaultFileList = imageFiles?.map((file: any, index: number) => ({
// Construct imageUrl and fileList for each file
const files = formik.values?.variable[tabKey]?.images || [];
const fileItems = files.map((file: any, index: number) => {
const imageUrl = file ? ImageBaseURL + file : '';
return {
uid: `-${index}`,
name: file?.name, // Use a default name if file.name is undefined
name: file?.name || '',
status: 'done',
url: file ? URL?.createObjectURL(file) : "",
thumbUrl: file ?URL?.createObjectURL(file):"",
}));
url: imageUrl?.replace("public", "/storage"),
thumbUrl: imageUrl?.replace("public", "/storage")
};
});
const FilehandleChange = ({ fileList }: { fileList: any }) => {
formik.setFieldValue(name, fileList.map((file: any) => file?.originFileObj));
};
console.log(fileList);
formik.setFieldValue(
name,
fileList.map((file: any) => (file?.originFileObj ? file.originFileObj : file.url))
); };
const customRequest = async ({ onSuccess }: any) => {
onSuccess();
@ -32,7 +41,7 @@ const MaltyFile = ({ tabKey }: any) => {
</label>
<Upload
listType="picture"
defaultFileList={defaultFileList}
defaultFileList={fileItems}
onChange={FilehandleChange}
customRequest={customRequest}
className="w-100"
@ -46,4 +55,4 @@ const MaltyFile = ({ tabKey }: any) => {
);
}
export default MaltyFile;
export default MaltyFile

View File

@ -1,52 +1,41 @@
import React, { useEffect, useState } from 'react';
import { CloseOutlined } from '@ant-design/icons';
import { Button, Card, Form, Input, Space, Typography } from 'antd';
import { Button, Form, Input, Space, Typography } from 'antd';
import { useFormikContext } from 'formik';
import { objectToArray } from '../../../../../utils/Array/ArrayToObjectFormik';
import { useTranslation } from 'react-i18next';
const ObjectField = ({tabKey}:any) => {
const ObjectField = ({ tabKey }: any) => {
const [form] = Form.useForm();
const formik = useFormikContext<any>();
const [FieldItems, setFieldItems] = useState<any>(formik?.values?.info[tabKey])
const [t] = useTranslation()
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
setFieldItems((prevState:any) =>{
formik.setFieldValue(`info.${tabKey}`, {
...prevState,
[name]: value
});
return ({
...prevState,
[name]: value
})
} )
const [FieldItems, setFieldItems] = useState<any>([]);
const [t] = useTranslation();
const initialValues = formik?.values?.variable[tabKey]?.info;
const handleChange = (index: number, fieldKey: string, value: string) => {
const updatedItems = [...FieldItems];
updatedItems[index][fieldKey] = value;
setFieldItems(updatedItems);
formik.setFieldValue(`variable.${tabKey}.info`, updatedItems);
};
useEffect(() => {
if (initialValues) {
setFieldItems([...initialValues]);
} else {
setFieldItems([{ Description: '', key: '' }]);
}
}, [tabKey]); // Update when tabKey or info[tabKey] changes
const removeItem = (index: number) => {
const updatedItems = [...FieldItems];
updatedItems.splice(index, 1);
setFieldItems(updatedItems);
formik.setFieldValue(`variable.${tabKey}.info`, updatedItems);
};
useEffect(() => {
if (formik?.values?.info[tabKey]) {
const defaultValues = formik.values.info[tabKey];
console.log(objectToArray( formik?.values?.info[tabKey]));
form.setFieldsValue({
items: [{ list:objectToArray( formik?.values?.info[tabKey])}]
});
}
else {
form.setFieldsValue({
items: [{ list: [{ key: '', Description: '' }] },], });
}
}, []); // Update when tabKey or info[tabKey] changes
console.log(initialValues);
}, [initialValues])
return (
<Form
@ -57,60 +46,34 @@ const ObjectField = ({tabKey}:any) => {
style={{ width: '100%' }} // Set width to 100%
autoComplete="off"
>
<Form.List name="items">
{(fields, { add, remove }) => (
<div style={{ display: 'flex', rowGap: 16, flexDirection: 'column' }}>
{fields.map((field, index) => (
<div key={field.key}>
<Typography.Text strong style={{ marginBottom: 8 }}>
<Typography.Text strong className='Information'>
{t("Information")}
</Typography.Text>
{FieldItems.map((item: any, index: number) => (
<Space key={index} style={{ marginBottom: 16 }}>
{/* Nested Form.List for sub-items */}
<Form.Item>
<Form.List name={[field.name, 'list']}>
{(subFields, subOpt) => (
<div style={{ display: 'flex', flexDirection: 'column', rowGap: 16 }}>
{subFields.map((subField) => (
<Space key={subField.key}>
<Form.Item noStyle name={[subField.name, 'key']}>
<Input
placeholder={t("key")}
onChange={handleChange} // Assign onChange handler
name={`${subField.name}.key`} // Ensure proper name for dynamic state update
value={item.key}
onChange={(e) => handleChange(index, 'key', e.target.value)}
/>
</Form.Item>
<Form.Item noStyle name={[subField.name, 'Description']}>
<Form.Item>
<Input
placeholder={t("Description")}
onChange={handleChange} // Assign onChange handler
name={`${subField.name}.Description`} // Ensure proper name for dynamic state update
value={item.Description}
onChange={(e) => handleChange(index, 'Description', e.target.value)}
/>
</Form.Item>
<CloseOutlined
onClick={() => {
subOpt.remove(subField.name);
}}
/>
<CloseOutlined onClick={() => removeItem(index)} />
</Space>
))}
<Button type="dashed" onClick={() => subOpt.add()} block>
<Button type="dashed" onClick={() => setFieldItems([...FieldItems, { Description: '', key: '' }])} block>
{t("+ Add Another Item")}
</Button>
</div>
)}
</Form.List>
</Form.Item>
</div>
))}
</div>
)}
</Form.List>
</Form>
);
};
export default ObjectField
export default ObjectField;

View File

@ -1,60 +0,0 @@
import React from 'react';
import { Select } from 'antd';
import { useTranslation } from 'react-i18next';
interface SearchTabsProps {
value: string;
onChange:any
name:any
}
const SearchTabs: React.FC<SearchTabsProps> = ({ value, onChange ,name}) =>{
const [t] = useTranslation()
return (
<div className='SellectTab'>
<label className="tabstext"> {t(`${name}`)} </label>
<Select
showSearch
style={{ width: "100%" }}
placeholder="Search to Select"
optionFilterProp="children"
filterOption={(input, option) => (option?.label ?? '').toLowerCase().includes(input.toLowerCase())}
filterSort={(optionA, optionB) =>
(optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
}
onChange={onChange}
value={value}
options={[
{
value: '1',
label: 'label 1',
},
{
value: '2',
label: 'label 2',
},
{
value: '3',
label: 'label 3',
},
{
value: '4',
label: 'label 4',
},
{
value: '5',
label: 'label 5',
},
{
value: '6',
label: 'label 6',
},
]}
/>
</div>
);
}
export default SearchTabs;

View File

@ -1,41 +0,0 @@
import { Form, Select } from 'antd'
import { useFormikContext } from 'formik';
import React from 'react'
import { useTranslation } from 'react-i18next';
const SelectField = ({tabKey,option,name,id,label}: any) => {
const { t } = useTranslation();
const formik = useFormikContext<any>();
const Formikname = `variable[${tabKey}].${name}`;
const FormikValue = formik?.values?.variable[tabKey]?.[name];
const onChange = (value:any) => {
formik.setFieldValue(Formikname,[ {
attribute_value_id:value,
attribute_id:id
}])
console.log(value);
};
return (
<div className='ValidationField'>
<label className="text">
{t(`${label}`)}
</label>
<Select
placeholder={t(`${label}`)}
options={option}
size="large"
className={` w-100`}
defaultValue={FormikValue?.attribute_value_id}
allowClear
onChange={onChange}
/>
</div>
)
}
export default React.memo(SelectField);

View File

@ -1,13 +0,0 @@
// TabItem.tsx
import React from 'react';
import { VariableTabs } from './VariableTabs';
interface TabItemProps {
UKey: any;
}
export const TabItem: React.FC<TabItemProps> = ({ UKey }) => {
return (
<VariableTabs tabKey={UKey} />
);
};

View File

@ -2,76 +2,105 @@
import React, { useEffect, useState } from 'react';
import { Tabs, Space } from 'antd';
import { CopyOutlined } from '@ant-design/icons';
import { TabItem } from './TabItem';
import { toast } from 'react-toastify';
import { FormikValues, useFormikContext } from 'formik';
import { useTranslation } from 'react-i18next';
import { useProductVarianState } from '../../../../lib/state mangment/Pages/Products';
import { VariableTabs } from './VariableTabs';
const { TabPane } = Tabs;
const initialItemShape: any = {
label: 'variable 1',
export const TabsContainer: React.FC = () => {
const [activeKey, setActiveKey] = useState('1');
const [t] = useTranslation()
const initialItemShape: any = {
label: `${t(`variant`)} 1`,
key: '1',
closable: true,
};
export const TabsContainer: React.FC = () => {
const [activeKey, setActiveKey] = useState('1');
// const [items, setItems] = useState<TabItem[]>([]);
const [items, setItems] = useState([initialItemShape]);
const { setFieldValue } = useFormikContext();
const formikContext = useFormikContext<FormikValues>();
const { values, handleChange } = formikContext;
const [width, setWidth] = useState(window.innerWidth);
// const {setTapItems,TapItems,TapItemValues,setTapItemValues} = useProductVarianState(state => state)
// useEffect(() => {
// setTapItems(items)
// }, [items])
// useEffect(() => {
// setTapItemValues(values?.variable)
// }, [values?.variable])
const { setFieldValue } = useFormikContext();
const { values, handleChange } = formikContext;
const varianCount = values?.variable?.slice(1)?.map((item:any,index:any)=>{
return {
label: `${t(`variant`)}`+ `${index+1}`,
key: index+1,
closable: true,
}
})?? initialItemShape
const [items, setItems] = useState(varianCount ?? [initialItemShape]); // Ensure items is always an array
const [width, setWidth] = useState(window.innerWidth);
const findFirstMissingKey = (itemKeys:string[]) => {
const keysAsNumbers = itemKeys.map(Number); // Convert strings to numbers
for (let i = 1; i <= keysAsNumbers.length + 1; i++) {
if (!keysAsNumbers.includes(i)) {
return i;
}
}
};
const [nextKey, setNextKey] = useState<any>(items?.map((item: any) => `${item.key}`)); // Initialize the key counter to the length of items + 1
useEffect(() => {
// Set the active key to the first tab key when the component mounts or items change
if (items.length > 0) {
setActiveKey(items[0].key);
}
}, []);
useEffect(() => {
const keys = items.map((item: any) => `${item.key}`);
setNextKey(findFirstMissingKey(keys))
}, [items]);
const [t] = useTranslation()
const handleAdd = () => {
const newKey = `${items.length + 1}`;
setItems([...items, { key: newKey, label: `variable ${newKey}`, closable: true }]);
const newKey = `${nextKey}`;
setItems([...items, { key: newKey, label: `${t(`variant`)} ${newKey}`, closable: true }]);
setActiveKey(newKey);
};
const handleDuplicate = (targetKey: string) => {
const targetItem = items.find((item) => item.key === targetKey);
const targetItem = items.find((item:any) => item.key === targetKey);
if (targetItem) {
const newKey = `${items.length + 1}`;
const newItem = { ...targetItem, key: newKey, label: `variable ${newKey}` };
const newKey = `${nextKey}`;
const newItem = { ...targetItem, key: newKey, label: `${t(`variant`)} ${newKey}` };
setItems([...items, newItem]);
setActiveKey(newKey);
const originalValues = values?.variable?.[targetKey];
setFieldValue(`variable.${newKey}`, originalValues);
setFieldValue(`variable.${newKey}`, {...originalValues,id:null});
const originalInfo = values?.info?.[targetKey];
console.log(originalInfo);
setFieldValue(`info.${newKey}`, originalInfo);
const originalvariable = values?.variable[targetKey]?.variable;
setFieldValue(`variable.${newKey}.variable`, originalvariable);
}
};
const [removedVariant, setremovedVariant] = useState<string[]>([]);
useEffect(() => {
setFieldValue(`removedVariant`, removedVariant);
}, [removedVariant]);
const handleRemove = (targetKey: string) => {
const newItems = items.filter((item) => item.key !== targetKey);
if (newItems.length > 0) {
const newItems = items.filter((item:any) => item.key !== targetKey);
const removedItem = values?.variable[targetKey] as any;
if (removedItem?.id) {
setremovedVariant((prevRemovedvariable) => [...prevRemovedvariable, removedItem.id]);
}
const newActiveKey = newItems.length ? newItems[newItems.length - 1].key : '1';
setItems(newItems);
setActiveKey(newActiveKey);
setFieldValue(`variable.${targetKey}`, undefined);
setFieldValue(`info.${targetKey}`, undefined);
} else {
toast.error("Cannot close the last tab");
}
};
useEffect(() => {
@ -88,31 +117,29 @@ useEffect(() => {
const tabPosition = width > 1000 ? 'left' : 'top';
return (
<>
<Tabs
type="editable-card"
onChange={setActiveKey}
activeKey={activeKey}
onEdit={(targetKey:any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
onEdit={(targetKey: any, action) => (action === 'add' ? handleAdd() : handleRemove(targetKey))}
tabPosition={tabPosition}
>
{items.map((item :any) =>{
return (
<TabPane
key={item?.key}
tab={
<Space>
{t(`${item.label}`)}
<CopyOutlined onClick={() => handleDuplicate(item.key)} />
</Space>
items={
items.map((item: any) => ({
label: <Space>{t(`${item.label}`)} <CopyOutlined onClick={() => handleDuplicate(item.key)} /></Space>,
children: <VariableTabs tabKey={item.key} />,
key: item.key,
closable: item.closable,
}))
}
closable={item.closable}
>
<TabItem UKey={item?.key} />
</TabPane>
)
})}
</Tabs>
{ items.length === 0 && (
<h6 className='AddNewTabText'>{t("Add New Variant")}</h6>
)}
</>
);
};

View File

@ -7,6 +7,7 @@ import File from './Field/File';
import MaltyFile from './Field/FileImage';
import ObjectField from './Field/Object';
import Atteibute from './Field/Atteibute';
import { useTranslation } from 'react-i18next';
interface VariableTabsProps {
@ -59,6 +60,7 @@ export const VariableTabs: React.FC<VariableTabsProps> = ({ tabKey }) => {
{values?.category_id &&
<Atteibute tabKey={tabKey} />
}
<ObjectField tabKey={tabKey} />
</Col>
<Col>

View File

@ -1,13 +0,0 @@
import React, { useState } from 'react'
import { TabsContainer } from './FormikTab/TabsContainer'
const VarianInfo = () => {
return (
<div className='VarianInfo'>
<TabsContainer/>
</div>
)
}
export default VarianInfo

View File

@ -1,50 +1,63 @@
import * as Yup from "yup";
import { ImageBaseURL } from "../../api/config";
export const getInitialValues = (objectToEdit: any | null = null) => {
const product = Array.isArray(objectToEdit?.product) ? objectToEdit?.product.map((item: any) => ({
name: item?.name,
description: item?.description,
export const getInitialValues = (objectToEdit: any) => {
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,
}));
return ({
name_ar: item?.name["ar"],
name_en: item?.name["en"],
name_de: item?.name["de"],
description_ar: item?.description["ar"],
description_en: item?.description["en"],
description_de: item?.description["de"],
images: item?.images,
main_photo: item?.main_photo,
price: item?.price,
quantity: item?.quantity,
product_attributes: item?.product_attributes,
})) : (
{
...objectToEdit?.product,
main_photo: objectToEdit?.product?.main_photo?.replace("public", "/storage"),
products_attributes: item?.products_attributes,
id:item?.id,
info:formattedData
}
);
console.log(product, "product");
})
})
const productInfo = objectToEdit?.product?.info || {}; // Ensure product.info exists and initialize as an empty object if it doesn't
const formattedData = Object.entries(productInfo).map(([key, value], index) => ({
const productsInfo = objectToEdit?.products?.info || {};
const formattedData = Object.entries(productsInfo).map(([key, value], index) => ({
[`${index}.Description`]: key,
[`${index}.key`]: value,
}));
const info = [undefined, ...formattedData];
return {
id: objectToEdit?.id ?? 0,
id:objectToEdit?.id,
name: objectToEdit?.name ?? "",
name_ar: objectToEdit?.name?.ar ?? '',
name_en: objectToEdit?.name?.en ?? '',
name_de: objectToEdit?.name?.de ?? '',
description: objectToEdit?.description ?? '',
price: objectToEdit?.price ?? "",
images: objectToEdit?.images ?? "",
attribute: objectToEdit?.attribute ?? "",
description_ar: objectToEdit?.description?.ar ?? '',
description_en: objectToEdit?.description?.en ?? '',
description_de: objectToEdit?.description?.de ?? '',
// attribute: objectToEdit?.attribute ?? "",
category_id: objectToEdit?.category?.id ?? "",
variable: [{}, product ?? {}],
price: objectToEdit?.price ?? "",
variable: [{}, ...products],
info: [undefined, ...formattedData] ?? [],
removedVariant:[],
}
};
@ -56,13 +69,14 @@ export const getInitialValuesAdd = (objectToEdit: any | null = null) => {
name_ar:'',
name_en: '',
name_de: '',
description: '',
description_ar:'',
description_en: '',
description_de: '',
price: "",
images: "",
attribute: "",
category_id: "",
variable: [],
info: [],
}
};
@ -75,6 +89,7 @@ export const getValidationSchema = (editMode: boolean = false) => {
category_id: Yup.string().required('Required'),
});
};

View File

@ -25,6 +25,7 @@ const useTableColumns :any = () => {
toggleMutation.mutate({id:row?.id,new_status:status})
}
const language = localStorage.getItem("language") ?? "en"
return useMemo(
() => [
@ -32,7 +33,7 @@ const useTableColumns :any = () => {
name: t("name"),
sortable: false,
center: true,
selector:(row:any) => row?.name,
selector:(row:any) => row?.name?.[language],
},
{
@ -48,7 +49,7 @@ const useTableColumns :any = () => {
sortable: false,
center: true,
cell: (row:any) => (
row?.category?.name
row?.category?.name?.[language]
),
},

View File

@ -15,7 +15,6 @@ function Page() {
const column =useTableColumns()
const {data ,status } = useGetSlider()
console.log(data);
const [t] = useTranslation()
const navigate = useNavigate()
const totalRows = data?.meta?.total;
@ -25,7 +24,7 @@ function Page() {
<DashBody status={status as QueryStatusEnum} >
<DashHeader showAddButton={false} title={'slider'}>
<div className='RightSide d-flex gap-2 align-center '>
<SearchField />
<SearchField searchBy={"title"} />
<AddButton onClick={()=>navigate('/slider/add')}></AddButton>
</div>

View File

@ -21,12 +21,14 @@ function Form() {
<Col>
<ValidationField name="state" type='Select' option={stateSelect} />
<ValidationField name="delivery_link" />
</Col>
<Col>
<ValidationField name="admin_note" />
<ValidationField name="deliviration_estimated_time" Format="YYYY-MM-DD HH:MM:SS" type='Date' />
</Col>

View File

@ -5,7 +5,7 @@ import 'react-tabs/style/react-tabs.css';
import { MdLanguage } from 'react-icons/md'
import { FaSadCry } from 'react-icons/fa'
import ViewPage from '../../../Layout/Dashboard/ViewPage';
import { Rate } from 'antd';
import { Rate, Spin } from 'antd';
import { usePageState } from '../../../lib/state mangment/LayoutPagestate';
import { useParams } from 'react-router-dom';
import LoadingPage from '../../../Layout/app/LoadingPage';
@ -14,37 +14,24 @@ import { BsInfoCircle } from 'react-icons/bs';
import { useGetOneSlider, useUpdateSlider } from '../../../api/Slider';
import useNavigateOnSuccess from '../../../Hooks/useNavigateOnSuccess';
import Form from './EditForm';
import { useGetOneOrder } from '../../../api/order';
import { useGetOneOrder, useUpdateOrder } from '../../../api/order';
const EditPage = () => {
const { setObjectToEdit, objectToEdit } = usePageState()
const {t} = useTranslation();
const {mutate ,isSuccess} = useUpdateSlider()
const {mutate ,isSuccess} = useUpdateOrder("put")
const { id } = useParams();
const { data, isLoading } = useGetOneOrder({id: id })
const FormatedData = data?.data ;
const handleSubmit = (values:any)=>{
const newData = {} as any;
for (const key in FormatedData) {
if (values[key] !== FormatedData[key]) {
newData[key] = values[key];
}
}
return mutate(newData);
return mutate(values);
}
useNavigateOnSuccess(isSuccess , '/order')
useEffect(() => {
console.log(data);
setObjectToEdit(data?.data);
@ -57,6 +44,9 @@ const EditPage = () => {
const ViewProps = { getInitialValues, getValidationSchema, getDataToSend, handleSubmit };
if ( isLoading || !objectToEdit) {
return <Spin />
}
return (

View File

@ -20,11 +20,13 @@ interface ValidateSchema extends formUtilCommon{
}
export const getInitialValues = (objectToEdit: any | null = null): any => {
console.log(objectToEdit,"objectToEdit");
// console.log(objectToEdit,"objectToEdit");
return {
id: objectToEdit?.id ?? 0,
state:objectToEdit?.state ?? "",
admin_note: objectToEdit?.admin_note ?? '',
deliviration_estimated_time:objectToEdit?.deliviration_estimated_time ??"",
delivery_link:objectToEdit?.delivery_link ??"",
};
};

View File

@ -30,7 +30,7 @@ const OrderPage = () => {
<DashBody status={status as QueryStatusEnum} >
<DashHeader title="orders" showAddButton={false}>
<div className='RightSide d-flex gap-2 align-center '>
<SearchField />
<SearchField searchBy="username" />
</div>
</DashHeader>
<LyTable

View File

@ -15,6 +15,8 @@ const useTableColumns = () => {
const [t] = useTranslation();
const navigate = useNavigate()
const deleteMutation = useDeleteOrder()
const language = localStorage.getItem("language") ?? "en"
let column = [
{
@ -39,7 +41,7 @@ const useTableColumns = () => {
name: t("name"),
sortable: false,
center:true,
selector:(row:any) => row?.user?.name,
selector:(row:any) => row?.user?.name[language],
},
{

View File

@ -4,6 +4,8 @@ import ColumnsImage from '../../../Components/Columns/ColumnsImage';
import { mapTranslatedProperties } from '../../../utils/language/mapTranslatedProperties';
export default function useTableColumns() {
const [t] = useTranslation();
const language = localStorage.getItem("language") ?? "en"
return [
{
name: t("id"),
@ -16,7 +18,7 @@ export default function useTableColumns() {
name: `${t('name')}`,
sortable: true,
center: true,
cell:(row) => row.name
cell:(row) => row.name[language]
},
{

View File

@ -506,3 +506,42 @@ padding: 10px 40px;
display: none;
}
}
.AddNewTabText{
text-wrap: nowrap !important;
margin-left: 60px;
transform: translateY(-30px);
}
/* Dynamic form complex */
#dynamic_form_complex{
margin-bottom:5px;
}
/* Ant space gap col small */
#dynamic_form_complex .ant-space-gap-col-small{
margin-bottom:-9px !important;
transform:translatex(0px) translatey(0px);
}
/* Ant space item */
#dynamic_form_complex .ant-space-gap-col-small .ant-space-item{
margin-bottom:6px;
}
/* Span Tag */
#dynamic_form_complex .ant-space-item span{
transform: translatex(-13px) translatey(-12px);
}
#dynamic_form_complex .ant-space-gap-col-small {
width: 100%;
}
.Information{
margin-block: 20px;
}
:where(.css-dev-only-do-not-override-6j9yrn).ant-form{
overflow-x: hidden;
}

View File

@ -91,3 +91,11 @@
margin-left:12px;
}
}
.react-tabs .react-tabs__tab-panel--selected .mt-4 .d-flex .ant-tabs-left{
width:100% !important;
}
:where(.css-dev-only-do-not-override-6j9yrn).ant-tabs {
width:100% !important;
}

View File

@ -21,6 +21,6 @@ export const useGetCategories = (params?:any) => useGetQueryPagination(KEY, API.
export const useGetOneCategories = () => useGetOneQuery(KEY, API.GET_ALL);
export const useAddCategories = () => useAddMutation(KEY, API.ADD);
export const useUpdateCategories = (method?:any) => useUpdateMutationPost(KEY, API.UPDATE,method);
export const useUpdateCategories = (method?:any) => useUpdateMutationPost(KEY, API.UPDATE,true,method);
export const useDeleteCategories = () =>useDeleteMutation(KEY, API.DELETE);

View File

@ -20,6 +20,6 @@ export const useGetCoupon = (params?:any) => useGetQueryPagination(KEY, API.GET_
export const useGetOneCoupon = () => useGetOneQuery(KEY, API.GET_ALL);
export const useAddCoupon = () => useAddMutation(KEY, API.ADD);
export const useUpdateCoupon = (method?:any) => useUpdateMutation(KEY, API.UPDATE,method);
export const useUpdateCoupon = (method:any) => useUpdateMutation(KEY, API.UPDATE,true,method);
export const useDeleteCoupon = () =>useDeleteMutation(KEY, API.DELETE);

View File

@ -6,6 +6,7 @@ import useGetOneQuery from "./helper/useGetOneQuery";
import useGetQuery from "./helper/useGetQuery"
import useGetSingleQuery from "./helper/useGetSingleQuery";
import useUpdateMutation from "./helper/useUpdateMutation";
import useUpdateMutationById from "./helper/useUpdateMutationById";
const API = {
ADD: `attribute`,
@ -16,6 +17,7 @@ const API = {
};
const KEY = "ATTRIBUTE"
const KEY2 = "ATTRIBUTEValue"
export const useGetAttribute = (params?:any) => useGetQueryPagination(KEY, API.GET_ALL,params);
@ -24,7 +26,7 @@ export const useGetSingleAttribute = (params?:any,options?:any) => useGetSingleQ
export const useAddAttribute = () => useAddMutation(KEY, API.ADD);
export const useUpdateAttribute = () => useUpdateMutation(KEY, API.UPDATE);
export const useUpdateAttributeStatus = () => useUpdateMutation(KEY, API.UPDATE);
export const useUpdateAttribute = (method:any) => useUpdateMutationById(KEY, API.UPDATE,false,method);
export const useUpdateAttributeStatus = () => useUpdateMutation(KEY, API.UPDATE,false);
export const useDeleteAttribute = () =>useDeleteMutation(KEY, API.DELETE);

View File

@ -6,6 +6,7 @@ import useGetOneQuery from "./helper/useGetOneQuery";
import useGetQuery from "./helper/useGetQuery"
import useGetSingleQuery from "./helper/useGetSingleQuery";
import useUpdateMutation from "./helper/useUpdateMutation";
import useUpdateMutationById from "./helper/useUpdateMutationById";
const API = {
ADD: `attributeValue`,
@ -24,7 +25,7 @@ export const useGetSingleAttributeValue = (params?:any) => useGetSingleQuery(KEY
export const useAddAttributeValue = () => useAddMutation(KEY, API.ADD);
export const useUpdateAttributeValue = () => useUpdateMutation(KEY, API.UPDATE);
export const useUpdateAttributeValue = () => useUpdateMutationById(KEY, API.UPDATE);
export const useUpdateAttributeValueStatus = () => useUpdateMutation(KEY, API.UPDATE);
export const useDeleteAttributeValue = () =>useDeleteMutation(KEY, API.DELETE);

View File

@ -1,55 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
exports.__esModule = true;
exports.useUpdateMyAccount = exports.getDataToSend = exports.useDeleteAccount = exports.useChangePassword = exports.useUpdateAccount = exports.useAddAccount = exports.useUpdateWallet = exports.useGetWallet = exports.useGetAccounts = void 0;
var RoleConfige_1 = require("../config/RoleConfige");
var buildFormData_1 = require("./helper/buildFormData");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetQuery_1 = require("./helper/useGetQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
GET: "/api/admin/account/all",
GET_ALL_PER: "/api/admin/role/all-permissions",
GET_ALL_ROLE: "/api/admin/role/all",
ADD: "/api/admin/account/create",
GETWALLET: "/api/admin/account/get-wallet",
UPDATEWALLET: "/api/admin/account/add-to-wallet",
UPDATE: "/api/admin/account/update",
DELETE: "/api/admin/account/delete",
UPDATE_MY_ACCOUNT: "/api/admin/account/update-my-account",
UPDATE_PASSWORD: "/api/admin/account/change-password"
};
var KEY = "ADMINS";
var MY_ACCOUNT = "MY_ACCOUNT";
exports.useGetAccounts = function () { return useGetQuery_1["default"](MY_ACCOUNT, API.GET); };
exports.useGetWallet = function () { return useGetQuery_1["default"]("WALLET", API.GETWALLET); };
exports.useUpdateWallet = function () { return useAddMutation_1["default"]("WALLET", API.UPDATEWALLET); };
exports.useAddAccount = function () { return useAddMutation_1["default"](MY_ACCOUNT, API.ADD); };
exports.useUpdateAccount = function () { return useUpdateMutation_1["default"](MY_ACCOUNT, API.UPDATE); };
exports.useChangePassword = function () { return useUpdateMutation_1["default"](MY_ACCOUNT, API.UPDATE_PASSWORD); };
exports.useDeleteAccount = function () { return useDeleteMutation_1["default"](MY_ACCOUNT, API.DELETE); };
exports.getDataToSend = function (values, editMode, objectToEdit) {
var formData = new FormData();
var objectToSend = __assign(__assign({}, values), (editMode && { account_id: objectToEdit.id }));
if (editMode) {
delete objectToSend["password"];
delete objectToSend["password_confirmation"];
}
if (values.role !== RoleConfige_1.VENDOR) {
delete objectToSend["shop_id"];
}
buildFormData_1.buildFormData(formData, objectToSend);
return formData;
};
exports.useUpdateMyAccount = function () { return useUpdateMutation_1["default"](MY_ACCOUNT, API.UPDATE_MY_ACCOUNT); };

View File

@ -1,20 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteCategories = exports.useUpdateCategories = exports.useAddCategories = exports.useGetOneCategories = exports.useGetCategories = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutationPut_1 = require("./helper/useUpdateMutationPut");
var API = {
ADD: "category",
GET_ALL: "category",
DELETE: "category",
UPDATE: "category"
};
var KEY = "CATEGORIES";
exports.useGetCategories = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneCategories = function () { return useGetOneQuery_1["default"](KEY, API.GET_ALL); };
exports.useAddCategories = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateCategories = function (method) { return useUpdateMutationPut_1["default"](KEY, API.UPDATE, method); };
exports.useDeleteCategories = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

View File

@ -1,20 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteCoupon = exports.useUpdateCoupon = exports.useAddCoupon = exports.useGetOneCoupon = exports.useGetCoupon = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "coupon",
GET_ALL: "coupon",
DELETE: "coupon",
UPDATE: "coupon"
};
var KEY = "COUPON";
exports.useGetCoupon = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneCoupon = function () { return useGetOneQuery_1["default"](KEY, API.GET_ALL); };
exports.useAddCoupon = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateCoupon = function (method) { return useUpdateMutation_1["default"](KEY, API.UPDATE, method); };
exports.useDeleteCoupon = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

View File

@ -1,20 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteSlider = exports.useUpdateSlider = exports.useAddSlider = exports.useGetOneSlider = exports.useGetSlider = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "slider",
GET_ALL: "slider",
DELETE: "slider",
UPDATE: "slider"
};
var KEY = "SLIDER";
exports.useGetSlider = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneSlider = function () { return useGetOneQuery_1["default"](KEY, API.GET_ALL); };
exports.useAddSlider = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateSlider = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteSlider = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

View File

@ -1,18 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteAppSetting = exports.useUpdateAppSetting = exports.useAddAppSetting = exports.useGetAppSetting = void 0;
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetQuery_1 = require("./helper/useGetQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "/api/admin/app-setting/create",
GET: "/api/admin/app-setting/all",
UPDATE: "api/admin/app-setting/update",
DELETE: "/api/admin/app-setting/delete"
};
var KEY = "APPSETTING";
exports.useGetAppSetting = function (params) { return useGetQuery_1["default"](KEY, API.GET, params); };
exports.useAddAppSetting = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateAppSetting = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteAppSetting = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

View File

@ -1,23 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteAttribute = exports.useUpdateAttributeStatus = exports.useUpdateAttribute = exports.useAddAttribute = exports.useGetSingleAttribute = exports.useGetOneAttribute = exports.useGetAttribute = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useGetSingleQuery_1 = require("./helper/useGetSingleQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "attribute",
GET_ALL: "attribute",
DELETE: "attribute",
UPDATE: "attribute"
};
var KEY = "ATTRIBUTE";
exports.useGetAttribute = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneAttribute = function (params) { return useGetOneQuery_1["default"](KEY, API.GET_ALL, params); };
exports.useGetSingleAttribute = function (params) { return useGetSingleQuery_1["default"](KEY, API.GET_ALL, params); };
exports.useAddAttribute = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateAttribute = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useUpdateAttributeStatus = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteAttribute = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

10
src/api/dist/auth.js vendored
View File

@ -1,10 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useLoginAdmin = void 0;
var useAddMutation_1 = require("./helper/useAddMutation");
var KEY = "AUTH";
var API = {
LOGIN: "admin/login",
LOGOUT: "/api/admin/logout"
};
exports.useLoginAdmin = function () { return useAddMutation_1["default"](KEY, API.LOGIN); };

View File

@ -1,12 +0,0 @@
"use strict";
exports.__esModule = true;
exports.USER_KEY = exports.TOKEN_KEY = exports.BaseURL_IMAGE = exports.ImageBaseURL = exports.BaseURL = void 0;
// export const BaseURL = `https://etaxiapi.rayantaxi.com/`;
// export const BaseURL = `https://etaxi.Point.net/`;
exports.BaseURL = "https://hijabi-back-dev.point-dev.net/api/";
exports.ImageBaseURL = "https://hijabi-back-dev.point-dev.net";
// export const BaseURL = `http://192.168.1.14:8000/`;
exports.BaseURL_IMAGE = exports.BaseURL.slice(0, -1);
var PROJECT_NAME = "Hijab";
exports.TOKEN_KEY = PROJECT_NAME + "_TOKEN";
exports.USER_KEY = PROJECT_NAME + "_USER";

24
src/api/dist/order.js vendored
View File

@ -1,24 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeliveredOrder = exports.useDeliverOrder = exports.useCancelOrder = exports.useAcceptOrder = exports.useDeleteOrder = exports.useUpdateOrder = exports.useAddOrder = exports.useGetOneOrder = exports.useGetOrder = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "order",
GET_ALL: "order",
DELETE: "order",
UPDATE: "order"
};
var KEY = "Order";
exports.useGetOrder = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneOrder = function (params) { return useGetOneQuery_1["default"](KEY, API.GET_ALL, params); };
exports.useAddOrder = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateOrder = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteOrder = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };
exports.useAcceptOrder = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useCancelOrder = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useDeliverOrder = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useDeliveredOrder = function () { return useAddMutation_1["default"](KEY, API.ADD); };

View File

@ -1,26 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteProduct = exports.useUpdateProductStatus = exports.useUpdateProductVariation = exports.useUpdateProduct = exports.useAddProductVariation = exports.useAddProduct = exports.useGetOneProduct = exports.useGetProduct = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "baseProduct",
GET_ALL: "baseProduct",
DELETE: "baseProduct",
UPDATE: "baseProduct",
ADD_VAR: "product",
UPDATE_VAR: "product"
};
var KEY = "Product";
var ONEKEY = "OneProduct";
exports.useGetProduct = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneProduct = function (params) { return useGetOneQuery_1["default"](ONEKEY, API.GET_ALL, params); };
exports.useAddProduct = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useAddProductVariation = function () { return useAddMutation_1["default"](KEY, API.ADD_VAR); };
exports.useUpdateProduct = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useUpdateProductVariation = function () { return useUpdateMutation_1["default"](KEY, API.ADD_VAR); };
exports.useUpdateProductStatus = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteProduct = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

20
src/api/dist/users.js vendored
View File

@ -1,20 +0,0 @@
"use strict";
exports.__esModule = true;
exports.useDeleteUsers = exports.useUpdateUsers = exports.useAddUsers = exports.useGetOneUser = exports.useGetUsers = void 0;
var ueGetPagination_1 = require("./helper/ueGetPagination");
var useAddMutation_1 = require("./helper/useAddMutation");
var useDeleteMutation_1 = require("./helper/useDeleteMutation");
var useGetOneQuery_1 = require("./helper/useGetOneQuery");
var useUpdateMutation_1 = require("./helper/useUpdateMutation");
var API = {
ADD: "user",
GET_ALL: "user",
DELETE: "user",
UPDATE: "user"
};
var KEY = "User";
exports.useGetUsers = function (params) { return ueGetPagination_1["default"](KEY, API.GET_ALL, params); };
exports.useGetOneUser = function (params) { return useGetOneQuery_1["default"](KEY, API.GET_ALL, params); };
exports.useAddUsers = function () { return useAddMutation_1["default"](KEY, API.ADD); };
exports.useUpdateUsers = function () { return useUpdateMutation_1["default"](KEY, API.UPDATE); };
exports.useDeleteUsers = function () { return useDeleteMutation_1["default"](KEY, API.DELETE); };

View File

@ -1,40 +0,0 @@
"use strict";
exports.__esModule = true;
var axios_1 = require("axios");
var AxiosBuilder = /** @class */ (function () {
function AxiosBuilder() {
this.baseURL = '';
this.headers = {};
this.timeout = 60000; // Request failed with 60 second
this.withCreds = false;
this.responseType = 'json';
}
// Custom Another Props with Your Position
AxiosBuilder.prototype.withBaseURL = function (baseURL) {
this.baseURL = baseURL;
return this;
};
AxiosBuilder.prototype.withHeaders = function (headers) {
this.headers = headers;
return this;
};
AxiosBuilder.prototype.withTimeout = function (timeout) {
this.timeout = timeout;
return this;
};
AxiosBuilder.prototype.withResponseType = function (responseType) {
this.responseType = responseType;
return this;
};
AxiosBuilder.prototype.build = function () {
var config = {
baseURL: this.baseURL,
headers: this.headers,
timeout: this.timeout,
responseType: this.responseType
};
return axios_1["default"].create(config);
};
return AxiosBuilder;
}());
exports["default"] = AxiosBuilder;

View File

@ -1,61 +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 react_query_1 = require("react-query");
var useAxios_1 = require("./useAxios");
function useGetQuery(key, url, params) {
var _this = this;
var axios = useAxios_1["default"]();
return react_query_1.useQuery(key, function () { return __awaiter(_this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.get(params ? url + params : url, params)];
case 1:
response = _a.sent();
return [2 /*return*/, response.data.data];
}
});
}); }, {
onError: function (error) {
console.error('An error occurred:', error);
},
refetchOnWindowFocus: false
});
}
exports["default"] = useGetQuery;

View File

@ -1,17 +0,0 @@
"use strict";
exports.__esModule = true;
exports.buildFormData = void 0;
exports.buildFormData = function (formData, data, parentKey) {
if (data &&
typeof data === "object" &&
!(data instanceof Date) &&
!(data instanceof File)) {
Object.keys(data).forEach(function (key) {
exports.buildFormData(formData, data[key], parentKey ? parentKey + "[" + key + "]" : key);
});
}
else {
var value = data == null ? "" : data;
formData.append(parentKey, value);
}
};

View File

@ -1,84 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 react_query_1 = require("react-query");
var useAxios_1 = require("./useAxios");
var react_router_dom_1 = require("react-router-dom");
var AuthState_1 = require("../../lib/state mangment/AuthState");
function useGetQueryPagination(KEY, Api, params, options) {
var _this = this;
var _a;
if (params === void 0) { params = {}; }
if (options === void 0) { options = {}; }
var axios = useAxios_1["default"]();
var location = react_router_dom_1.useLocation();
var pagination = (location === null || location === void 0 ? void 0 : location.search) || '';
// console.log(params);
var logout = AuthState_1["default"]().logout;
var language = (_a = localStorage.getItem("language")) !== null && _a !== void 0 ? _a : "en";
var navigate = react_router_dom_1.useNavigate();
return react_query_1.useQuery([KEY, pagination], function () { return __awaiter(_this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.get(Api + pagination, { params: params })];
case 1:
response = _a.sent();
return [2 /*return*/, response.data];
}
});
}); }, __assign({ onError: function (error) {
if (error.response.status == 401 || error.response.status == 403) {
logout();
navigate("/auth");
}
}, refetchOnWindowFocus: false }, options));
}
exports["default"] = useGetQueryPagination;
// export const useGetDynamic = (Api: string) => useGetQueryPagination(Api);

View File

@ -1,74 +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 react_query_1 = require("react-query");
var react_toastify_1 = require("react-toastify");
var useAxios_1 = require("./useAxios");
var react_i18next_1 = require("react-i18next");
function useAddMutation(key, url) {
var _this = this;
var axios = useAxios_1["default"]();
var t = react_i18next_1.useTranslation()[0];
var queryClient = react_query_1.useQueryClient();
return react_query_1.useMutation(function (dataToSend) { return __awaiter(_this, void 0, void 0, function () {
var data;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.post(url, dataToSend, {
headers: {
'Content-Type': 'multipart/form-data'
}
})];
case 1:
data = (_a.sent()).data;
return [2 /*return*/, data];
}
});
}); }, {
onSuccess: function (data) {
queryClient.invalidateQueries([key]);
react_toastify_1.toast.success(data.message || t("Add Successful"));
},
onError: function (error) {
var _a, _b;
var message = ((_b = (_a = error === null || error === void 0 ? void 0 : error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("failed_to_add_data");
react_toastify_1.toast.error(message);
}
});
}
exports["default"] = useAddMutation;

View File

@ -1,18 +0,0 @@
"use strict";
exports.__esModule = true;
var config_1 = require("../config");
var AuthState_1 = require("../../lib/state mangment/AuthState");
var AxiosBuilder_1 = require("./AxiosBuilder");
function useAxios() {
var _a = AuthState_1["default"](), isAuthenticated = _a.isAuthenticated, token = _a.token;
var buildAxios = new AxiosBuilder_1["default"]().
withBaseURL(config_1.BaseURL)
.withResponseType('json')
.withTimeout(120000)
.withHeaders({ "Content-Type": "application/json" });
if (isAuthenticated) {
buildAxios.withHeaders({ Authorization: 'Bearer ' + token });
}
return (buildAxios.build());
}
exports["default"] = useAxios;

View File

@ -1,79 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 react_query_1 = require("react-query");
var react_toastify_1 = require("react-toastify");
var useAxios_1 = require("./useAxios");
var react_i18next_1 = require("react-i18next");
function useDeleteMutation(key, url) {
var _this = this;
var axios = useAxios_1["default"]();
var queryClient = react_query_1.useQueryClient();
var t = react_i18next_1.useTranslation().t;
return react_query_1.useMutation(function (_a) {
var dataToSend = _a.dataToSend, id = _a.id;
return __awaiter(_this, void 0, void 0, function () {
var data;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, axios["delete"](url + "/" + id)];
case 1:
data = (_b.sent()).data;
return [2 /*return*/, __assign(__assign({}, data), { id: id, dataToSend: dataToSend })];
}
});
});
}, {
onSuccess: function (data) {
queryClient.invalidateQueries(key);
react_toastify_1.toast.success(t('deleted_successfully'));
}
});
}
exports["default"] = useDeleteMutation;

View File

@ -1,81 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 react_query_1 = require("react-query");
var useAxios_1 = require("./useAxios");
var AuthState_1 = require("../../lib/state mangment/AuthState");
var react_router_dom_1 = require("react-router-dom");
function useGetOneQuery(key, url, params, options) {
var _this = this;
var _a;
if (params === void 0) { params = {}; }
if (options === void 0) { options = {}; }
var axios = useAxios_1["default"]();
var logout = AuthState_1["default"]().logout;
var language = (_a = localStorage.getItem("language")) !== null && _a !== void 0 ? _a : "en";
var navigate = react_router_dom_1.useNavigate();
var id = react_router_dom_1.useParams().id;
return react_query_1.useQuery([id, key], function () { return __awaiter(_this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.get(url + "/" + id + ("?lang=" + language))];
case 1:
response = _a.sent();
return [2 /*return*/, response.data];
}
});
}); }, __assign({ onError: function (error) {
if (error.response.status == 401 || error.response.status == 403) {
logout();
navigate("/auth");
}
}, refetchOnWindowFocus: false }, options));
}
exports["default"] = useGetOneQuery;

View File

@ -1,81 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 react_query_1 = require("react-query");
var useAxios_1 = require("./useAxios");
var AuthState_1 = require("../../lib/state mangment/AuthState");
var react_router_dom_1 = require("react-router-dom");
function useGetQuery(key, url, params, options) {
var _this = this;
if (params === void 0) { params = {}; }
if (options === void 0) { options = {}; }
var axios = useAxios_1["default"]();
var logout = AuthState_1["default"]().logout;
var navigate = react_router_dom_1.useNavigate();
return react_query_1.useQuery(params ? [key, params] : key, function () { return __awaiter(_this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.get(url, { params: params })];
case 1:
response = _a.sent();
return [2 /*return*/, response.data.data];
}
});
}); }, __assign({ onError: function (error) {
console.log('====================================');
console.log(error.response.status);
console.log('====================================');
if (error.response.status == 401 || error.response.status == 403) {
logout();
navigate("/auth");
}
}, refetchOnWindowFocus: false }, options));
}
exports["default"] = useGetQuery;

View File

@ -1,81 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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 react_query_1 = require("react-query");
var useAxios_1 = require("./useAxios");
var AuthState_1 = require("../../lib/state mangment/AuthState");
var react_router_dom_1 = require("react-router-dom");
function useGetSingleQuery(key, url, params, options) {
var _this = this;
var _a;
if (params === void 0) { params = {}; }
if (options === void 0) { options = {}; }
var axios = useAxios_1["default"]();
var logout = AuthState_1["default"]().logout;
var language = (_a = localStorage.getItem("language")) !== null && _a !== void 0 ? _a : "en";
var navigate = react_router_dom_1.useNavigate();
var id = react_router_dom_1.useParams().id;
return react_query_1.useQuery([id, key, params === null || params === void 0 ? void 0 : params.id], function () { return __awaiter(_this, void 0, void 0, function () {
var response;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, axios.get(url + "?" + (params === null || params === void 0 ? void 0 : params.name) + "=" + (params === null || params === void 0 ? void 0 : params.id) + ("?lang=" + language))];
case 1:
response = _a.sent();
return [2 /*return*/, response.data];
}
});
}); }, __assign({ onError: function (error) {
if (error.response.status == 401 || error.response.status == 403) {
logout();
navigate("/auth");
}
}, refetchOnWindowFocus: false }, options));
}
exports["default"] = useGetSingleQuery;

View File

@ -1,89 +0,0 @@
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
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;
exports.useToggleStatus = void 0;
var react_query_1 = require("react-query");
var react_toastify_1 = require("react-toastify");
var react_i18next_1 = require("react-i18next");
var useAxios_1 = require("./useAxios");
exports.useToggleStatus = function (key, url, object_id) {
var axios = useAxios_1["default"]();
var queryClient = react_query_1.useQueryClient();
var t = react_i18next_1.useTranslation()[0];
return react_query_1.useMutation(function (_a) {
var id = _a.id, new_status = _a.new_status;
return __awaiter(void 0, void 0, void 0, function () {
var data;
var _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0: return [4 /*yield*/, axios.post(url, (_b = {},
_b[object_id] = id,
_b.new_status = new_status,
_b))];
case 1:
data = (_c.sent()).data;
return [2 /*return*/, __assign(__assign({}, data), { id: id, new_status: new_status })];
}
});
});
}, {
onSuccess: function (_a) {
var message = _a.message, id = _a.id, new_status = _a.new_status;
react_toastify_1.toast.success(message || t("toggle_success"));
queryClient.invalidateQueries([key]);
},
onError: function (err) {
var _a, _b;
var message = ((_b = (_a = err === null || err === void 0 ? void 0 : err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || t("toggle_failed");
react_toastify_1.toast.error(message);
// validateSession(err.response);
}
});
};

Some files were not shown because too many files have changed in this diff Show More