feat(inspection): кнопка «Продолжить осмотр» на автозакрытом
Бэкенд раз в час закрывает осмотры, которые несколько часов никто не трогает, — иначе снятые фото не попадают в отчёты. Редактирование в приложении завязано на статус, поэтому механик, вернувшийся с перерыва, упирался бы в заблокированную карточку и заводил осмотр заново. На автозакрытом (meta.auto_completed) показываем плашку с объяснением и кнопку: статус возвращается в in_progress, редактор открывается снова. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import { AuthImg } from "@/components/AuthImg";
|
|||||||
import { ttImageUrl } from "@/api/vehicles";
|
import { ttImageUrl } from "@/api/vehicles";
|
||||||
import { VendorVehicleScheme } from "@/components/vehicle-scheme/VendorVehicleScheme";
|
import { VendorVehicleScheme } from "@/components/vehicle-scheme/VendorVehicleScheme";
|
||||||
import { Card } from "@/components/ui/card";
|
import { Card } from "@/components/ui/card";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
import { loadZoneLabels } from "@/data/zoneLabels";
|
import { loadZoneLabels } from "@/data/zoneLabels";
|
||||||
|
|
||||||
const STATUS_LABELS: Record<string, string> = {
|
const STATUS_LABELS: Record<string, string> = {
|
||||||
@@ -138,6 +139,19 @@ export default function InspectionReview() {
|
|||||||
onError: () => toast.error("Не удалось сохранить заметку"),
|
onError: () => toast.error("Не удалось сохранить заметку"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Осмотр закрыт не механиком, а автоматикой — вернуть в работу и дать
|
||||||
|
// доснять. Без этой кнопки механик, вернувшийся через три часа, упирается в
|
||||||
|
// заблокированную карточку и вынужден заводить осмотр заново.
|
||||||
|
const reopenMutation = useMutation({
|
||||||
|
mutationFn: () => patchInspection(insId, { status: "in_progress" }),
|
||||||
|
onSuccess: (updated) => {
|
||||||
|
queryClient.setQueryData(["inspection", insId], updated);
|
||||||
|
queryClient.invalidateQueries({ queryKey: ["vehicle"] });
|
||||||
|
navigate(`/inspections/${insId}/edit`);
|
||||||
|
},
|
||||||
|
onError: () => toast.error("Не удалось вернуть осмотр в работу"),
|
||||||
|
});
|
||||||
|
|
||||||
if (isLoading) return <div className="p-8 text-muted-foreground">Загружаю…</div>;
|
if (isLoading) return <div className="p-8 text-muted-foreground">Загружаю…</div>;
|
||||||
if (isError || !ins)
|
if (isError || !ins)
|
||||||
return <div className="p-8 text-destructive">Осмотр не найден.</div>;
|
return <div className="p-8 text-destructive">Осмотр не найден.</div>;
|
||||||
@@ -233,6 +247,27 @@ export default function InspectionReview() {
|
|||||||
)}
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{ins.meta?.auto_completed === true && (
|
||||||
|
<Card className="p-4 space-y-3 border-amber-500/40 bg-amber-500/10">
|
||||||
|
<div className="text-sm">
|
||||||
|
<div className="font-semibold">Закрыт автоматически</div>
|
||||||
|
<p className="mt-1 text-muted-foreground leading-relaxed">
|
||||||
|
Осмотр несколько часов никто не открывал, поэтому система завершила
|
||||||
|
его сама — чтобы фотографии не пропали из отчётов. Если работа не
|
||||||
|
доделана, верните осмотр в работу и продолжите.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className="w-full"
|
||||||
|
onClick={() => reopenMutation.mutate()}
|
||||||
|
disabled={reopenMutation.isPending}
|
||||||
|
>
|
||||||
|
{reopenMutation.isPending ? "Открываю…" : "Продолжить осмотр"}
|
||||||
|
</Button>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
<Card className="p-4 space-y-2">
|
<Card className="p-4 space-y-2">
|
||||||
<h2 className="text-sm font-semibold text-muted-foreground">
|
<h2 className="text-sm font-semibold text-muted-foreground">
|
||||||
Заметки механика
|
Заметки механика
|
||||||
|
|||||||
Reference in New Issue
Block a user