fix add product modal

This commit is contained in:
Moaz Dawalibi 2024-08-03 15:17:06 +03:00
parent ed0d7d3a5d
commit a7d4b29eef
13 changed files with 210 additions and 147 deletions

5
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,5 @@
{
"cSpell.words": [
"formik"
]
}

View File

@ -1,10 +1,11 @@
import React from "react";
import "./ValidationField.scss";
import { Date, Time, File, DataRange, SelectField, Default, CheckboxField } from './View';
import MaltyFile from "./View/MaltyFile";
export interface ValidationFieldProps {
name: string;
type?: "text" | "Select" | "DataRange" | "Date" | "Time" | "File" | "number" | "Checkbox" | "password";
type?: "text" | "Select" | "DataRange" | "Date" | "Time" | "File" | "number" | "Checkbox" | "password" |"MaltyFile";
placeholder?: string;
label?: string;
className?: string;
@ -31,6 +32,8 @@ const ValidationField = (props: ValidationFieldProps) => {
return <Time {...props} />;
case "File":
return <File {...props} />;
case "MaltyFile":
return <MaltyFile {...props} />;
case "Checkbox":
return <CheckboxField {...props} />;
default:

View File

@ -22,6 +22,7 @@ const Default = ({ name, label, placeholder, isDisabled, onChange, props }: any)
placeholder={t(`${placeholder ? placeholder : name}`)}
name={name}
disabled={isDisabled}
// onChange={onChange ? onChange : handleChange}
/>
</Form.Item>

View File

@ -19,6 +19,7 @@ const MaltyFile = ({
const fileList = useMemo(() => {
return imageUrl
? imageUrl.map((file: any, index: number) => {
return file instanceof File
? {
uid: index,
@ -58,7 +59,7 @@ const MaltyFile = ({
return (
<div className="ValidationField upload_image_button">
<label htmlFor={name} className="text">
{t(`input.${label || name}`)}
{t(`${label || name}`)}
</label>
<Upload
@ -75,7 +76,7 @@ const MaltyFile = ({
className={isError ? "isError w-100" : "w-100"}
icon={<FaUpload />}
>
{t(`input.` + placeholder) ?? t("input.upload_image")}
{t(placeholder) ?? t("upload_image")}
</Button>
<div className="Error_color">{isError ? "required" : ""}</div>
</Upload>

View File

@ -17,7 +17,6 @@
console.log(values);
const dataToSend = getDataToSend(values)
mutate(dataToSend)
// Submit Value
}

View File

@ -12,8 +12,8 @@ function EditProductModal() {
const {status, mutate} = useUpdateProduct();
const handleSubmit = (value:InitialValues)=>{
const dataToSend = getDataToSend({...value})
console.log(value);
const dataToSend = getDataToSend({...value})
mutate(dataToSend)
}

View File

@ -5,11 +5,8 @@ import ValidationField from '../../Components/ValidationField/ValidationField';
import { useTranslation } from 'react-i18next';
import { useGetCategory } from '../../api/category';
import { objectToKeyValueArray } from '../../utils/ConvertObjToArr';
import { Collection, Param } from './formUtil';
interface Param {
key: string;
value: string;
}
interface FormValues {
attachments: any;
@ -18,6 +15,7 @@ interface FormValues {
model: string;
image: string;
params: Param[];
collections: Collection[]
}
function FormProduct() {
@ -29,20 +27,19 @@ function FormProduct() {
value: e.id,
label: e?.name,
}));
// console.log(formik.values.params);
const paramsArray = objectToKeyValueArray(formik.values.params)
// console.log(formik.values.params);
return (
<>
<Row xs={1} sm={1} md={1} lg={2} xl={2}>
<Row xs={1} sm={1} md={1} lg={3} xl={3}>
<Col>
<ValidationField name="name" type="text" label="Name" placeholder="placeholder" />
<ValidationField name="description" type="text" label="description" placeholder="placeholder" />
<ValidationField name="model" type="text" label="Model" placeholder="placeholder" />
<ValidationField name="file" type="File" label="Image" placeholder="placeholder" />
<ValidationField name="category_id" type="Select" label="Category" option={CategoryOption} placeholder="placeholder" />
<ValidationField name="attachments" type="MaltyFile" label="Attachments inputs" placeholder="Attachments" />
</Col>
<Col>
<FieldArray name="params">
{({ push, remove }) => (
@ -61,9 +58,8 @@ function FormProduct() {
label={`Param Value ${index + 1}`}
placeholder="Value"
/>
<div className='flex_between'>
<Button type="button" className='remove_button' color='danger' onClick={() => remove(index)}>{t("Remove")}</Button>
</div>
))}
<Button
type="button"
className="add_button"
@ -73,68 +69,85 @@ function FormProduct() {
{t("Add Param")}
</Button>
</div>
</div>
))}
</div>
)}
</FieldArray>
</Col>
</Row>
<Row>
{/* collection */}
<Col className='border'>
{/* <FieldArray name="">
<Col>
<FieldArray name="collections">
{({ push, remove }) => (
<div>
{formik.values.params.map((param, index) => (
{Array.isArray(formik.values.collections) && formik.values.collections?.map((collection, index) => (
<div key={index}>
<ValidationField
name={`params.${index}.key`}
name={`collections.${index}.name`}
type="text"
label={`Param Key ${index + 1}`}
label={`Collection Name ${index + 1}`}
placeholder="Collection Name"
/>
<FieldArray name={`collections.${index}.collectionParams`}>
{({ push: pushParam, remove: removeParam }) => (
<div>
{Array.isArray(collection?.collectionParams) && collection?.collectionParams?.map((param, paramIndex) => (
<div key={paramIndex}>
<ValidationField
name={`collections.${index}.collectionParams.${paramIndex}.key`}
type="text"
label={`Param Key ${paramIndex + 1}`}
placeholder="Key"
/>
<ValidationField
name={`params.${index}.value`}
name={`collections.${index}.collectionParams.${paramIndex}.value`}
type="text"
label={`Param Value ${index + 1}`}
label={`Param Value ${paramIndex + 1}`}
placeholder="Value"
/>
<Button type="button" className='remove_button' color='danger' onClick={() => remove(index)}>{t("Remove")}</Button>
<div className='flex_evenly'>
<Button type="button" className='remove_button remove_sub_color' color='danger' onClick={() => removeParam(paramIndex)}>
{t("Remove Param")}
</Button>
<Button
type="button"
className="add_button add_sub_color"
color='primary'
onClick={() => pushParam({ key: '', value: '' })}
>
{t("Add Param")}
</Button>
</div>
</div>
))}
<Button type="button" className="add_button" color='primary' onClick={() => push({ key: '', value: '' })}>{t("Add Param")}</Button>
</div>
)}
</FieldArray> */}
{/* attachements array */}
<FieldArray name="attachments">
{({ push, remove }) => (
<div>
{formik.values.attachments.map((attachment: any, index: number) => (
<div key={index}>
{/* <ValidationField
name={`attachments[${index}].id`}
type="text"
label={`Attachment ID ${index + 1}`}
placeholder="Attachment ID"
/> */}
<ValidationField
name={`attachments[${index}].attachment`}
type="File"
label={`Attachment URL ${index + 1}`}
placeholder="Attachment URL"
/>
<Button type="button" className='remove_button' color='danger' onClick={() => remove(index)}>{t("Remove")}</Button>
</FieldArray>
<div className='flex_between'>
<Button type="button" className='remove_button' color='danger' onClick={() => remove(index)}>
{t("Remove Collection")}
</Button>
<Button
type="button"
className="add_button"
color='primary'
onClick={() => push({ name: '', collectionParams: [{ key: '', value: '' }] })}
>
{t("Add Collection")}
</Button>
</div>
</div>
))}
<Button type="button" className="add_button" color='primary' onClick={() => push({ id: null, attachment: '' })}>{t("Add Attachment")}</Button>
</div>
)}
</FieldArray>
</Col>
</Row>
</>
);
)
}
export default FormProduct;
export default FormProduct

View File

@ -1,5 +1,4 @@
import React from 'react'
import DashBody from '../../Layout/Dashboard/DashBody'
import DashHeader from '../../Layout/Dashboard/DashHeader'
import LyTable from '../../Layout/Dashboard/LyTable'

View File

@ -1,8 +1,8 @@
import * as Yup from 'yup';
import { buildFormData } from '../../api/helper/buildFormData';
import { objectToKeyValueArray } from '../../utils/ConvertObjToArr';
import { collectionObjectToArray, objectToKeyValueArray } from '../../utils/ConvertObjToArr';
interface Param {
export interface Param {
key: string;
value: string;
}
@ -11,16 +11,16 @@ interface Category {
name: string | null;
}
interface Collection {
export interface Collection {
name: string;
collectionParam: {
collectionParams: {
key: string;
value: string;
};
}
interface Attachment {
id: number | null;
// type: string;
attachment: string;
}
@ -33,10 +33,11 @@ interface FormUtilCommon {
category?: Category;
params?: Param[];
collections?: Collection[];
attachments?: Attachment[]; // Add attachments here
attachment?: Attachment[]; // Add attachments here
}
interface ObjectToEdit extends FormUtilCommon {
id?: number | null;
}
export interface InitialValues extends ObjectToEdit {
@ -48,8 +49,14 @@ interface ValidateSchema extends FormUtilCommon {}
export const getInitialValues = (objectToEdit: ObjectToEdit | null = null): any => {
const params = objectToEdit?.params ? objectToKeyValueArray(objectToEdit.params) : [{ key: '', value: '' }];
const collections = objectToEdit?.collections || [];
const attachments = objectToEdit?.attachments ? objectToEdit.attachments.map(attachment => attachment.attachment ?? []):[]
const collection = objectToEdit?.collections ? objectToKeyValueArray(objectToEdit.collections) : [{ name: '', collectionParams: [{ key: '', value: '' }]} ];
// { name: '', collectionParams: [{ key: '', value: '' }] };
const attachments = objectToEdit?.attachment ? objectToEdit.attachment.map(attachment => {
return {
url: attachment.attachment ?? ""
}
}) : []
return {
id: objectToEdit?.id ?? null,
@ -59,12 +66,12 @@ export const getInitialValues = (objectToEdit: ObjectToEdit | null = null): any
model: objectToEdit?.model ?? '',
file: objectToEdit?.file ?? '',
params: params,
collections: collections,
collections: collection,
attachments: attachments, // Set the attachments here
};
}
export const getValidationSchema = (editMode: boolean = false): Yup.Schema<ValidateSchema> => {
export const getValidationSchema = (editMode: boolean = false): any => {
return Yup.object().shape({
name: Yup.string().required('required'),
category_id: Yup.number().nullable().required('required'),
@ -77,11 +84,24 @@ export const getValidationSchema = (editMode: boolean = false): Yup.Schema<Valid
value: Yup.string().required('Value is required'),
})
).default([]),
collections: Yup.array().of(
Yup.object().shape({
name: Yup.string().required('Collection Name is required'),
collectionParams: Yup.array().of(
Yup.object().shape({
key: Yup.string().required('Key is required'),
value: Yup.string().required('Value is required'),
})
).required('At least one parameter is required').min(1, 'At least one parameter is required'), // Ensure at least one parameter
})
).optional(), // Allow collections to be optional
});
};
export const getDataToSend = (values: any): any => {
const data = { ...values };
console.log(values);
if (data?.id) {
data["_method"] = "PUT"
}
@ -91,14 +111,12 @@ export const getDataToSend = (values: any): any => {
data.params = [];
}
// if (data.attachments && Array.isArray(data.attachments)) {
// data.attachments = data.attachments.map(({att}:any ) => att.attachment);
// }
// const formData = new FormData();
// buildFormData(formData, data);
// return formData;
if (typeof data['file'] == 'string') delete data['file']
// Return the data object directly
if (!Array.isArray(data.collections)) {
data.collections = [];
}
return data;
};

View File

@ -61,7 +61,7 @@ const useTableColumns :any = () => {
<Actions
// importnat to return the row in on Edit Function to store in objectToEdit That Upper in Edit Modal
onEdit={() => row}
// onEdit={() => navigate('/')}
objectToEdit={row}
showEdit={true}
showView={false}

View File

@ -98,3 +98,24 @@ svg {
margin-right: 10px;
border-top: 2px solid gray;
}
.param_field{
display: none !important;
width: 40% !important;
}
.flex_between{
display: flex;align-items: center;justify-content: space-around;
}
.flex_evenly{
display: flex;align-items: center;justify-content: space-evenly;
margin-bottom: 5px;
}
.add_sub_color{
background: rgba(3, 79, 210, 0.699) !important;
border-color: rgba(3, 79, 210, 0.699) !important;
}
.remove_sub_color{
background: rgba(255, 0, 0, 0.704) !important;
border-color: rgba(255, 0, 0, 0.704) !important;
}

View File

@ -1,5 +1,5 @@
export const BaseURL = `http://192.168.1.102:8000/`;
export const BaseURL = `http://127.0.0.1:8000/`;
export const BaseURL_IMAGE = '';

View File

@ -8,13 +8,16 @@ export function objectToKeyValueArray(obj: { [key: string]: any } | null | undef
}));
}
// // Example usage:
// const inputObject = {
// "wesam": "alabdeh",
// "ahmad": "alabdeh"
// };
// const resultArray = objectToKeyValueArray(inputObject);
// console.log(resultArray);
// Output: [ { wesam: 'alabdeh' }, { ahmad: 'alabdeh' } ]
export function collectionObjectToArray(collection: { name: string; collectionParams: { key: string; value: string } } | null | undefined): Array<{ name: string; collectionParams: { key: string; value: string } }> {
if (!collection) {
return [{ name: '', collectionParams: { key: '', value: '' } }];
}
return [{
name: collection.name,
collectionParams: {
key: collection.collectionParams.key,
value: collection.collectionParams.value,
},
}];
}