fix: prevent new backend guards from ever surfacing as raw errors
The colony-apiary and queen-availability validation just added backend-side had no matching frontend guard, so a user could still pick an inactive apiary or open the assign-colony dialog on an unavailable queen and only find out it fails after submitting: - Colony create/move apiary pickers now fetch only ACTIVE apiaries. - The queen "Volk zuweisen" button is disabled once her status is LOST/REPLACED/SOLD/DECEASED (QUEEN_UNAVAILABLE_STATUSES, mirroring the backend's QUEEN_NO_LONGER_AVAILABLE_STATUSES), instead of only failing after the form is filled out and submitted. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
1 parent
3e179391b0
commit
3678a01319
5 files changed
+37
-5
No files matched your search
@@ -48,7 +48,10 @@ function MoveDialog({ colony }: { colony: Colony }) {
|
||||
const queryClient = useQueryClient();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [apiaryId, setApiaryId] = useState("");
|
||||
const { data: apiaries } = useQuery({ queryKey: ["apiaries"], queryFn: () => fetchApiaries() });
|
||||
const { data: apiaries } = useQuery({
|
||||
queryKey: ["apiaries", { status: "ACTIVE" }],
|
||||
queryFn: () => fetchApiaries({ status: "ACTIVE" }),
|
||||
});
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: () => moveColony(colony.id, { apiaryId }),
|
||||
|
||||
@@ -24,7 +24,10 @@ import { Card, CardContent } from "@/components/ui/card";
|
||||
export default function NewColonyPage() {
|
||||
const router = useRouter();
|
||||
const queryClient = useQueryClient();
|
||||
const { data: apiaries } = useQuery({ queryKey: ["apiaries"], queryFn: () => fetchApiaries() });
|
||||
const { data: apiaries } = useQuery({
|
||||
queryKey: ["apiaries", { status: "ACTIVE" }],
|
||||
queryFn: () => fetchApiaries({ status: "ACTIVE" }),
|
||||
});
|
||||
|
||||
const [code, setCode] = useState("");
|
||||
const [apiaryId, setApiaryId] = useState("");
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
import { FormEvent, useState } from "react";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { assignQueenColony } from "@/lib/queens/api";
|
||||
import { QUEEN_UNAVAILABLE_STATUSES } from "@/lib/queens/labels";
|
||||
import { QueenStatus } from "@/lib/queens/types";
|
||||
import { fetchColonies } from "@/lib/colonies/api";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Label } from "@/components/ui/label";
|
||||
@@ -22,11 +24,18 @@ import {
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
export function AssignColonyDialog({ queenId }: { queenId: string }) {
|
||||
export function AssignColonyDialog({
|
||||
queenId,
|
||||
queenStatus,
|
||||
}: {
|
||||
queenId: string;
|
||||
queenStatus: QueenStatus;
|
||||
}) {
|
||||
const queryClient = useQueryClient();
|
||||
const [open, setOpen] = useState(false);
|
||||
const [colonyId, setColonyId] = useState("");
|
||||
const { data: colonies } = useQuery({ queryKey: ["colonies"], queryFn: () => fetchColonies() });
|
||||
const unavailable = QUEEN_UNAVAILABLE_STATUSES.includes(queenStatus);
|
||||
|
||||
const mutation = useMutation({
|
||||
mutationFn: () => assignQueenColony(queenId, { colonyId }),
|
||||
@@ -39,7 +48,13 @@ export function AssignColonyDialog({ queenId }: { queenId: string }) {
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogTrigger render={<Button variant="outline">Volk zuweisen</Button>} />
|
||||
<DialogTrigger
|
||||
render={
|
||||
<Button variant="outline" disabled={unavailable}>
|
||||
Volk zuweisen
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Königin einem Volk zuweisen</DialogTitle>
|
||||
|
||||
@@ -37,7 +37,7 @@ export default function QueenDetailPage() {
|
||||
<div className="grid grid-cols-1 items-start gap-4 lg:grid-cols-3">
|
||||
<div className="flex flex-col gap-4 lg:col-span-1">
|
||||
<QueenEditCard key={queen.id} queen={queen} />
|
||||
<AssignColonyDialog queenId={queen.id} />
|
||||
<AssignColonyDialog queenId={queen.id} queenStatus={queen.status} />
|
||||
</div>
|
||||
<div className="flex flex-col gap-4 lg:col-span-2">
|
||||
<div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
||||
|
||||
@@ -12,6 +12,17 @@ export const QUEEN_STATUSES: QueenStatus[] = [
|
||||
"DECEASED",
|
||||
];
|
||||
|
||||
// Mirrors the backend's QUEEN_NO_LONGER_AVAILABLE_STATUSES - a queen in one
|
||||
// of these statuses can no longer be assigned to a colony (the backend
|
||||
// rejects it), so the assign-colony UI disables itself instead of letting
|
||||
// the user hit that error after filling out the form.
|
||||
export const QUEEN_UNAVAILABLE_STATUSES: QueenStatus[] = [
|
||||
"LOST",
|
||||
"REPLACED",
|
||||
"SOLD",
|
||||
"DECEASED",
|
||||
];
|
||||
|
||||
export const QUEEN_STATUS_LABELS: Record<QueenStatus, string> = {
|
||||
ACTIVE: "Aktiv",
|
||||
RESERVE: "Reserve",
|
||||
|
||||
Reference in new issue
Block a user