Initial commit

Create the Board Score PWA with offline support, Kurzgesagt-style themes, multiple game configs, dynamic players, avatars via DiceBear, and complete statistics.
This commit is contained in:
Zed
2026-07-06 16:12:25 +02:00
commit bf67c58171
62 changed files with 54527 additions and 0 deletions
+89
View File
@@ -0,0 +1,89 @@
export type ScoreType =
"positive" | "negative" | "target" | "fixed_rounds" | "sudden_death";
export interface ScoringCategory {
id: string;
label: string;
}
export interface GameConfig {
id: string;
name: string;
minPlayers: number;
maxPlayers: number;
scoreType: ScoreType;
targetScore?: number; // Used if scoreType is 'target'
targetScoreCondition?: "reaches" | "exceeds";
getTargetScore?: (options: Record<string, any>) => number;
calculatePlayerTotal?: (
rounds: Round[],
playerId: string,
isEndGameCalculation?: boolean,
) => number;
fixedRounds?: number; // Used if scoreType is 'fixed_rounds'
scoringCategories?: ScoringCategory[];
description?: string;
icon?: string;
imagePath?: string; // Optional custom logo image (SVG, PNG, WebP...)
bannerPath?: string; // Optional custom banner/background image
rulesUrl?: string; // URL to a PDF or Markdown file (e.g. "/games-assets/azul-rules.pdf")
colors: {
primary: string;
secondary?: string;
};
options?: GameOption[];
}
export interface GameOption {
id: string;
label: string;
type: "boolean" | "number" | "select";
defaultValue: any;
options?: { label: string; value: string | number }[]; // For select type
}
export interface Player {
id: string;
name: string;
color?: string;
avatar?: string;
}
export interface RoundScore {
playerId: string;
score: number;
details?: Record<string, any>;
caboCall?: "success" | "fail"; // For Cabo game specifically
kamikaze?: boolean; // For Cabo Kamikaze rule
}
export interface Round {
id: string;
roundNumber: number;
scores: RoundScore[];
}
export interface GameSession {
id: string;
gameId: string;
dateStart: number;
dateEnd?: number;
players: Player[];
rounds: Round[];
status: "playing" | "finished";
options: Record<string, any>;
winnerIds?: string[];
}
export interface AppSettings {
id: number;
theme: "light" | "dark" | "system";
language: string;
}
export interface SavedPlayer {
id: string;
name: string;
createdAt: number;
avatar?: string;
}