manage attribute form
This commit is contained in:
@@ -0,0 +1,20 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
isActive: boolean,
|
||||||
|
value: string,
|
||||||
|
onChange: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const Radio: FC<Props> = (props: Props) => {
|
||||||
|
return (
|
||||||
|
<div onClick={() => props.onChange(props.value)} className='size-4 cursor-pointer rounded-full bg-[#EAEDF5] flex justify-center items-center'>
|
||||||
|
{
|
||||||
|
props.isActive &&
|
||||||
|
<div className='size-2 bg-black rounded-full'></div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Radio
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
import Radio from './Radio'
|
||||||
|
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
items: {
|
||||||
|
label: string
|
||||||
|
value: string
|
||||||
|
}[]
|
||||||
|
selected: string
|
||||||
|
onChange: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const RadioGroup: FC<Props> = (props: Props) => {
|
||||||
|
return (
|
||||||
|
<div className='flex xl:flex-nowrap flex-wrap gap-3 xl:gap-5 items-center text-xs'>
|
||||||
|
{
|
||||||
|
props.items.map((item, index) => (
|
||||||
|
<div key={index} className='flex gap-2 items-center'>
|
||||||
|
<Radio value={item.value} onChange={props.onChange} isActive={item.value === props.selected} />
|
||||||
|
<div className='mt-0.5 whitespace-nowrap'>
|
||||||
|
{item.label}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RadioGroup
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import { type FC } from 'react'
|
||||||
|
import type { AttributeType } from '../type/Types'
|
||||||
|
import { clx } from '@/helpers/utils'
|
||||||
|
import { FieldTypeEnum } from '../enum/OrderEnum'
|
||||||
|
import Select from '@/components/Select'
|
||||||
|
import { Checkbox } from '@/components/ui/checkbox'
|
||||||
|
import RadioGroup from '@/components/RadioGroup'
|
||||||
|
import DatePickerComponent from '@/components/DatePicker'
|
||||||
|
import Input from '@/components/Input'
|
||||||
|
import Textarea from '@/components/Textarea'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
attributes?: AttributeType[]
|
||||||
|
}
|
||||||
|
|
||||||
|
const ManageAttribute: FC<Props> = (props) => {
|
||||||
|
|
||||||
|
const { attributes } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={clx(
|
||||||
|
!attributes && 'hidden'
|
||||||
|
)}>
|
||||||
|
{
|
||||||
|
attributes?.map((item) => {
|
||||||
|
if (item?.type === FieldTypeEnum.select)
|
||||||
|
return (
|
||||||
|
<div className='mt-6' key={item.id}>
|
||||||
|
<Select
|
||||||
|
placeholder={`انتخاب ${item.isRequired ? '(اجباری)' : '(اختاری)'}`}
|
||||||
|
label={item.name}
|
||||||
|
items={item.values?.map((value) => {
|
||||||
|
return {
|
||||||
|
label: value.value,
|
||||||
|
value: value.value
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else if (item.type === FieldTypeEnum.checkbox)
|
||||||
|
return (
|
||||||
|
<div key={item.id} className='mt-6'>
|
||||||
|
<div className='text-sm mb-3'>{item.name}</div>
|
||||||
|
<div className='flex gap-5 flex-wrap'>
|
||||||
|
{
|
||||||
|
item.values?.map((value) => {
|
||||||
|
return (
|
||||||
|
<div key={value.id} className='flex gap-2 items-center'>
|
||||||
|
<div>{value.value}</div>
|
||||||
|
<Checkbox
|
||||||
|
name={item.id + ''}
|
||||||
|
value={value.value}
|
||||||
|
onCheckedChange={(c) => console.log(c)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else if (item.type === FieldTypeEnum.radio)
|
||||||
|
return (
|
||||||
|
<div key={item.id} className='mt-6'>
|
||||||
|
<div className='text-sm mb-3'>{item.name}</div>
|
||||||
|
<RadioGroup
|
||||||
|
items={item.values?.map((value) => {
|
||||||
|
return {
|
||||||
|
label: value.value,
|
||||||
|
value: value.value
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
onChange={(v) => console.log(v)}
|
||||||
|
selected=''
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else if (item.type === FieldTypeEnum.date)
|
||||||
|
return (
|
||||||
|
<div key={item.id} className='mt-6'>
|
||||||
|
<DatePickerComponent
|
||||||
|
onChange={(date) => console.log(date)}
|
||||||
|
placeholder=''
|
||||||
|
label={item.name}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else if (item.type === FieldTypeEnum.number || item.type === FieldTypeEnum.text)
|
||||||
|
return (
|
||||||
|
<div key={item.id} className='mt-6'>
|
||||||
|
<Input
|
||||||
|
label={item.name}
|
||||||
|
type={item.type}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
else if (item.type === FieldTypeEnum.textarea)
|
||||||
|
return (
|
||||||
|
<div key={item.id} className='mt-6'>
|
||||||
|
<Textarea
|
||||||
|
label={item.name}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ManageAttribute
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { type FC } from 'react'
|
import { useState, type ChangeEvent, type FC } from 'react'
|
||||||
import Button from '@/components/Button'
|
import Button from '@/components/Button'
|
||||||
import Input from '@/components/Input'
|
import Input from '@/components/Input'
|
||||||
import Select from '@/components/Select'
|
import Select from '@/components/Select'
|
||||||
@@ -7,26 +7,96 @@ import VoiceRecorder from '@/components/VoiceRecorder'
|
|||||||
import { COLORS } from '@/constants/colors'
|
import { COLORS } from '@/constants/colors'
|
||||||
import { AddSquare } from 'iconsax-react'
|
import { AddSquare } from 'iconsax-react'
|
||||||
import ProductsSelect from './ProductsSelect'
|
import ProductsSelect from './ProductsSelect'
|
||||||
|
import { useFormik } from 'formik'
|
||||||
|
import * as Yup from 'yup'
|
||||||
|
import type { OrderType, ProductType } from '../type/Types'
|
||||||
|
import { useGetProducts } from '../hooks/useOrderData'
|
||||||
|
import ManageAttribute from './ManageAttribute'
|
||||||
|
|
||||||
const Order: FC = () => {
|
const Order: FC = () => {
|
||||||
|
|
||||||
|
const { data } = useGetProducts()
|
||||||
|
const [productSelected, setProductSelected] = useState<ProductType>()
|
||||||
|
// const [attribute, setAttribute] = useState<AttributeType>()
|
||||||
|
|
||||||
|
const formik = useFormik<OrderType>({
|
||||||
|
initialValues: {
|
||||||
|
productId: 0,
|
||||||
|
attachments: [],
|
||||||
|
quantity: undefined,
|
||||||
|
description: '',
|
||||||
|
},
|
||||||
|
validationSchema: Yup.object({
|
||||||
|
|
||||||
|
}),
|
||||||
|
onSubmit: (values) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChange = (e: ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
const productId = e.target.value
|
||||||
|
const product = data?.data?.find(o => Number(o.id) === Number(productId))
|
||||||
|
if (product) {
|
||||||
|
product.quantities.unshift(0)
|
||||||
|
setProductSelected(product)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const handleChangeAttribute = (e: ChangeEvent<HTMLSelectElement>) => {
|
||||||
|
// const attributeId = e.target.value
|
||||||
|
// const attribute = productSelected?.attributes?.find(o => Number(o.id) === Number(attributeId))
|
||||||
|
// if (attribute) {
|
||||||
|
// setAttribute(attribute)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='bg-white rounded-3xl p-6 mt-8'>
|
<div className='bg-white rounded-3xl p-6 mt-8'>
|
||||||
<div className='font-light'>اطلاعات سفارش</div>
|
<div className='font-light'>اطلاعات سفارش</div>
|
||||||
|
|
||||||
<div className='mt-6'>
|
<div className='mt-6 rowTwoInput'>
|
||||||
<ProductsSelect />
|
<ProductsSelect
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* <Select
|
||||||
|
label='ویژگی'
|
||||||
|
placeholder='انتخاب'
|
||||||
|
items={productSelected?.attributes?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id + ''
|
||||||
|
}
|
||||||
|
}) || []}
|
||||||
|
onChange={handleChangeAttribute}
|
||||||
|
/> */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<ManageAttribute
|
||||||
|
attributes={productSelected?.attributes}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='mt-6 rowTwoInput'>
|
<div className='mt-6 rowTwoInput'>
|
||||||
<Select
|
<Select
|
||||||
items={[]}
|
items={productSelected?.quantities?.map((item) => {
|
||||||
|
return {
|
||||||
|
label: item === 0 ? 'انتخاب دلخواه' : item + '',
|
||||||
|
value: item + ''
|
||||||
|
}
|
||||||
|
}) || []}
|
||||||
label='تعداد'
|
label='تعداد'
|
||||||
placeholder='انتخاب'
|
placeholder='انتخاب'
|
||||||
|
{...formik.getFieldProps('quantity')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Input
|
<Input
|
||||||
label='انتخاب دلخواه'
|
label='تعداد دلخواه'
|
||||||
placeholder='100'
|
readOnly={Number(formik.values.quantity) !== 0}
|
||||||
|
{...formik.getFieldProps('quantity')}
|
||||||
|
type='number'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -5,3 +5,13 @@ export const enum TabMyOrdersEnum {
|
|||||||
DELIVERED = "delivered",
|
DELIVERED = "delivered",
|
||||||
CANCELLED = "cancelled",
|
CANCELLED = "cancelled",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const enum FieldTypeEnum {
|
||||||
|
text = "text",
|
||||||
|
textarea = "textarea",
|
||||||
|
number = "number",
|
||||||
|
select = "select",
|
||||||
|
radio = "radio",
|
||||||
|
checkbox = "checkbox",
|
||||||
|
date = "date",
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { BaseResponse } from "@/shared/types/Types";
|
import type { BaseResponse } from "@/shared/types/Types";
|
||||||
|
import type { FieldTypeEnum } from "../enum/OrderEnum";
|
||||||
|
|
||||||
export type CategoryType = {
|
export type CategoryType = {
|
||||||
avatarUrl?: string;
|
avatarUrl?: string;
|
||||||
@@ -10,6 +11,36 @@ export type CategoryType = {
|
|||||||
title: string;
|
title: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type OrderType = {
|
||||||
|
productId: number;
|
||||||
|
quantity?: number;
|
||||||
|
// attributesValues: [],
|
||||||
|
attachments: {
|
||||||
|
url: string;
|
||||||
|
type: string;
|
||||||
|
}[];
|
||||||
|
description?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AttributeValueType = {
|
||||||
|
attribute: number;
|
||||||
|
createdAt: string;
|
||||||
|
id: number;
|
||||||
|
order: number;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AttributeType = {
|
||||||
|
createdAt: string;
|
||||||
|
id: number;
|
||||||
|
isRequired: boolean;
|
||||||
|
name: string;
|
||||||
|
order: number;
|
||||||
|
product: number;
|
||||||
|
type: FieldTypeEnum;
|
||||||
|
values: AttributeValueType[];
|
||||||
|
};
|
||||||
|
|
||||||
export type ProductType = {
|
export type ProductType = {
|
||||||
category: CategoryType;
|
category: CategoryType;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
@@ -21,6 +52,7 @@ export type ProductType = {
|
|||||||
order: number;
|
order: number;
|
||||||
quantities: number[];
|
quantities: number[];
|
||||||
title: string;
|
title: string;
|
||||||
|
attributes: AttributeType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProductsResponseType = BaseResponse<ProductType[]>;
|
export type ProductsResponseType = BaseResponse<ProductType[]>;
|
||||||
|
|||||||
Reference in New Issue
Block a user