Files
Red-Bull-Tracker/src/types.ts
T
Ned Halksworth 023ec1096f feat: integrate barcode scanning functionality and enhance Appwrite setup
- Added a new `barcode_products` collection to the Appwrite setup for managing barcode data.
- Implemented barcode scanning feature with a dedicated modal for scanning and adding products.
- Introduced new components for barcode product preview and management.
- Updated the setup script to seed verified barcode products from a JSON file.
- Enhanced the application state management to handle barcode-related actions and user interactions.
2026-05-27 14:29:22 +01:00

145 lines
2.8 KiB
TypeScript

export type BuiltInSize = 250 | 355 | 473;
export type RedBullEntry = {
id: string;
userId: string;
cans: number;
flavour: string;
flavourAccent: string;
sizeMl: number;
pricePerCan: number;
dateTime: string;
notes?: string;
store?: string;
sugarFree: boolean;
caffeineMgPerCan?: number;
importKey: string;
source: "manual" | "quick-add" | "excel" | "json";
createdAt?: string;
updatedAt?: string;
};
export type Flavour = {
name: string;
accent: string;
sugarFree?: boolean;
};
export type DateFilter = "all" | "today" | "week" | "month" | "custom";
export type EntryDraft = Omit<
RedBullEntry,
"id" | "userId" | "importKey" | "source" | "createdAt" | "updatedAt"
> & {
source?: RedBullEntry["source"];
};
export type BarcodeFormatName = "ean-13" | "ean-8" | "upc-a" | "upc-e" | "unknown";
export type BarcodeProductDraft = {
flavourName: string;
sizeMl: number;
pricePerCan: number;
sugarFree?: boolean;
caffeineMgPerCan?: number;
};
export type ResolvedBarcodeProduct = BarcodeProductDraft & {
flavourAccent: string;
source: "built-in" | "user";
};
export type BarcodeSeedProduct = BarcodeProductDraft & {
verifiedBy: string;
sourceName?: string;
sourceUrl?: string;
notes?: string;
variant?: string;
};
export type UserBarcodeMapping = BarcodeProductDraft & {
barcode: string;
createdAt: string;
updatedAt: string;
};
export type BarcodeLookupCatalog = {
verifiedProducts?: Record<string, BarcodeSeedProduct>;
userMappings?: UserBarcodeMapping[];
};
export type BarcodeLookupResult =
| {
status: "known" | "user";
barcode: string;
product: ResolvedBarcodeProduct;
}
| {
status: "partial";
barcode: string;
product: BarcodeProductDraft;
reason: string;
}
| {
status: "unknown";
barcode: string;
};
export type Filters = {
flavour: string;
dateRange: DateFilter;
store: string;
from: string;
to: string;
};
export type ImportPreviewRow = {
rowNumber: number;
entry?: EntryDraft;
errors: string[];
duplicate: boolean;
duplicateReason?: string;
};
export type ImportPreview = {
fileName: string;
rows: ImportPreviewRow[];
};
export type ChatRole = "user" | "assistant";
export type CoachMessage = {
id: string;
role: ChatRole;
content: string;
thinking?: string;
pending?: boolean;
stopped?: boolean;
};
export type CoachChat = {
id: string;
userId: string;
title: string;
messages: CoachMessage[];
createdAt: string;
updatedAt: string;
};
export type UserLimits = {
dailyCanLimit?: number;
dailySpendLimit?: number;
stopTime?: string;
};
export type LimitViolation = "cans" | "spend" | "stopTime";
export type LimitCheckResult = {
violations: LimitViolation[];
projectedCans: number;
projectedSpend: number;
todayCans: number;
todaySpend: number;
pastStopTime: boolean;
};