Files
edr-platform/apps/edr-freight-web/backoffice/src/components/cargoes/DeliverCargoDialog.tsx
2026-06-22 11:52:59 +00:00

98 lines
3.5 KiB
TypeScript

import { useState } from 'react';
import { PackageCheck } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea';
import { useMutation } from '@tanstack/react-query';
import { api } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
/**
* Customer Pickup + Proof of Delivery capture for a LOADED cargo.
* Records receiver name, pickup date and remarks, then marks the cargo DELIVERED.
*/
export function DeliverCargoDialog({ cargoId, onSuccess }: { cargoId: string; onSuccess?: () => void }) {
const [open, setOpen] = useState(false);
const [receiverName, setReceiverName] = useState('');
const [pickupDate, setPickupDate] = useState('');
const [deliveryRemarks, setDeliveryRemarks] = useState('');
const deliver = useMutation(api.cargoes.deliver.mutationOptions());
const { toast } = useToast();
const handleDeliver = async () => {
if (!receiverName.trim()) {
toast({ title: 'Receiver name is required', variant: 'destructive' });
return;
}
try {
await deliver.mutateAsync({
id: cargoId,
payload: {
receiverName: receiverName.trim(),
pickupDate: pickupDate ? new Date(pickupDate).toISOString() : undefined,
deliveryRemarks: deliveryRemarks.trim() || undefined,
},
});
toast({ title: 'Delivered', description: 'Proof of delivery recorded; cargo marked delivered.' });
setOpen(false);
setReceiverName('');
setPickupDate('');
setDeliveryRemarks('');
onSuccess?.();
} catch (error) {
const message =
(error as { response?: { data?: { message?: string } } })?.response?.data?.message ??
'Could not record delivery.';
toast({ title: 'Delivery failed', description: String(message), variant: 'destructive' });
}
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" title="Customer pickup / Proof of delivery">
<PackageCheck className="size-4" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Customer Pickup &amp; Proof of Delivery</DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div>
<Label>Receiver name*</Label>
<Input
required
value={receiverName}
placeholder="Name of person collecting the cargo"
onChange={(e) => setReceiverName(e.target.value)}
/>
</div>
<div>
<Label>Pickup date</Label>
<Input
type="datetime-local"
value={pickupDate}
onChange={(e) => setPickupDate(e.target.value)}
/>
</div>
<div>
<Label>Remarks</Label>
<Textarea
value={deliveryRemarks}
placeholder="Condition on handover, ID checked, etc."
onChange={(e) => setDeliveryRemarks(e.target.value)}
/>
</div>
<Button onClick={handleDeliver} disabled={deliver.isPending} className="w-full">
{deliver.isPending ? 'Recording…' : 'Confirm Pickup & Mark Delivered'}
</Button>
</div>
</DialogContent>
</Dialog>
);
}