fix: backfill memberships, handle booking create errors

- Migration 00012: populate tenant_memberships from tenant_users join
  users, not only the seeded demo owner (Codex P1)
- bookings-page: check response.error so 4xx failures do not close the
  modal silently; refetch dashboard summary after create (Codex P2)

Authored By: TDvorak <[email protected]>

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-17 20:33:53 +02:00
1 parent f2f7439050
commit 50c8440a06
3 files changed
+12 -7

No files matched your search

@@ -72,15 +72,17 @@ function BookingsPage() {
}
setCreatingBooking(true);
try {
await (apiClient as any).POST("/v1/catalog/bookings", {
const response = await (apiClient as any).POST("/v1/catalog/bookings", {
headers: { Authorization: `Bearer ${bearer}` },
body: {
customerName: newBookingCustomer(), customerEmail: newBookingEmail(), service: newBookingService(),
startsAt: new Date(`${newBookingDate()}T${newBookingTime()}`).toISOString(), notes: newBookingNotes()
}
});
if (response.error) throw new Error(typeof response.error === "string" ? response.error : "booking create failed");
setNewBookingCustomer(""); setNewBookingEmail(""); setNewBookingService(""); setNewBookingDate(""); setNewBookingTime(""); setNewBookingNotes("");
setShowNewBooking(false);
void data.refetchSummary();
} catch { data.setDemoNotice(data.i18n.locale() === "cs" ? "Vytvoření rezervace selhalo." : "Failed to create booking."); }
finally { setCreatingBooking(false); }
};
@@ -94,6 +94,7 @@ export interface DashboardData {
token: () => string | null | undefined;
isDemoMode: () => boolean;
resolvedSummary: () => any;
refetchSummary: () => void;
resolvedBootstrap: () => any;
resolvedBilling: () => any;
normalizedKpis: () => any[];
@@ -150,7 +151,7 @@ export function DashboardDataProvider(props: { children: any }) {
const isDemoMode = () => token()?.startsWith("demo.") ?? false;
const demoData = createMemo(() => createDemoData(i18n));
const [summary] = createResource(token, async (bearer) => {
const [summary, { refetch: refetchSummary }] = createResource(token, async (bearer) => {
if (!bearer) return null;
if (bearer.startsWith("demo.")) return demoData().summary;
const response = await apiClient.GET("/v1/dashboard/summary", { headers: { Authorization: `Bearer ${bearer}` } });
@@ -286,6 +287,7 @@ export function DashboardDataProvider(props: { children: any }) {
token: () => token(),
isDemoMode,
resolvedSummary,
refetchSummary,
resolvedBootstrap,
resolvedBilling,
normalizedKpis,