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.
This commit is contained in:
iris 2026-07-29 20:36:36 +02:00
commit fb02cc0f94

View file

@ -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<T = any>(res: Response): Promise<T> {
@ -15,8 +16,13 @@ async function errText(res: Response): Promise<string> {
}
}
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 }