Done
This commit is contained in:
parent
82c7c0d09b
commit
cd66a46088
92
src/Components/Karimalden/View/Object.tsx
Normal file
92
src/Components/Karimalden/View/Object.tsx
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
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';
|
||||||
|
|
||||||
|
const ObjectField = ({value , onChange}:any) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const formik = useFormikContext<any>();
|
||||||
|
const [FieldItems, setFieldItems] = useState<any>([])
|
||||||
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const { name, value } = e.target;
|
||||||
|
setFieldItems((prevState:any) => ({
|
||||||
|
...prevState,
|
||||||
|
[name]: value
|
||||||
|
}));
|
||||||
|
formik.setFieldValue("info", FieldItems)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
form.setFieldsValue({
|
||||||
|
items: [{ list: [{ Attribute: '', Description: '' }] }]
|
||||||
|
});
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
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 }}>
|
||||||
|
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, 'Attribute']}>
|
||||||
|
<Input
|
||||||
|
placeholder="Attribute"
|
||||||
|
|
||||||
|
onChange={handleChange} // Assign onChange handler
|
||||||
|
name={`${subField.name}.Attribute`} // Ensure proper name for dynamic state update
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item noStyle name={[subField.name, 'Description']}>
|
||||||
|
<Input
|
||||||
|
placeholder="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>
|
||||||
|
+ Add Another Item
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Form.List>
|
||||||
|
</Form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ObjectField;
|
||||||
|
|
@ -18,7 +18,7 @@ const BasicInfo = ({setIsValed}:any) => {
|
||||||
console.log(values);
|
console.log(values);
|
||||||
}
|
}
|
||||||
}, [isValid,values]);
|
}, [isValid,values]);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
||||||
|
|
@ -30,7 +30,7 @@ const BasicInfo = ({setIsValed}:any) => {
|
||||||
<Col>
|
<Col>
|
||||||
<KarimField name="main_photo" type='File' />
|
<KarimField name="main_photo" type='File' />
|
||||||
<KarimField name="category_id" type='Select' option={[]} label='category' placeholder='category' />
|
<KarimField name="category_id" type='Select' option={[]} label='category' placeholder='category' />
|
||||||
|
|
||||||
</Col>
|
</Col>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { CloseOutlined } from '@ant-design/icons';
|
||||||
import { Button, Card, Form, Input, Space, Typography } from 'antd';
|
import { Button, Card, Form, Input, Space, Typography } from 'antd';
|
||||||
import { useFormikContext } from 'formik';
|
import { useFormikContext } from 'formik';
|
||||||
|
|
||||||
const ObjectField: React.FC = () => {
|
const ObjectField = () => {
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const formik = useFormikContext<any>();
|
const formik = useFormikContext<any>();
|
||||||
const [FieldItems, setFieldItems] = useState<any>([])
|
const [FieldItems, setFieldItems] = useState<any>([])
|
||||||
|
|
@ -13,8 +13,9 @@ const ObjectField: React.FC = () => {
|
||||||
...prevState,
|
...prevState,
|
||||||
[name]: value
|
[name]: value
|
||||||
}));
|
}));
|
||||||
|
|
||||||
formik.setFieldValue("info", FieldItems)
|
formik.setFieldValue("info", FieldItems)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -22,6 +23,7 @@ const ObjectField: React.FC = () => {
|
||||||
items: [{ list: [{ Attribute: '', Description: '' }] }]
|
items: [{ list: [{ Attribute: '', Description: '' }] }]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
41
src/Pages/Products/View/taps/File.tsx
Normal file
41
src/Pages/Products/View/taps/File.tsx
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { UploadOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Upload } from 'antd';
|
||||||
|
import type { UploadFile } from 'antd';
|
||||||
|
|
||||||
|
const fileList: UploadFile[] = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const App = ({value, onChange}:any) => {
|
||||||
|
|
||||||
|
const FilehandleChange = (data:any) => {
|
||||||
|
|
||||||
|
console.log('====================================');
|
||||||
|
console.log(data?.fileList);
|
||||||
|
console.log('====================================');
|
||||||
|
};
|
||||||
|
const customRequest = async ({ onSuccess}: any) => {
|
||||||
|
onSuccess();
|
||||||
|
};
|
||||||
|
return(
|
||||||
|
|
||||||
|
<>
|
||||||
|
<Upload
|
||||||
|
action="https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188"
|
||||||
|
listType="picture"
|
||||||
|
maxCount={1}
|
||||||
|
defaultFileList={[...fileList]}
|
||||||
|
className="upload-list-inline"
|
||||||
|
onChange={(data:any)=>onChange(data?.fileList)}
|
||||||
|
customRequest={customRequest}
|
||||||
|
>
|
||||||
|
<Button icon={<UploadOutlined />}>Upload</Button>
|
||||||
|
</Upload>
|
||||||
|
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
39
src/Pages/Products/View/taps/FileImage.tsx
Normal file
39
src/Pages/Products/View/taps/FileImage.tsx
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { UploadOutlined } from '@ant-design/icons';
|
||||||
|
import { Button, Upload } from 'antd';
|
||||||
|
import type { UploadFile } from 'antd';
|
||||||
|
|
||||||
|
const fileList: UploadFile[] = [
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
const App = ({value, onChange}:any) => {
|
||||||
|
|
||||||
|
const FilehandleChange = (data:any) => {
|
||||||
|
|
||||||
|
console.log('====================================');
|
||||||
|
console.log(data?.fileList);
|
||||||
|
console.log('====================================');
|
||||||
|
};
|
||||||
|
const customRequest = async ({ onSuccess}: any) => {
|
||||||
|
onSuccess();
|
||||||
|
};
|
||||||
|
return(
|
||||||
|
|
||||||
|
<>
|
||||||
|
<Upload
|
||||||
|
action="https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188"
|
||||||
|
listType="picture"
|
||||||
|
defaultFileList={[...fileList]}
|
||||||
|
className="upload-list-inline"
|
||||||
|
onChange={(data:any)=>onChange(data?.fileList)}
|
||||||
|
customRequest={customRequest}
|
||||||
|
>
|
||||||
|
<Button icon={<UploadOutlined />}>Upload</Button>
|
||||||
|
</Upload>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Tabs, Space, Input } from 'antd';
|
import { Tabs, Space, Input } from 'antd';
|
||||||
import { CopyOutlined } from '@ant-design/icons';
|
import { CopyOutlined } from '@ant-design/icons';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Col, Row } from 'reactstrap';
|
||||||
|
import FileImage from './FileImage';
|
||||||
|
import SearchTabs from './SearchTabs';
|
||||||
|
import ObjectField from '../ObjectField';
|
||||||
|
import { useFormikContext } from 'formik';
|
||||||
|
|
||||||
const { TabPane } = Tabs;
|
const { TabPane } = Tabs;
|
||||||
|
|
||||||
|
|
@ -26,6 +31,22 @@ const App: React.FC = () => {
|
||||||
const onChange = (newActiveKey: string) => {
|
const onChange = (newActiveKey: string) => {
|
||||||
setActiveKey(newActiveKey);
|
setActiveKey(newActiveKey);
|
||||||
};
|
};
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(inputValues);
|
||||||
|
}, [inputValues])
|
||||||
|
|
||||||
|
|
||||||
|
const formikContext = useFormikContext();
|
||||||
|
const { values } :any = formikContext;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setInputValues((prevInputValues:any) => ({
|
||||||
|
...prevInputValues,
|
||||||
|
[14]: values?.info,
|
||||||
|
}));
|
||||||
|
}, [values?.info])
|
||||||
|
|
||||||
const add = () => {
|
const add = () => {
|
||||||
const newActiveKey = `${items.length + 1}`;
|
const newActiveKey = `${items.length + 1}`;
|
||||||
|
|
@ -48,11 +69,23 @@ const App: React.FC = () => {
|
||||||
key: newActiveKey,
|
key: newActiveKey,
|
||||||
label: `variable ${newActiveKey}`,
|
label: `variable ${newActiveKey}`,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get the values of the original tab
|
||||||
|
const originalValues = inputValues[targetKey] || ['', '', '', ''];
|
||||||
|
|
||||||
const newPanes = [...items, newItem];
|
const newPanes = [...items, newItem];
|
||||||
setItems(newPanes);
|
setItems(newPanes);
|
||||||
setActiveKey(newActiveKey);
|
setActiveKey(newActiveKey);
|
||||||
|
|
||||||
|
// Update the inputValues state with the original values for the new tab
|
||||||
|
setInputValues((prevInputValues) => ({
|
||||||
|
...prevInputValues,
|
||||||
|
[newActiveKey]: originalValues,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const remove = (targetKey: string) => {
|
const remove = (targetKey: string) => {
|
||||||
let newActiveKey = activeKey;
|
let newActiveKey = activeKey;
|
||||||
|
|
@ -127,25 +160,72 @@ interface VariableTabsProps {
|
||||||
onChange: (value: string[]) => void;
|
onChange: (value: string[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VariableTabs: React.FC<VariableTabsProps> = ({ value, onChange }) => {
|
|
||||||
|
const VariableTabs: React.FC<VariableTabsProps> = ({ value, onChange } ) => {
|
||||||
const handleInputChange = (index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleInputChange = (index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const newValues = [...value];
|
const newValues = [...value];
|
||||||
newValues[index] = e.target.value;
|
newValues[index] = e.target.value;
|
||||||
onChange(newValues);
|
onChange(newValues);
|
||||||
};
|
};
|
||||||
const [t] = useTranslation()
|
//@ts-ignore
|
||||||
|
const SelecthandleChange = (index: number) => (Selectvalue:any) => {
|
||||||
|
const newValues = [...value];
|
||||||
|
newValues[index] = Selectvalue;
|
||||||
|
onChange(newValues);
|
||||||
|
};
|
||||||
|
const FilehandleChange = (index: number) => (data:any) => {
|
||||||
|
const newValues = [...value];
|
||||||
|
newValues[index] = data;
|
||||||
|
onChange(newValues);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [t] = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<label className="text">
|
<Row>
|
||||||
{t(`Name`)}
|
<Col>
|
||||||
</label>
|
<label className="tabstext"> {t(`Name`)} </label>
|
||||||
<Input value={value[0]} onChange={handleInputChange(0)} />
|
<Input value={value[0]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`Description`)} </label>
|
||||||
<Input value={value[1]} onChange={handleInputChange(1)} />
|
<Input value={value[1]} onChange={handleInputChange(1)} />
|
||||||
<Input value={value[2]} onChange={handleInputChange(2)} />
|
<SearchTabs value={value[2]} onChange={SelecthandleChange(2)} name={"color"} />
|
||||||
<Input value={value[3]} onChange={handleInputChange(3)} />
|
<label className="tabstext"> {t(`main_photo`)} </label>
|
||||||
</div>
|
|
||||||
|
<FileImage value={value[13]} onChange={FilehandleChange(13)} />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<label className="tabstext"> {t(`name_en`)} </label>
|
||||||
|
<Input value={value[6]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`name_ar`)} </label>
|
||||||
|
<Input value={value[7]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`name_de`)} </label>
|
||||||
|
<Input value={value[8]} onChange={handleInputChange(0)} />
|
||||||
|
|
||||||
|
<ObjectField key="14" />
|
||||||
|
</Col>
|
||||||
|
<Col>
|
||||||
|
<label className="tabstext"> {t(`Image`)} </label>
|
||||||
|
<FileImage value={value[3]} onChange={FilehandleChange(3)} />
|
||||||
|
<SearchTabs value={value[4]} onChange={SelecthandleChange(4)} name={"size"} />
|
||||||
|
<label className="tabstext"> {t(`Price`)} </label>
|
||||||
|
<Input value={value[5]} onChange={handleInputChange(5)} />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<label className="tabstext"> {t(`description_en`)} </label>
|
||||||
|
<Input value={value[9]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`description_ar`)} </label>
|
||||||
|
<Input value={value[10]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`description_de`)} </label>
|
||||||
|
<Input value={value[11]} onChange={handleInputChange(0)} />
|
||||||
|
<label className="tabstext"> {t(`quantity`)} </label>
|
||||||
|
<Input value={value[12]} onChange={handleInputChange(0)} />
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
60
src/Pages/Products/View/taps/SearchTabs.tsx
Normal file
60
src/Pages/Products/View/taps/SearchTabs.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
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;
|
||||||
9
src/Pages/Products/View/taps/VariableTabs.tsx
Normal file
9
src/Pages/Products/View/taps/VariableTabs.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
const VariableTabs = () => {
|
||||||
|
return (
|
||||||
|
<div>VariableTabs</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default VariableTabs
|
||||||
|
|
@ -21,6 +21,7 @@ export const getInitialValues = (objectToEdit: any | null = null) => {
|
||||||
images:objectToEdit?.images??"",
|
images:objectToEdit?.images??"",
|
||||||
category_id:objectToEdit?.category_id??1,
|
category_id:objectToEdit?.category_id??1,
|
||||||
variable:[],
|
variable:[],
|
||||||
|
info : []
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -362,13 +362,14 @@ background: var(--bg);
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
}
|
}
|
||||||
.SingleInfo{
|
.SingleInfo{
|
||||||
|
|
||||||
svg{
|
svg{
|
||||||
color: green !important;
|
color: green !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.ResposiveTabs{
|
.ResposiveTabs{
|
||||||
padding-block: 20px;
|
padding-block: 20px;
|
||||||
min-height: 300px;
|
min-height: 500px;
|
||||||
}
|
}
|
||||||
/* Ant tabs tab active */
|
/* Ant tabs tab active */
|
||||||
.ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab-active{
|
.ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab-active{
|
||||||
|
|
@ -383,7 +384,24 @@ background: var(--bg);
|
||||||
}
|
}
|
||||||
.ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab{
|
.ant-tabs-nav-wrap .ant-tabs-nav-list .ant-tabs-tab{
|
||||||
align-self: center !important;
|
align-self: center !important;
|
||||||
|
padding: 10px 40px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.VarianInfo{
|
||||||
|
padding: 10px 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.react-tabs__tab-panel--selected .mt-4 .VarianInfo .ant-tabs-editable .ant-tabs-content-holder .ant-tabs-content .ant-tabs-tabpane .row .col .ant-upload-wrapper .ant-upload-select .ant-upload .ant-btn{
|
||||||
|
width:100% !important;
|
||||||
|
}
|
||||||
|
.tabstext{
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SellectTab{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user