-
{eg.label}
+
{eg.label}{eg.items[0]?.eventHall ? ` · ${eg.items[0].eventHall}` : ""}
{eg.items.length} чел.
{egStats.coming > 0 && {egStats.coming} придёт}
@@ -785,12 +787,25 @@ function BookingsPageInner() {
const [addOpen, setAddOpen] = useState(false);
const [searchResults, setSearchResults] = useState(null);
const [statusFilter, setStatusFilter] = useState("all");
+ const [hallFilter, setHallFilter] = useState("all");
+ const [halls, setHalls] = useState([]);
const [refreshKey, setRefreshKey] = useState(0);
const [dashboardKey, setDashboardKey] = useState(0);
const refreshDashboard = useCallback(() => setDashboardKey((k) => k + 1), []);
const lastTotalRef = useRef(null);
const { showError } = useToast();
+ // Fetch available halls from schedule
+ useEffect(() => {
+ adminFetch("/api/admin/sections/schedule")
+ .then((r) => r.json())
+ .then((data: { locations?: { name: string }[] }) => {
+ const names = data.locations?.map((l) => l.name).filter(Boolean) ?? [];
+ setHalls([...new Set(names)]);
+ })
+ .catch(() => {});
+ }, []);
+
// Poll for new bookings, auto-refresh silently
useEffect(() => {
const id = setInterval(() => {
@@ -863,6 +878,31 @@ function BookingsPageInner() {
/>
+ {/* Hall filter */}
+ {halls.length > 1 && (
+
+
+ {halls.map((hall) => (
+
+ ))}
+
+ )}
+
{searchResults ? (
/* #5: Actionable search results — filtered by status */
(() => {
@@ -925,7 +965,7 @@ function BookingsPageInner() {
{tab === "reminders" &&
}
{tab === "classes" &&
}
{tab === "master-classes" &&
}
- {tab === "open-day" &&
}
+ {tab === "open-day" &&
}
>
)}
diff --git a/src/app/admin/bookings/types.ts b/src/app/admin/bookings/types.ts
index 85ef10d..a2b4692 100644
--- a/src/app/admin/bookings/types.ts
+++ b/src/app/admin/bookings/types.ts
@@ -36,7 +36,7 @@ export function countStatuses(items: { status: string }[]): Record