From 1f766846b07e987e3951c45daf8df21e7f9441ae Mon Sep 17 00:00:00 2001 From: Anthony Correa Date: Tue, 6 Jan 2026 20:40:52 -0600 Subject: [PATCH] Add playoff round support to cost estimator - Introduced `PlayoffRound` model with cost inputs for games, umpires, balls, and fields. - Added UI to manage multiple playoff rounds, each with configurable fields. - Extended cost computations to include playoff-specific totals for umpires, balls, and fields. - Updated import/export logic to handle a new save file version (v2) including playoff data. - Implemented `localStorage` auto-save/load for persistence across sessions. --- src/App.tsx | 566 +++++++++++++++++++++++++++------------------------- 1 file changed, 295 insertions(+), 271 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 1152225..a678edb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef, useState } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; // --- Helpers --------------------------------------------------------------- const currency = (n: number) => @@ -10,7 +10,6 @@ const currency = (n: number) => const clamp = (v: number, min: number, max: number) => Math.min(max, Math.max(min, v)); -// Map 1..5 to human-friendly week labels const weekLabel = (w: number) => ({ 1: "1st", 2: "2nd", 3: "3rd", 4: "4th", 5: "5th" } as Record)[w] ?? `${w}th`; @@ -29,21 +28,19 @@ const months = [ "December", ]; -// Approximate how many weeks between (month, week) pairs (inclusive) function approxWeeksBetween( startMonthIdx: number, startWeek: number, endMonthIdx: number, endWeek: number ) { - const weeksPerMonth = 4.34524; // avg weeks per month + const weeksPerMonth = 4.34524; const start = startMonthIdx + (startWeek - 1) / 5; const end = endMonthIdx + (endWeek - 1) / 5; const monthsBetween = Math.max(0, end - start); return Math.max(0, Math.round(monthsBetween * weeksPerMonth + 1)); } -// File download helper function downloadText(filename: string, text: string) { const blob = new Blob([text], { type: "application/json" }); const url = URL.createObjectURL(blob); @@ -54,7 +51,6 @@ function downloadText(filename: string, text: string) { URL.revokeObjectURL(url); } -// Generic labeled number+slider input pair function NumberSlider({ label, value, @@ -78,7 +74,7 @@ function NumberSlider({ return (
-
); }