fix(01-03): defer species/breed Select render until data loads — fixes CUID showing in trigger

This commit is contained in:
admin committed 2026-06-06 10:35:31 +02:00
1 parent 63ec6637b1
commit c4588098ca
1 file changed
+76 -71
+76 -71
View File
@@ -19,6 +19,7 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { Skeleton } from "@/components/ui/skeleton";
/**
* PetForm — reusable create/edit form for pet profiles.
@@ -98,12 +99,12 @@ export function PetForm({
initialValues?.speciesId ?? ""
);
const { data: speciesList = [] } = useQuery({
const { data: speciesList = [], isLoading: speciesLoading } = useQuery({
...trpc.pets.listSpecies.queryOptions(),
staleTime: Infinity,
});
const { data: breedList = [] } = useQuery({
const { data: breedList = [], isLoading: breedsLoading } = useQuery({
...trpc.pets.listBreeds.queryOptions(
{ speciesId: selectedSpeciesId || "__none__" },
),
@@ -201,40 +202,42 @@ export function PetForm({
)}
</div>
{/* Species selector */}
{/* Species selector — defer render until list loaded so SelectValue resolves names */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="species">Species</Label>
<Controller
name="speciesId"
control={control}
render={({ field }) => (
<Select
value={field.value || null}
onValueChange={(val) => {
const newVal = val ?? "";
field.onChange(newVal);
setSelectedSpeciesId(newVal);
// Reset breed when species changes (species and breed are coupled)
setValue("breedId", null);
}}
>
<SelectTrigger
id="species"
className="w-full"
aria-invalid={!!errors.speciesId}
{speciesLoading ? (
<Skeleton className="h-9 w-full" />
) : (
<Controller
name="speciesId"
control={control}
render={({ field }) => (
<Select
value={field.value || undefined}
onValueChange={(val) => {
field.onChange(val);
setSelectedSpeciesId(val);
setValue("breedId", null);
}}
>
<SelectValue placeholder="Select species" />
</SelectTrigger>
<SelectContent>
{speciesList.map((species) => (
<SelectItem key={species.id} value={species.id}>
{species.name}
</SelectItem>
))}
</SelectContent>
</Select>
)}
/>
<SelectTrigger
id="species"
className="w-full"
aria-invalid={!!errors.speciesId}
>
<SelectValue placeholder="Select species" />
</SelectTrigger>
<SelectContent>
{speciesList.map((species) => (
<SelectItem key={species.id} value={species.id}>
{species.name}
</SelectItem>
))}
</SelectContent>
</Select>
)}
/>
)}
{errors.speciesId && (
<p className="text-xs text-destructive">
{errors.speciesId.message}
@@ -242,49 +245,51 @@ export function PetForm({
)}
</div>
{/* Breed selector */}
{/* Breed selector — defer render until list loaded so SelectValue resolves names */}
<div className="flex flex-col gap-1.5">
<Label htmlFor="breed">Breed</Label>
<Controller
name="breedId"
control={control}
render={({ field }) => (
<Select
value={field.value ?? null}
onValueChange={(val) => {
field.onChange(val ?? null);
}}
disabled={!selectedSpeciesId}
>
<SelectTrigger
id="breed"
className="w-full"
{selectedSpeciesId && breedsLoading ? (
<Skeleton className="h-9 w-full" />
) : (
<Controller
name="breedId"
control={control}
render={({ field }) => (
<Select
value={field.value ?? undefined}
onValueChange={(val) => field.onChange(val ?? null)}
disabled={!selectedSpeciesId}
>
<SelectValue
placeholder={
selectedSpeciesId
? "Select breed (optional)"
: "Select a species first"
}
/>
</SelectTrigger>
<SelectContent>
{breedList.length === 0 ? (
<SelectItem value="__empty__" disabled>
No breeds found for this species.
</SelectItem>
) : (
breedList.map((breed) => (
<SelectItem key={breed.id} value={breed.id}>
{breed.name}
<SelectTrigger
id="breed"
className="w-full"
disabled={!selectedSpeciesId}
>
<SelectValue
placeholder={
selectedSpeciesId
? "Select breed (optional)"
: "Select a species first"
}
/>
</SelectTrigger>
<SelectContent>
{breedList.length === 0 ? (
<SelectItem value="__empty__" disabled>
No breeds found for this species.
</SelectItem>
))
)}
</SelectContent>
</Select>
)}
/>
) : (
breedList.map((breed) => (
<SelectItem key={breed.id} value={breed.id}>
{breed.name}
</SelectItem>
))
)}
</SelectContent>
</Select>
)}
/>
)}
{errors.breedId && (
<p className="text-xs text-destructive">{errors.breedId.message}</p>
)}