Files
negareh-admin/src/pages/requests/components/RequestItem.tsx
T
morteza 44cb2f099d
deploy to danak / build_and_deploy (push) Has been cancelled
up
2026-06-26 11:19:05 +03:30

121 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { type FC } from 'react'
import type { RequestDetailItemType } from '../types/Types'
import { useGetEntityField } from '@/pages/formBuilder/hooks/useFormBuilderData'
import { Paperclip2 } from 'iconsax-react'
import placeholderProductImage from '@/assets/images/placeholder-product.svg'
type Props = {
item: RequestDetailItemType
}
const RequestItem: FC<Props> = ({ item }) => {
const { data: fields } = useGetEntityField(String(item.product?.id ?? ''))
const attributes = item.attributes ?? []
const getAttributeFieldId = (attribute: NonNullable<RequestDetailItemType['attributes']>[number]) =>
attribute.fieldId ?? attribute.attributeId ?? attribute.field?.id
const fieldRows = fields?.data?.map((field) => ({
id: field.id,
name: field.name,
value: attributes.find((attribute) => String(getAttributeFieldId(attribute)) === String(field.id))?.value,
})) ?? []
const matchedFieldIds = new Set(fieldRows.map((field) => String(field.id)))
const extraAttributeRows = attributes
.filter((attribute) => {
const fieldId = getAttributeFieldId(attribute)
return fieldId && !matchedFieldIds.has(String(fieldId))
})
.map((attribute) => ({
id: String(getAttributeFieldId(attribute)),
name: attribute.field?.name ?? String(getAttributeFieldId(attribute)),
value: attribute.value,
}))
const attributeRows = [...fieldRows, ...extraAttributeRows]
const handleOpenAttachment = (url: string) => {
window.open(url, '_blank')
}
const productImage = item.product?.images?.[0]
return (
<div key={item.product?.id} className='border border-border rounded-3xl p-6'>
<div className="flex items-center gap-6">
{/* Product Image */}
<div className='size-[86px] rounded-lg overflow-hidden bg-gray-100'>
<img
src={productImage || placeholderProductImage}
alt={item.product?.title ?? 'محصول'}
className='size-full object-cover'
onError={(e) => {
e.currentTarget.src = placeholderProductImage
}}
/>
</div>
{/* Request Details */}
<div className="flex-1 flex gap-20 pr-10 flex-wrap">
<div className='flex items-center gap-2'>
<div className="text-xs text-desc">عنوان:</div>
<div className="text-sm font-medium text-black">{item.product?.title}</div>
</div>
<div className='flex items-center gap-2'>
<div className="text-xs text-desc">تعداد:</div>
<div className="text-sm font-medium text-black">{item.quantity}</div>
</div>
</div>
</div>
{/* Description */}
{item.description && (
<div className="mt-6 pt-6 border-t border-dashed border-desc">
<div className="text-sm font-medium mb-2 text-desc">شرح درخواست:</div>
<p className="text-sm font-light text-black leading-6">
{item.description}
</p>
</div>
)}
{/* Attributes */}
{attributeRows.length ? (
<>
<div className='font-bold mb-5 mt-7'>ویژگی ها</div>
{
attributeRows.map((field) => (
<div className='flex gap-3 items-center mt-3' key={field.id}>
<div className='text-sm text-gray-500'>{field.name}:</div>
<div className='text-sm -mt-px'>{field.value || '-'}</div>
</div>
))
}
</>
) : null}
{/* Attachments */}
{item.attachments?.length ? (
<div className='mt-6 pt-6 border-t border-dashed border-desc'>
<div className='text-sm font-medium mb-2 text-desc'>ضمایم:</div>
<div className="flex gap-3 flex-wrap">
{item.attachments
?.filter((url): url is string => typeof url === 'string')
.map((url, index) => (
<button
key={index}
onClick={() => handleOpenAttachment(url as string)}
className="flex cursor-pointer items-center gap-1.5 text-[#0047FF] hover:underline"
>
<Paperclip2 size={20} color="#0047FF" />
<span className="text-xs">فایل {index + 1}</span>
</button>
))}
</div>
</div>
) : null}
</div>
)
}
export default RequestItem