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 Input from '@/components/Input'
|
||||
import Select from '@/components/Select'
|
||||
@@ -7,26 +7,96 @@ import VoiceRecorder from '@/components/VoiceRecorder'
|
||||
import { COLORS } from '@/constants/colors'
|
||||
import { AddSquare } from 'iconsax-react'
|
||||
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 { 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 (
|
||||
<div className='bg-white rounded-3xl p-6 mt-8'>
|
||||
<div className='font-light'>اطلاعات سفارش</div>
|
||||
|
||||
<div className='mt-6'>
|
||||
<ProductsSelect />
|
||||
<div className='mt-6 rowTwoInput'>
|
||||
<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 className='mt-6 rowTwoInput'>
|
||||
<Select
|
||||
items={[]}
|
||||
items={productSelected?.quantities?.map((item) => {
|
||||
return {
|
||||
label: item === 0 ? 'انتخاب دلخواه' : item + '',
|
||||
value: item + ''
|
||||
}
|
||||
}) || []}
|
||||
label='تعداد'
|
||||
placeholder='انتخاب'
|
||||
{...formik.getFieldProps('quantity')}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label='انتخاب دلخواه'
|
||||
placeholder='100'
|
||||
label='تعداد دلخواه'
|
||||
readOnly={Number(formik.values.quantity) !== 0}
|
||||
{...formik.getFieldProps('quantity')}
|
||||
type='number'
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -5,3 +5,13 @@ export const enum TabMyOrdersEnum {
|
||||
DELIVERED = "delivered",
|
||||
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 { FieldTypeEnum } from "../enum/OrderEnum";
|
||||
|
||||
export type CategoryType = {
|
||||
avatarUrl?: string;
|
||||
@@ -10,6 +11,36 @@ export type CategoryType = {
|
||||
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 = {
|
||||
category: CategoryType;
|
||||
createdAt: string;
|
||||
@@ -21,6 +52,7 @@ export type ProductType = {
|
||||
order: number;
|
||||
quantities: number[];
|
||||
title: string;
|
||||
attributes: AttributeType[];
|
||||
};
|
||||
|
||||
export type ProductsResponseType = BaseResponse<ProductType[]>;
|
||||
|
||||
Reference in New Issue
Block a user