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