feat(jobs): clinic-side 'Düzeltme İste' (revision request) flow
Up to now the only thing a clinic could do on a prova was approve it.
If the casting didn't fit there was no way to bounce the case back to
the lab short of cancelling the whole thing. Real-world flow needs a
'try again, this is what's wrong' lever, so:
- requestRevisionAction (clinic only): pre-conditions
in_progress + at_clinic + currentStep set; flips location → at_lab
while leaving currentStep untouched so the same prova stage repeats
after the lab redoes the work. Requires a note (the lab can't fix
what it doesn't know is broken) — appended to job_status_history
with a '[Düzeltme talebi]' prefix and surfaced to the lab via
notification.
- JobActionsPanel: when the clinic side sees a prova (in_progress +
at_clinic) it now shows two buttons — Onayla as before, plus
Düzeltme İste (variant=destructive). The dialog requires a note
before submit.
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
Loader2,
|
||||
PackageCheck,
|
||||
Play,
|
||||
RotateCcw,
|
||||
Send,
|
||||
X,
|
||||
} from "lucide-react";
|
||||
@@ -32,6 +33,7 @@ import {
|
||||
cancelJobAction,
|
||||
handToClinicAction,
|
||||
markDeliveredAction,
|
||||
requestRevisionAction,
|
||||
} from "@/lib/appwrite/job-actions";
|
||||
import { initialJobActionState } from "@/lib/appwrite/job-types";
|
||||
import type { Job, TenantKind } from "@/lib/appwrite/schema";
|
||||
@@ -67,7 +69,10 @@ export function JobActionsPanel({
|
||||
|
||||
{/* Clinic finished the prova — approve and send back to lab */}
|
||||
{isClinic && job.status === "in_progress" && isAtClinic && (
|
||||
<ApproveAtClinicButton job={job} />
|
||||
<>
|
||||
<ApproveAtClinicButton job={job} />
|
||||
<RequestRevisionButton job={job} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Final delivery — clinic took it from the lab */}
|
||||
@@ -236,6 +241,68 @@ function ApproveAtClinicButton({ job }: { job: Job }) {
|
||||
);
|
||||
}
|
||||
|
||||
function RequestRevisionButton({ job }: { job: Job }) {
|
||||
const router = useRouter();
|
||||
const [state, action, pending] = useActionState(
|
||||
requestRevisionAction,
|
||||
initialJobActionState,
|
||||
);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (state.ok) {
|
||||
toast.success("Düzeltme talebi gönderildi.");
|
||||
setOpen(false);
|
||||
router.refresh();
|
||||
} else if (state.error) {
|
||||
toast.error(state.error);
|
||||
}
|
||||
}, [state, router]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<Button variant="outline" onClick={() => setOpen(true)}>
|
||||
<RotateCcw className="size-4" />
|
||||
Düzeltme İste
|
||||
</Button>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Provayı reddet, lab'a geri gönder</DialogTitle>
|
||||
<DialogDescription>
|
||||
Bu aşamayı reddettiğinizde iş aynı adımda kalır ve laboratuvar
|
||||
yeniden çalışır. Neyin düzeltilmesi gerektiğini lütfen yazın.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<form action={action} className="grid gap-3">
|
||||
<input type="hidden" name="jobId" value={job.$id} />
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="note">Düzeltme notu *</Label>
|
||||
<Textarea
|
||||
id="note"
|
||||
name="note"
|
||||
rows={4}
|
||||
required
|
||||
maxLength={1000}
|
||||
placeholder="Örn. Distalde temas yok, oklüzyon yüksek geldi."
|
||||
/>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<DialogClose asChild>
|
||||
<Button type="button" variant="outline">
|
||||
Vazgeç
|
||||
</Button>
|
||||
</DialogClose>
|
||||
<Button type="submit" variant="destructive" disabled={pending}>
|
||||
{pending ? <Loader2 className="size-4 animate-spin" /> : <RotateCcw className="size-4" />}
|
||||
Düzeltme İste
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</form>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
function DeliverButton({ jobId }: { jobId: string }) {
|
||||
const router = useRouter();
|
||||
const [state, action, pending] = useActionState(markDeliveredAction, initialJobActionState);
|
||||
|
||||
Reference in New Issue
Block a user