From f2c8cc1e8066751109818de01cb3162422c6c9df Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 4 Jun 2026 19:50:18 +0200 Subject: [PATCH] =?UTF-8?q?fix(logistics):=20Hotels=20tab=20crash=20?= =?UTF-8?q?=E2=80=94=20Radix=20SelectItem=20cannot=20have=20empty=20value?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'Unassigned' rooming option used value="" which throws at runtime (blank tab behind the error boundary). Use a sentinel value mapped to unassign. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/components/admin/logistics/hotels-tab.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/admin/logistics/hotels-tab.tsx b/src/components/admin/logistics/hotels-tab.tsx index c82ad08..47394c1 100644 --- a/src/components/admin/logistics/hotels-tab.tsx +++ b/src/components/admin/logistics/hotels-tab.tsx @@ -38,6 +38,10 @@ import { } from '@/components/ui/select' import { Download, ExternalLink, Hotel as HotelIcon, Loader2, Plus, Trash2, Pencil } from 'lucide-react' +// Radix forbids an empty-string value, so the "unassigned" option +// uses this sentinel; handleHotelChange maps it back to an unassign. +const UNASSIGN_VALUE = '__unassign__' + interface Props { programId: string } @@ -439,7 +443,7 @@ function AttendeeRoomRow({ const currentHotelId = row.stay?.hotelId ?? '' const handleHotelChange = (value: string) => { - if (!value) { + if (!value || value === UNASSIGN_VALUE) { unassignMutation.mutate({ attendingMemberId: row.attendingMemberId }) } else { assignMutation.mutate({ @@ -506,7 +510,7 @@ function AttendeeRoomRow({ - — Unassigned — + — Unassigned — {hotels.map((h) => ( {h.name}