Files
edr-platform/apps/edr-freight-web/backoffice/src/components/warehouses/DeliverInventoryModal.tsx

83 lines
2.7 KiB
TypeScript

import { useEffect, useState } from 'react';
import { Alert, Button, Group, Modal, Stack, Text, Textarea, TextInput } from '@mantine/core';
import { Info } from 'lucide-react';
import { useMutation } from '@tanstack/react-query';
import { api } from '@/services/api';
import { useToast } from '@/hooks/use-toast';
import type { WarehouseInventoryItem } from '@/types/warehouse';
import { extractErrorMessage } from './options';
interface DeliverInventoryModalProps {
opened: boolean;
onClose: () => void;
item: WarehouseInventoryItem | null;
}
export function DeliverInventoryModal({ opened, onClose, item }: DeliverInventoryModalProps) {
const { toast } = useToast();
const deliverMutation = useMutation(api.warehouses.deliver.mutationOptions());
const [receiverName, setReceiverName] = useState('');
const [remarks, setRemarks] = useState('');
useEffect(() => {
if (opened) {
setReceiverName('');
setRemarks('');
}
}, [opened, item]);
const handleSubmit = async () => {
if (!item) return;
if (!receiverName.trim()) {
toast({ variant: 'destructive', title: 'Receiver name is required' });
return;
}
try {
await deliverMutation.mutateAsync({
id: item.id,
payload: { receiverName: receiverName.trim(), remarks: remarks.trim() || undefined },
});
toast({ title: 'Delivered — proof of delivery captured' });
onClose();
} catch (error) {
toast({ variant: 'destructive', title: 'Delivery failed', description: extractErrorMessage(error) });
}
};
return (
<Modal opened={opened} onClose={onClose} title="Deliver to customer (proof of delivery)" centered size="md">
<Stack gap="md">
<Alert icon={<Info size={16} />} color="green" variant="light">
<Text size="sm">
A release order must already be issued. Capturing the receiver marks the goods <b>DELIVERED</b>.
</Text>
</Alert>
<TextInput
label="Receiver name"
required
placeholder="Who received the goods"
value={receiverName}
onChange={(e) => setReceiverName(e.currentTarget.value)}
/>
<Textarea
label="Remarks"
placeholder="Optional delivery notes"
minRows={2}
value={remarks}
onChange={(e) => setRemarks(e.currentTarget.value)}
/>
<Group justify="flex-end" mt="sm">
<Button variant="default" onClick={onClose} disabled={deliverMutation.isPending}>
Cancel
</Button>
<Button color="green" onClick={handleSubmit} loading={deliverMutation.isPending}>
Confirm delivery
</Button>
</Group>
</Stack>
</Modal>
);
}