- {groups.map((group, idx) => {
- const sorted = [...group.numbers].sort((a, b) => a - b)
- const color = COLORS[group.colorIndex]
- return (
-
- {/* Group label with color */}
-
-
-
-
- G{String(idx + 1).padStart(2, "0")}
-
+
+ {rows.map((row, rowIdx) => (
+
+ {row.map((group, idx) => {
+ const sorted = [...group.numbers].sort((a, b) => a - b)
+ const color = COLORS[group.colorIndex]
+ const globalIdx = groups.indexOf(group)
+ return (
+
+ {/* Group label with color */}
+
+
+
+ G{String(globalIdx + 1).padStart(2, "0")}
+
+
+ {String(group.numbers.length).padStart(2, "0")} P
+
+
+ {/* Numbers with color */}
+
+ {sorted.map((num) => (
+
+ {String(num).padStart(2, "0")}
+
+ ))}
+
-
- {String(group.numbers.length).padStart(2, "0")} P
-
-
- {/* Numbers with color */}
-
- {sorted.map((num) => (
-
- {String(num).padStart(2, "0")}
-
- ))}
-
-
- )
- })}
+ )
+ })}
+
+ ))}
)
}
diff --git a/components/settings.tsx b/components/settings.tsx
index 4e14d4a..df979dd 100644
--- a/components/settings.tsx
+++ b/components/settings.tsx
@@ -5,16 +5,16 @@ import type { Mode } from "@/components/logic"
interface SettingsPanelProps {
mode: Mode
- totalTasks: number
- pickCount: number
- rounds: number
+ totalTasks: number | string
+ pickCount: number | string
+ rounds: number | string
allowRepeat: boolean
singleAllowRepeat: boolean
selectedRecords: { number: number; colorIndex: number }[]
onModeChange: (v: Mode) => void
- onTotalTasksChange: (v: number) => void
- onPickCountChange: (v: number) => void
- onRoundsChange: (v: number) => void
+ onTotalTasksChange: (v: number | string) => void
+ onPickCountChange: (v: number | string) => void
+ onRoundsChange: (v: number | string) => void
onAllowRepeatChange: (v: boolean) => void
onSingleAllowRepeatChange: (v: boolean) => void
onRoll: () => void
@@ -29,13 +29,18 @@ function FieldRow({
value,
onChange,
min = 1,
+ error,
}: {
label: string
hint: string
- value: number
- onChange: (v: number) => void
+ value: number | string
+ onChange: (v: number | string) => void
min?: number
+ error?: string
}) {
+ const displayValue = value === "" ? "" : value
+ const hasError = error && value === ""
+
return (
@@ -44,7 +49,13 @@ function FieldRow({
{
- const v = parseInt(e.target.value, 10)
- if (!isNaN(v) && v >= min) onChange(v)
+ const inputValue = e.target.value
+ if (inputValue === "") {
+ onChange("")
+ } else {
+ const v = parseInt(inputValue, 10)
+ if (!isNaN(v)) onChange(v)
+ }
}}
className={cn(
- "w-12 h-7 text-center text-sm font-mono text-[#16191f] bg-[#f7f8fa]",
+ "w-12 h-7 text-center text-sm font-mono bg-[#f7f8fa]",
"border-x border-[#e2e6ea]",
"focus:outline-none focus:bg-[#ffffff]",
- "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none"
+ "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none",
+ hasError && "text-[#d92d20] border-[#d92d20]"
)}
/>