This commit is contained in:
Tomas Dvorak
2025-10-24 14:52:46 +02:00
parent 70ea0c3c91
commit 8a7c292e54
41 changed files with 912 additions and 404 deletions
+5
View File
@@ -1,10 +1,13 @@
import api from './api';
export type PollStyle = 'auto' | 'rating-stars' | 'rating-scale' | 'choices-list' | 'choices-chips' | 'choices-cards';
export interface Poll {
id: number;
title: string;
description: string;
type: 'single' | 'multiple' | 'rating';
style: PollStyle;
status: 'draft' | 'active' | 'closed' | 'archived';
start_date?: string;
end_date?: string;
@@ -101,6 +104,7 @@ export interface CreatePollRequest {
title: string;
description?: string;
type?: 'single' | 'multiple' | 'rating';
style?: PollStyle;
status?: 'draft' | 'active' | 'closed' | 'archived';
start_date?: string;
end_date?: string;
@@ -129,6 +133,7 @@ export interface UpdatePollRequest {
title?: string;
description?: string;
type?: 'single' | 'multiple' | 'rating';
style?: PollStyle;
status?: 'draft' | 'active' | 'closed' | 'archived';
start_date?: string;
end_date?: string;
+30
View File
@@ -14,12 +14,18 @@ export type ScoreboardState = {
secondaryColor?: string; // away color
homeScore: number;
awayScore: number;
homeFouls?: number;
awayFouls?: number;
halfLength: number; // minutes
theme: ScoreboardTheme;
externalMatchId?: string;
active?: boolean;
timer?: string; // MM:SS
running?: boolean;
sidesFlipped?: boolean;
half?: number;
qrEvery?: number;
qrDuration?: number;
};
const DEFAULT_STATE: ScoreboardState = {
@@ -33,12 +39,18 @@ const DEFAULT_STATE: ScoreboardState = {
secondaryColor: '#2563eb',
homeScore: 0,
awayScore: 0,
homeFouls: 0,
awayFouls: 0,
halfLength: 45,
theme: 'pill',
externalMatchId: '',
active: false,
timer: '00:00',
running: false,
sidesFlipped: false,
half: 1,
qrEvery: 5,
qrDuration: 60,
};
const STORAGE_KEY = 'scoreboard_state_v1';
@@ -121,6 +133,12 @@ export async function pauseTimer(): Promise<void> {
export async function resetTimer(): Promise<void> {
await api.post('/admin/scoreboard/timer/reset');
}
export async function swapSides(): Promise<void> {
await api.post('/admin/scoreboard/swap-sides');
}
export async function startSecondHalf(): Promise<void> {
await api.post('/admin/scoreboard/second-half');
}
// Utilities
export function deriveShort(name?: string): string {
@@ -178,12 +196,18 @@ function normalizeFromApi(d: any): Partial<ScoreboardState> {
secondaryColor: d.secondaryColor || d.secondary_color || d.SecondaryColor || undefined,
homeScore: typeof d.homeScore === 'number' ? d.homeScore : (typeof d.home_score === 'number' ? d.home_score : 0),
awayScore: typeof d.awayScore === 'number' ? d.awayScore : (typeof d.away_score === 'number' ? d.away_score : 0),
homeFouls: typeof d.homeFouls === 'number' ? d.homeFouls : (typeof d.home_fouls === 'number' ? d.home_fouls : 0),
awayFouls: typeof d.awayFouls === 'number' ? d.awayFouls : (typeof d.away_fouls === 'number' ? d.away_fouls : 0),
halfLength: typeof d.halfLength === 'number' ? d.halfLength : (typeof d.half_length === 'number' ? d.half_length : 45),
theme: (d.theme || 'pill') as any,
externalMatchId: d.externalMatchId || d.external_match_id || d.ExternalMatchID || '',
active: typeof d.active === 'boolean' ? d.active : undefined,
timer: d.timer || d.Timer || '00:00',
running: typeof d.running === 'boolean' ? d.running : undefined,
sidesFlipped: typeof d.sidesFlipped === 'boolean' ? d.sidesFlipped : (typeof d.sides_flipped === 'boolean' ? d.sides_flipped : undefined),
half: typeof d.half === 'number' ? d.half : undefined,
qrEvery: typeof d.qrEvery === 'number' ? d.qrEvery : (typeof d.qr_show_every_minutes === 'number' ? d.qr_show_every_minutes : undefined),
qrDuration: typeof d.qrDuration === 'number' ? d.qrDuration : (typeof d.qr_show_duration_seconds === 'number' ? d.qr_show_duration_seconds : undefined),
};
}
@@ -199,10 +223,16 @@ function toApiPayload(p: Partial<ScoreboardState>) {
if (p.secondaryColor !== undefined) out.secondaryColor = p.secondaryColor;
if (p.homeScore !== undefined) out.homeScore = p.homeScore;
if (p.awayScore !== undefined) out.awayScore = p.awayScore;
if (p.homeFouls !== undefined) out.homeFouls = p.homeFouls;
if (p.awayFouls !== undefined) out.awayFouls = p.awayFouls;
if (p.halfLength !== undefined) out.halfLength = p.halfLength;
if (p.theme !== undefined) out.theme = p.theme;
if (p.externalMatchId !== undefined) out.externalMatchId = p.externalMatchId;
if (p.active !== undefined) out.active = p.active;
if (p.timer !== undefined) out.timer = p.timer;
if (p.sidesFlipped !== undefined) out.sidesFlipped = p.sidesFlipped;
if (p.half !== undefined) out.half = p.half;
if (p.qrEvery !== undefined) out.qrEvery = p.qrEvery;
if (p.qrDuration !== undefined) out.qrDuration = p.qrDuration;
return out;
}