From 96e316aa8e87258411d448229a450e10c00ad0aa Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Fri, 27 Feb 2026 00:55:33 +0000 Subject: [PATCH] Changes --- src/components/InspectionChecklist.tsx | 136 +++++++++++++++++++++++++ src/components/ViewerControls.tsx | 43 ++++++++ src/components/three/ModelViewer.tsx | 56 +++++++++- src/pages/Viewer.tsx | 52 ++++++---- src/stores/useModelStore.ts | 45 ++++++++ 5 files changed, 308 insertions(+), 24 deletions(-) create mode 100644 src/components/InspectionChecklist.tsx create mode 100644 src/components/ViewerControls.tsx diff --git a/src/components/InspectionChecklist.tsx b/src/components/InspectionChecklist.tsx new file mode 100644 index 0000000..9705518 --- /dev/null +++ b/src/components/InspectionChecklist.tsx @@ -0,0 +1,136 @@ +import { CheckCircle, XCircle, Clock, MessageSquare } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { Textarea } from '@/components/ui/textarea'; +import { useModelStore, type ChecklistItem } from '@/stores/useModelStore'; +import { useState } from 'react'; +import { toast } from 'sonner'; + +function ChecklistRow({ item }: { item: ChecklistItem }) { + const { setChecklistItemStatus, setChecklistItemNote } = useModelStore(); + const [showNote, setShowNote] = useState(item.status === 'rejected'); + + const handleApprove = () => { + setChecklistItemStatus(item.id, 'approved'); + setShowNote(false); + toast.success(`"${item.label}" aprovado`); + }; + + const handleReject = () => { + setChecklistItemStatus(item.id, 'rejected'); + setShowNote(true); + toast.error(`"${item.label}" reprovado — adicione uma anotação`); + }; + + const statusColor = + item.status === 'approved' ? 'text-success' : + item.status === 'rejected' ? 'text-destructive' : + 'text-muted-foreground'; + + const StatusIcon = + item.status === 'approved' ? CheckCircle : + item.status === 'rejected' ? XCircle : + Clock; + + return ( +