From 306297ed09080c3d0660c0b90153715bd44308a9 Mon Sep 17 00:00:00 2001 From: shafi54 <108669266+shafi-aviz@users.noreply.github.com> Date: Sun, 19 Jul 2026 09:54:14 +0530 Subject: [PATCH] enh --- apps/user-ui/components/SlotSpecificView.tsx | 2 +- apps/web-ui/src/components/ComplaintForm.tsx | 173 +++++ .../src/hooks/useUploadToObjectStorage.ts | 119 +++ apps/web-ui/src/lib/string-manipulators.ts | 6 + apps/web-ui/src/routes/me.orders.$id.tsx | 718 +++++++++--------- 5 files changed, 642 insertions(+), 376 deletions(-) create mode 100644 apps/web-ui/src/components/ComplaintForm.tsx create mode 100644 apps/web-ui/src/hooks/useUploadToObjectStorage.ts create mode 100644 apps/web-ui/src/lib/string-manipulators.ts diff --git a/apps/user-ui/components/SlotSpecificView.tsx b/apps/user-ui/components/SlotSpecificView.tsx index 2cb714c..7798640 100644 --- a/apps/user-ui/components/SlotSpecificView.tsx +++ b/apps/user-ui/components/SlotSpecificView.tsx @@ -292,7 +292,7 @@ const CompactProductCard = ({ onChange={handleQuantityChange} step={item.incrementStep} showUnits={true} - unit={item.unitNotation} + // unit={item.unitNotation} /> ) : ( void + orderId: number +} + +interface ComplaintImage { + imgUrl: string + mimeType: string + file: File +} + +export default function ComplaintForm({ open, onClose, orderId }: ComplaintFormProps) { + const [complaintBody, setComplaintBody] = useState('') + const [complaintImages, setComplaintImages] = useState([]) + const fileInputRef = useRef(null) + + const raiseComplaintMutation = trpc.user.complaint.raise.useMutation() + const { refetch: refetchComplaints } = trpc.user.complaint.getAll.useQuery(undefined, { + enabled: false, + }) + + const { upload, isUploading } = useUploadToObjectStorage() + + const handleAddImages = (files: FileList | null) => { + if (!files || files.length === 0) return + const newImages: ComplaintImage[] = [] + Array.from(files).forEach((file) => { + if (!file.type.startsWith('image/')) return + newImages.push({ + imgUrl: URL.createObjectURL(file), + mimeType: file.type || 'image/jpeg', + file, + }) + }) + setComplaintImages((prev) => [...prev, ...newImages]) + } + + const handleRemoveImage = (image: ComplaintImage) => { + setComplaintImages((prev) => { + URL.revokeObjectURL(image.imgUrl) + return prev.filter((item) => item.imgUrl !== image.imgUrl) + }) + } + + const handleSubmit = async () => { + if (!complaintBody.trim()) { + alert('Please enter complaint details') + return + } + + try { + let imageUrls: string[] = [] + + if (complaintImages.length > 0) { + const uploadImages = complaintImages.map((image) => ({ + blob: image.file, + mimeType: image.mimeType || 'image/jpeg', + })) + + const { keys } = await upload({ + images: uploadImages, + contextString: 'complaint', + }) + + imageUrls = keys + } + + await raiseComplaintMutation.mutateAsync({ + orderId: orderId.toString(), + complaintBody: complaintBody.trim(), + imageUrls, + }) + + await refetchComplaints() + alert('Complaint raised successfully') + setComplaintBody('') + setComplaintImages([]) + onClose() + } catch (error: any) { + alert(error.message || 'Failed to raise complaint') + } + } + + if (!open) return null + + return ( +
+
+

Raise Complaint

+ +
+ +

Describe the issue

+