Add delivery task fail dialog
This commit is contained in:
+103
@@ -0,0 +1,103 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useForm, zodResolver, z } from '@/lib/form'
|
||||||
|
import { FormField } from '@/components/shared/form-field'
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Button } from '@/components/ui/button'
|
||||||
|
import {
|
||||||
|
Dialog,
|
||||||
|
DialogContent,
|
||||||
|
DialogHeader,
|
||||||
|
DialogTitle,
|
||||||
|
DialogDescription,
|
||||||
|
DialogFooter,
|
||||||
|
} from '@/components/ui/dialog'
|
||||||
|
import { FieldGroup } from '@/components/ui/field'
|
||||||
|
import { toast } from '@/components/ui/toast'
|
||||||
|
import { deliveryTasks as deliveryTasksApi, getApiError } from '@/lib/api/index'
|
||||||
|
import type { DeliveryTaskResponse } from '@/types/api'
|
||||||
|
|
||||||
|
const schema = z.object({
|
||||||
|
note: z.string().min(1, 'Reason is required'),
|
||||||
|
})
|
||||||
|
|
||||||
|
type FormValues = z.infer<typeof schema>
|
||||||
|
|
||||||
|
interface DeliveryTaskFailDialogProps {
|
||||||
|
open: boolean
|
||||||
|
onClose: () => void
|
||||||
|
onSuccess: () => void
|
||||||
|
task: DeliveryTaskResponse | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DeliveryTaskFailDialog({ open, onClose, onSuccess, task }: DeliveryTaskFailDialogProps) {
|
||||||
|
const form = useForm<FormValues>({
|
||||||
|
resolver: zodResolver(schema),
|
||||||
|
defaultValues: { note: '' },
|
||||||
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (open) {
|
||||||
|
form.reset({ note: '' })
|
||||||
|
}
|
||||||
|
}, [open])
|
||||||
|
|
||||||
|
if (!task) return null
|
||||||
|
|
||||||
|
async function onSubmit(values: FormValues) {
|
||||||
|
try {
|
||||||
|
await deliveryTasksApi.fail(task!.id, values.note)
|
||||||
|
toast.add({ title: 'Delivery task marked as failed', type: 'success' })
|
||||||
|
onSuccess()
|
||||||
|
onClose()
|
||||||
|
} catch (err) {
|
||||||
|
toast.add({ title: 'Failed to update task', description: getApiError(err), type: 'error' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog open={open} onOpenChange={(v) => !v && onClose()}>
|
||||||
|
<DialogContent className="overflow-y-auto sm:max-w-lg">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Mark Delivery Failed</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Record why this delivery could not be completed.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
|
||||||
|
<form onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-6">
|
||||||
|
<FieldGroup>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="note"
|
||||||
|
label="Reason"
|
||||||
|
required
|
||||||
|
render={({ field, invalid }) => (
|
||||||
|
<Input
|
||||||
|
id="note"
|
||||||
|
name={field.name}
|
||||||
|
ref={field.ref}
|
||||||
|
value={field.value as string}
|
||||||
|
onChange={field.onChange}
|
||||||
|
onBlur={field.onBlur}
|
||||||
|
placeholder="Reason the delivery failed..."
|
||||||
|
aria-invalid={invalid}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</FieldGroup>
|
||||||
|
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type="button" variant="outline" onClick={onClose}>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" variant="destructive" disabled={form.formState.isSubmitting}>
|
||||||
|
{form.formState.isSubmitting ? 'Submitting…' : 'Mark as Failed'}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user