From fb02cc0f9485e7342ac5c6606f0e9f8d54274b2a Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 29 Jul 2026 20:36:36 +0200 Subject: [PATCH] admin: reuse @wutzcalc/shared's Drink/Bar types instead of re-declaring them Admin.tsx defined its own local Drink/BarRow-adjacent interfaces rather than importing from @wutzcalc/shared, even though the tablet code in the same package already does (App.tsx, Sale.tsx, BarPicker.tsx). The two had already drifted: the local Drink.archived was typed number while the shared package's was boolean, despite describing the exact same wire field. No runtime bug (JS doesn't enforce it, and the code only does truthiness checks), but a maintainability smell. BarRow now extends the shared Bar type instead of duplicating its fields; Drink is imported directly. Totals/PerDrink/ByDay stay local since they're admin-only stats shapes, not part of the wire contract the tablet also consumes. --- client/src/admin/Admin.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/src/admin/Admin.tsx b/client/src/admin/Admin.tsx index ac74807..a77e6b8 100644 --- a/client/src/admin/Admin.tsx +++ b/client/src/admin/Admin.tsx @@ -1,4 +1,5 @@ import { useEffect, useRef, useState } from 'preact/hooks'; +import type { Bar, Drink } from '@wutzcalc/shared'; import { formatCents } from '../api'; async function j(res: Response): Promise { @@ -15,8 +16,13 @@ async function errText(res: Response): Promise { } } -interface Drink { id: number; name: string; price_cents: number; archived: number } -interface BarRow { id: number; name: string; pfand_cents: number; drink_ids: number[] } +// `Drink`/`Bar` come from @wutzcalc/shared — the tablet code already did +// this, but Admin.tsx used to re-declare its own near-identical copies, +// which had already drifted (its local Drink.archived was typed `number` +// while the shared one was `boolean`, even though both describe the exact +// same wire field). BarRow/stats shapes below are admin-only — not part +// of the wire contract the tablet also consumes — so they stay local. +interface BarRow extends Bar { drink_ids: number[] } interface Totals { bar_id: number; bar_name: string; tx_count: number; paid_cents: number; crew_count: number; pfand_returns: number } interface PerDrink { drink_id: number; drink_name: string; sold_qty: number } interface ByDay { day: string; tx_count: number; paid_cents: number; crew_count: number; pfand_returns: number }