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);
|
||||
}
|
||||
}, [isValid,values]);
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
|
||||
|
|
@ -30,7 +30,7 @@ const BasicInfo = ({setIsValed}:any) => {
|
|||
<Col>
|
||||
<KarimField name="main_photo" type='File' />
|
||||
<KarimField name="category_id" type='Select' option={[]} label='category' placeholder='category' />
|
||||
|
||||
|
||||
</Col>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { CloseOutlined } from '@ant-design/icons';
|
|||
import { Button, Card, Form, Input, Space, Typography } from 'antd';
|
||||
import { useFormikContext } from 'formik';
|
||||
|
||||
const ObjectField: React.FC = () => {
|
||||
const ObjectField = () => {
|
||||
const [form] = Form.useForm();
|
||||
const formik = useFormikContext<any>();
|
||||
const [FieldItems, setFieldItems] = useState<any>([])
|
||||
|
|
@ -13,8 +13,9 @@ const ObjectField: React.FC = () => {
|
|||
...prevState,
|
||||
[name]: value
|
||||
}));
|
||||
|
||||
formik.setFieldValue("info", FieldItems)
|
||||
|
||||
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -22,6 +23,7 @@ const ObjectField: React.FC = () => {
|
|||
items: [{ list: [{ Attribute: '', Description: '' }] }]
|
||||
});
|
||||
|
||||
|
||||
}, []);
|
||||
|
||||
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 { CopyOutlined } from '@ant-design/icons';
|
||||
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;
|
||||
|
||||
|
|
@ -26,6 +31,22 @@ const App: React.FC = () => {
|
|||
const onChange = (newActiveKey: string) => {
|
||||
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 newActiveKey = `${items.length + 1}`;
|
||||
|
|
@ -48,11 +69,23 @@ const App: React.FC = () => {
|
|||
key: newActiveKey,
|
||||
label: `variable ${newActiveKey}`,
|
||||
};
|
||||
|
||||
// Get the values of the original tab
|
||||
const originalValues = inputValues[targetKey] || ['', '', '', ''];
|
||||
|
||||
const newPanes = [...items, newItem];
|
||||
setItems(newPanes);
|
||||
setActiveKey(newActiveKey);
|
||||
|
||||
// Update the inputValues state with the original values for the new tab
|
||||
setInputValues((prevInputValues) => ({
|
||||
...prevInputValues,
|
||||
[newActiveKey]: originalValues,
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const remove = (targetKey: string) => {
|
||||
let newActiveKey = activeKey;
|
||||
|
|
@ -127,25 +160,72 @@ interface VariableTabsProps {
|
|||
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 newValues = [...value];
|
||||
newValues[index] = e.target.value;
|
||||
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 (
|
||||
<div>
|
||||
<label className="text">
|
||||
{t(`Name`)}
|
||||
</label>
|
||||
<Input value={value[0]} onChange={handleInputChange(0)} />
|
||||
|
||||
<Input value={value[1]} onChange={handleInputChange(1)} />
|
||||
<Input value={value[2]} onChange={handleInputChange(2)} />
|
||||
<Input value={value[3]} onChange={handleInputChange(3)} />
|
||||
</div>
|
||||
<>
|
||||
<Row>
|
||||
<Col>
|
||||
<label className="tabstext"> {t(`Name`)} </label>
|
||||
<Input value={value[0]} onChange={handleInputChange(0)} />
|
||||
<label className="tabstext"> {t(`Description`)} </label>
|
||||
<Input value={value[1]} onChange={handleInputChange(1)} />
|
||||
<SearchTabs value={value[2]} onChange={SelecthandleChange(2)} name={"color"} />
|
||||
<label className="tabstext"> {t(`main_photo`)} </label>
|
||||
|
||||
<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??"",
|
||||
category_id:objectToEdit?.category_id??1,
|
||||
variable:[],
|
||||
info : []
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -362,13 +362,14 @@ background: var(--bg);
|
|||
border-radius: 20px;
|
||||
}
|
||||
.SingleInfo{
|
||||
|
||||
svg{
|
||||
color: green !important;
|
||||
}
|
||||
}
|
||||
.ResposiveTabs{
|
||||
padding-block: 20px;
|
||||
min-height: 300px;
|
||||
min-height: 500px;
|
||||
}
|
||||
/* 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{
|
||||
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