@digilogiclabs/saas-factory-ui 2.7.0 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +79 -8
- package/dist/index.d.ts +79 -8
- package/dist/index.js +145 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +145 -66
- package/dist/index.mjs.map +1 -1
- package/dist/web/index.d.mts +79 -8
- package/dist/web/index.d.ts +79 -8
- package/dist/web/index.js +145 -66
- package/dist/web/index.js.map +1 -1
- package/dist/web/index.mjs +145 -66
- package/dist/web/index.mjs.map +1 -1
- package/package.json +17 -17
package/dist/web/index.js
CHANGED
|
@@ -30539,6 +30539,7 @@ function DiceRoller({
|
|
|
30539
30539
|
iconEmoji = "\u{1F3B2}",
|
|
30540
30540
|
showHistory = false,
|
|
30541
30541
|
historyMax = 8,
|
|
30542
|
+
initialHistory,
|
|
30542
30543
|
rollRef,
|
|
30543
30544
|
arenaHeight: arenaHeightProp,
|
|
30544
30545
|
hideResults = false,
|
|
@@ -30550,7 +30551,9 @@ function DiceRoller({
|
|
|
30550
30551
|
const dark = useDarkMode(darkMode);
|
|
30551
30552
|
const [rolling, setRolling] = (0, import_react69.useState)(false);
|
|
30552
30553
|
const [results, setResults] = (0, import_react69.useState)(null);
|
|
30553
|
-
const [history, setHistory] = (0, import_react69.useState)(
|
|
30554
|
+
const [history, setHistory] = (0, import_react69.useState)(
|
|
30555
|
+
() => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax) : []
|
|
30556
|
+
);
|
|
30554
30557
|
const dieWrapperRefs = (0, import_react69.useRef)([]);
|
|
30555
30558
|
const cubeRefs = (0, import_react69.useRef)([]);
|
|
30556
30559
|
const shadowRefs = (0, import_react69.useRef)([]);
|
|
@@ -30724,7 +30727,10 @@ function DiceRoller({
|
|
|
30724
30727
|
defaultPositions,
|
|
30725
30728
|
half
|
|
30726
30729
|
]);
|
|
30730
|
+
const prevSidesRef = (0, import_react69.useRef)(sides);
|
|
30727
30731
|
(0, import_react69.useEffect)(() => {
|
|
30732
|
+
if (prevSidesRef.current === sides) return;
|
|
30733
|
+
prevSidesRef.current = sides;
|
|
30728
30734
|
setHistory([]);
|
|
30729
30735
|
}, [sides]);
|
|
30730
30736
|
const roll = (0, import_react69.useCallback)(() => {
|
|
@@ -31780,32 +31786,26 @@ function BracketGenerator({
|
|
|
31780
31786
|
const autoPlay = (0, import_react70.useCallback)(() => {
|
|
31781
31787
|
if (simulating) {
|
|
31782
31788
|
if (autoRef.current) clearTimeout(autoRef.current);
|
|
31789
|
+
autoRef.current = null;
|
|
31783
31790
|
setSimulating(false);
|
|
31784
31791
|
return;
|
|
31785
31792
|
}
|
|
31786
31793
|
setSimulating(true);
|
|
31787
|
-
|
|
31788
|
-
|
|
31789
|
-
|
|
31790
|
-
|
|
31791
|
-
|
|
31792
|
-
|
|
31793
|
-
|
|
31794
|
-
|
|
31795
|
-
|
|
31796
|
-
|
|
31797
|
-
|
|
31798
|
-
|
|
31799
|
-
|
|
31800
|
-
const finalMatch = matches.find((m) => m.round === prev.rounds - 1);
|
|
31801
|
-
const champion = finalMatch?.winner || null;
|
|
31802
|
-
if (!champion) autoRef.current = setTimeout(tick, simulateDelayMs);
|
|
31803
|
-
else setSimulating(false);
|
|
31804
|
-
return { ...prev, matches, champion };
|
|
31805
|
-
});
|
|
31794
|
+
simulateNext();
|
|
31795
|
+
}, [simulating, simulateNext]);
|
|
31796
|
+
(0, import_react70.useEffect)(() => {
|
|
31797
|
+
if (!simulating) return;
|
|
31798
|
+
const hasNext = bracketState.matches.some((m) => m.a && m.b && !m.winner);
|
|
31799
|
+
if (bracketState.champion || !hasNext) {
|
|
31800
|
+
setSimulating(false);
|
|
31801
|
+
return;
|
|
31802
|
+
}
|
|
31803
|
+
autoRef.current = setTimeout(simulateNext, simulateDelayMs);
|
|
31804
|
+
return () => {
|
|
31805
|
+
if (autoRef.current) clearTimeout(autoRef.current);
|
|
31806
|
+
autoRef.current = null;
|
|
31806
31807
|
};
|
|
31807
|
-
|
|
31808
|
-
}, [simulating, simulateDelayMs]);
|
|
31808
|
+
}, [simulating, bracketState, simulateDelayMs, simulateNext]);
|
|
31809
31809
|
const advanceWinner = (0, import_react70.useCallback)(
|
|
31810
31810
|
(matchId, winnerSlot) => {
|
|
31811
31811
|
setBracketState((prev) => {
|
|
@@ -32793,6 +32793,8 @@ function CoinFlipper({
|
|
|
32793
32793
|
tailsLabel = "Tails",
|
|
32794
32794
|
showHistory = false,
|
|
32795
32795
|
historyMax = 20,
|
|
32796
|
+
initialHistory,
|
|
32797
|
+
initialStats,
|
|
32796
32798
|
flipRef,
|
|
32797
32799
|
ariaLabel,
|
|
32798
32800
|
className = ""
|
|
@@ -32801,8 +32803,23 @@ function CoinFlipper({
|
|
|
32801
32803
|
const tc = typeof theme5 === "string" ? PRESETS3[theme5] || PRESETS3.gold : theme5;
|
|
32802
32804
|
const [result, setResult] = (0, import_react71.useState)(null);
|
|
32803
32805
|
const [flipping, setFlipping] = (0, import_react71.useState)(false);
|
|
32804
|
-
const [history, setHistory] = (0, import_react71.useState)(
|
|
32805
|
-
|
|
32806
|
+
const [history, setHistory] = (0, import_react71.useState)(
|
|
32807
|
+
() => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax).map((result2, i) => ({ result: result2, id: -(i + 1) })) : []
|
|
32808
|
+
);
|
|
32809
|
+
const [stats, setStats] = (0, import_react71.useState)(() => {
|
|
32810
|
+
if (initialStats) {
|
|
32811
|
+
return {
|
|
32812
|
+
heads: Math.max(0, Math.floor(initialStats.heads)),
|
|
32813
|
+
tails: Math.max(0, Math.floor(initialStats.tails))
|
|
32814
|
+
};
|
|
32815
|
+
}
|
|
32816
|
+
if (initialHistory && initialHistory.length > 0) {
|
|
32817
|
+
const seeded = initialHistory.slice(0, historyMax);
|
|
32818
|
+
const heads = seeded.filter((r) => r === "heads").length;
|
|
32819
|
+
return { heads, tails: seeded.length - heads };
|
|
32820
|
+
}
|
|
32821
|
+
return { heads: 0, tails: 0 };
|
|
32822
|
+
});
|
|
32806
32823
|
const flipIdRef = (0, import_react71.useRef)(0);
|
|
32807
32824
|
const coinRef = (0, import_react71.useRef)(null);
|
|
32808
32825
|
const shadowRef = (0, import_react71.useRef)(null);
|
|
@@ -33731,6 +33748,23 @@ function ReelStage({
|
|
|
33731
33748
|
}
|
|
33732
33749
|
);
|
|
33733
33750
|
}
|
|
33751
|
+
function computeDraftSeed(participants, drawnIds, removeWinners) {
|
|
33752
|
+
if (!removeWinners || !drawnIds || drawnIds.length === 0) return null;
|
|
33753
|
+
if (new Set(drawnIds).size !== drawnIds.length) return null;
|
|
33754
|
+
const byId = new Map(participants.map((p) => [p.id, p]));
|
|
33755
|
+
const drawn = [];
|
|
33756
|
+
for (const id of drawnIds) {
|
|
33757
|
+
const p = byId.get(id);
|
|
33758
|
+
if (!p) return null;
|
|
33759
|
+
drawn.push(p);
|
|
33760
|
+
}
|
|
33761
|
+
const drawnSet = new Set(drawnIds);
|
|
33762
|
+
return {
|
|
33763
|
+
pool: participants.filter((p) => !drawnSet.has(p.id)),
|
|
33764
|
+
// Same cap as the live history (see the pop/promote paths).
|
|
33765
|
+
history: drawn.slice(0, 20)
|
|
33766
|
+
};
|
|
33767
|
+
}
|
|
33734
33768
|
function RandomPlayerPicker({
|
|
33735
33769
|
participants,
|
|
33736
33770
|
mode = "wheel",
|
|
@@ -33745,6 +33779,7 @@ function RandomPlayerPicker({
|
|
|
33745
33779
|
trigger = "button",
|
|
33746
33780
|
label = "Spin",
|
|
33747
33781
|
removeWinners = false,
|
|
33782
|
+
initialDrawnIds,
|
|
33748
33783
|
spinDuration = 5e3,
|
|
33749
33784
|
minRevolutions = 4,
|
|
33750
33785
|
maxRevolutions = 7,
|
|
@@ -33771,12 +33806,21 @@ function RandomPlayerPicker({
|
|
|
33771
33806
|
const reducedMotion = usePrefersReducedMotion();
|
|
33772
33807
|
const intensityCfg = INTENSITY_CONFIG[intensity];
|
|
33773
33808
|
const physicsDriven = intensity === "dramatic" && !reducedMotion;
|
|
33774
|
-
const [
|
|
33809
|
+
const [draftSeed] = (0, import_react73.useState)(
|
|
33810
|
+
() => computeDraftSeed(participants, initialDrawnIds, removeWinners)
|
|
33811
|
+
);
|
|
33812
|
+
const [pool, setPool] = (0, import_react73.useState)(
|
|
33813
|
+
draftSeed ? draftSeed.pool : participants
|
|
33814
|
+
);
|
|
33775
33815
|
const [rotation, setRotation] = (0, import_react73.useState)(0);
|
|
33776
33816
|
const [reelY, setReelY] = (0, import_react73.useState)(0);
|
|
33777
33817
|
const [spinning, setSpinning] = (0, import_react73.useState)(false);
|
|
33778
|
-
const [winner, setWinner] = (0, import_react73.useState)(
|
|
33779
|
-
|
|
33818
|
+
const [winner, setWinner] = (0, import_react73.useState)(
|
|
33819
|
+
draftSeed ? draftSeed.history[0] ?? null : null
|
|
33820
|
+
);
|
|
33821
|
+
const [history, setHistory] = (0, import_react73.useState)(
|
|
33822
|
+
draftSeed ? draftSeed.history : []
|
|
33823
|
+
);
|
|
33780
33824
|
const [revealKey, setRevealKey] = (0, import_react73.useState)(0);
|
|
33781
33825
|
const [particles, setParticles] = (0, import_react73.useState)([]);
|
|
33782
33826
|
const winnerTimer = (0, import_react73.useRef)(null);
|
|
@@ -33788,7 +33832,9 @@ function RandomPlayerPicker({
|
|
|
33788
33832
|
const tickAudioRef = (0, import_react73.useRef)(null);
|
|
33789
33833
|
const winAudioRef = (0, import_react73.useRef)(null);
|
|
33790
33834
|
const containerRef = (0, import_react73.useRef)(null);
|
|
33791
|
-
const prevIdsRef = (0, import_react73.useRef)(
|
|
33835
|
+
const prevIdsRef = (0, import_react73.useRef)(
|
|
33836
|
+
draftSeed ? participants.map((p) => p.id).join("|") : ""
|
|
33837
|
+
);
|
|
33792
33838
|
const wheelSvgRef = (0, import_react73.useRef)(null);
|
|
33793
33839
|
const reelTapeRef = (0, import_react73.useRef)(null);
|
|
33794
33840
|
const rafRef = (0, import_react73.useRef)(null);
|
|
@@ -39362,8 +39408,8 @@ function RosterImport({
|
|
|
39362
39408
|
maxNames,
|
|
39363
39409
|
maxFileBytes,
|
|
39364
39410
|
onClose: () => setOpen(false),
|
|
39365
|
-
onImport: (names) => {
|
|
39366
|
-
onImport(names);
|
|
39411
|
+
onImport: (names, info) => {
|
|
39412
|
+
onImport(names, info);
|
|
39367
39413
|
setOpen(false);
|
|
39368
39414
|
}
|
|
39369
39415
|
}
|
|
@@ -39429,6 +39475,11 @@ function RosterImportModal({
|
|
|
39429
39475
|
}),
|
|
39430
39476
|
[table, column, skipHeader, maxNames]
|
|
39431
39477
|
);
|
|
39478
|
+
const extractedTotal = (0, import_react77.useMemo)(
|
|
39479
|
+
() => extractRoster(table, { column, skipHeader }),
|
|
39480
|
+
[table, column, skipHeader]
|
|
39481
|
+
);
|
|
39482
|
+
const trimmedCount = Math.max(0, extractedTotal.length - extracted.length);
|
|
39432
39483
|
const handleFile = (0, import_react77.useCallback)(
|
|
39433
39484
|
async (e) => {
|
|
39434
39485
|
setFileError(null);
|
|
@@ -39806,7 +39857,10 @@ function RosterImportModal({
|
|
|
39806
39857
|
"button",
|
|
39807
39858
|
{
|
|
39808
39859
|
type: "button",
|
|
39809
|
-
onClick: () => onImport(extracted
|
|
39860
|
+
onClick: () => onImport(extracted, {
|
|
39861
|
+
trimmedCount,
|
|
39862
|
+
totalCount: extractedTotal.length
|
|
39863
|
+
}),
|
|
39810
39864
|
disabled: !canImport,
|
|
39811
39865
|
style: primaryBtn(!canImport),
|
|
39812
39866
|
children: confirmLabel
|
|
@@ -40010,6 +40064,19 @@ function IconUsers({ size = 40 }) {
|
|
|
40010
40064
|
}
|
|
40011
40065
|
);
|
|
40012
40066
|
}
|
|
40067
|
+
function mergeNames(prev, incoming, max) {
|
|
40068
|
+
const seen = new Set(prev.map((n) => n.toLowerCase()));
|
|
40069
|
+
const room = Math.max(0, max - prev.length);
|
|
40070
|
+
const deduped = [];
|
|
40071
|
+
for (const n of incoming) {
|
|
40072
|
+
const key = n.toLowerCase();
|
|
40073
|
+
if (seen.has(key)) continue;
|
|
40074
|
+
seen.add(key);
|
|
40075
|
+
deduped.push(n);
|
|
40076
|
+
if (deduped.length >= room) break;
|
|
40077
|
+
}
|
|
40078
|
+
return deduped.length > 0 ? [...prev, ...deduped] : prev;
|
|
40079
|
+
}
|
|
40013
40080
|
function splitIntoTeams(names, count2) {
|
|
40014
40081
|
const shuffled = shuffle(names);
|
|
40015
40082
|
const teams = Array.from({ length: count2 }, () => []);
|
|
@@ -40083,29 +40150,14 @@ function TeamGenerator({
|
|
|
40083
40150
|
const trimmed = input.trim();
|
|
40084
40151
|
if (!trimmed) return;
|
|
40085
40152
|
const newNames = trimmed.split(/[,\n]+/).map((n) => n.trim()).filter((n) => n.length > 0);
|
|
40086
|
-
setNames((prev) =>
|
|
40087
|
-
const room = Math.max(0, maxPlayers - prev.length);
|
|
40088
|
-
return [...prev, ...newNames.slice(0, room)];
|
|
40089
|
-
});
|
|
40153
|
+
setNames((prev) => mergeNames(prev, newNames, maxPlayers));
|
|
40090
40154
|
setInput("");
|
|
40091
40155
|
inputRef.current?.focus();
|
|
40092
40156
|
}, [input, maxPlayers]);
|
|
40093
40157
|
const importNames = (0, import_react78.useCallback)(
|
|
40094
40158
|
(incoming) => {
|
|
40095
40159
|
if (incoming.length === 0) return;
|
|
40096
|
-
setNames((prev) =>
|
|
40097
|
-
const seen = new Set(prev.map((n) => n.toLowerCase()));
|
|
40098
|
-
const room = Math.max(0, maxPlayers - prev.length);
|
|
40099
|
-
const deduped = [];
|
|
40100
|
-
for (const n of incoming) {
|
|
40101
|
-
const key = n.toLowerCase();
|
|
40102
|
-
if (seen.has(key)) continue;
|
|
40103
|
-
seen.add(key);
|
|
40104
|
-
deduped.push(n);
|
|
40105
|
-
if (deduped.length >= room) break;
|
|
40106
|
-
}
|
|
40107
|
-
return deduped.length > 0 ? [...prev, ...deduped] : prev;
|
|
40108
|
-
});
|
|
40160
|
+
setNames((prev) => mergeNames(prev, incoming, maxPlayers));
|
|
40109
40161
|
},
|
|
40110
40162
|
[maxPlayers]
|
|
40111
40163
|
);
|
|
@@ -40706,6 +40758,7 @@ function RoundRobinScheduler({
|
|
|
40706
40758
|
resumeRounds,
|
|
40707
40759
|
onTeamsChange,
|
|
40708
40760
|
onGenerate,
|
|
40761
|
+
onBeforeScheduleDiscard,
|
|
40709
40762
|
labels,
|
|
40710
40763
|
ariaLabel = "Round robin scheduler",
|
|
40711
40764
|
className,
|
|
@@ -40724,7 +40777,7 @@ function RoundRobinScheduler({
|
|
|
40724
40777
|
(0, import_react79.useEffect)(() => {
|
|
40725
40778
|
onTeamsChange?.(teams);
|
|
40726
40779
|
}, [teams, onTeamsChange]);
|
|
40727
|
-
const
|
|
40780
|
+
const mergeNames2 = (0, import_react79.useCallback)(
|
|
40728
40781
|
(prev, incoming) => {
|
|
40729
40782
|
const existing = new Set(prev.map((t) => t.toLowerCase()));
|
|
40730
40783
|
const next = [...prev];
|
|
@@ -40741,23 +40794,29 @@ function RoundRobinScheduler({
|
|
|
40741
40794
|
},
|
|
40742
40795
|
[maxTeams, nameMaxLength]
|
|
40743
40796
|
);
|
|
40797
|
+
const gateDiscard = (0, import_react79.useCallback)(
|
|
40798
|
+
(action) => rounds.length === 0 || !onBeforeScheduleDiscard || onBeforeScheduleDiscard(action),
|
|
40799
|
+
[rounds.length, onBeforeScheduleDiscard]
|
|
40800
|
+
);
|
|
40744
40801
|
const addTeams = (0, import_react79.useCallback)(
|
|
40745
40802
|
(raw) => {
|
|
40746
40803
|
const names = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
40747
40804
|
if (names.length === 0) return;
|
|
40748
|
-
|
|
40805
|
+
if (!gateDiscard("add")) return;
|
|
40806
|
+
setTeams((prev) => mergeNames2(prev, names));
|
|
40749
40807
|
setInput("");
|
|
40750
40808
|
setRounds([]);
|
|
40751
40809
|
},
|
|
40752
|
-
[
|
|
40810
|
+
[mergeNames2, gateDiscard]
|
|
40753
40811
|
);
|
|
40754
40812
|
const importTeams = (0, import_react79.useCallback)(
|
|
40755
40813
|
(incoming) => {
|
|
40756
40814
|
if (incoming.length === 0) return;
|
|
40757
|
-
|
|
40815
|
+
if (!gateDiscard("import")) return;
|
|
40816
|
+
setTeams((prev) => mergeNames2(prev, incoming));
|
|
40758
40817
|
setRounds([]);
|
|
40759
40818
|
},
|
|
40760
|
-
[
|
|
40819
|
+
[mergeNames2, gateDiscard]
|
|
40761
40820
|
);
|
|
40762
40821
|
const handleKeyDown = (0, import_react79.useCallback)(
|
|
40763
40822
|
(e) => {
|
|
@@ -40768,10 +40827,14 @@ function RoundRobinScheduler({
|
|
|
40768
40827
|
},
|
|
40769
40828
|
[addTeams, input]
|
|
40770
40829
|
);
|
|
40771
|
-
const removeTeam = (0, import_react79.useCallback)(
|
|
40772
|
-
|
|
40773
|
-
|
|
40774
|
-
|
|
40830
|
+
const removeTeam = (0, import_react79.useCallback)(
|
|
40831
|
+
(idx) => {
|
|
40832
|
+
if (!gateDiscard("remove")) return;
|
|
40833
|
+
setTeams((prev) => prev.filter((_, i) => i !== idx));
|
|
40834
|
+
setRounds([]);
|
|
40835
|
+
},
|
|
40836
|
+
[gateDiscard]
|
|
40837
|
+
);
|
|
40775
40838
|
const handleGenerate = (0, import_react79.useCallback)(() => {
|
|
40776
40839
|
if (teams.length < minTeams) return;
|
|
40777
40840
|
const result = generateSchedule(teams, L.roundLabel);
|
|
@@ -40779,15 +40842,17 @@ function RoundRobinScheduler({
|
|
|
40779
40842
|
onGenerate?.(result);
|
|
40780
40843
|
}, [teams, minTeams, L.roundLabel, onGenerate]);
|
|
40781
40844
|
const handleShuffle = (0, import_react79.useCallback)(() => {
|
|
40845
|
+
if (!gateDiscard("shuffle")) return;
|
|
40782
40846
|
setTeams((prev) => shuffle(prev));
|
|
40783
40847
|
setRounds([]);
|
|
40784
|
-
}, []);
|
|
40848
|
+
}, [gateDiscard]);
|
|
40785
40849
|
const handleClear = (0, import_react79.useCallback)(() => {
|
|
40850
|
+
if (!gateDiscard("clear")) return;
|
|
40786
40851
|
setTeams([]);
|
|
40787
40852
|
setRounds([]);
|
|
40788
40853
|
setInput("");
|
|
40789
40854
|
inputRef.current?.focus();
|
|
40790
|
-
}, []);
|
|
40855
|
+
}, [gateDiscard]);
|
|
40791
40856
|
const canGenerate = teams.length >= minTeams;
|
|
40792
40857
|
const rootStyle = {
|
|
40793
40858
|
borderRadius: 16,
|
|
@@ -41248,7 +41313,11 @@ function Scoreboard({
|
|
|
41248
41313
|
onRoundAdvance,
|
|
41249
41314
|
onNewGame,
|
|
41250
41315
|
onReset,
|
|
41316
|
+
onBeforeReset,
|
|
41317
|
+
onBeforeNewGame,
|
|
41251
41318
|
nameMaxLength,
|
|
41319
|
+
scoreMin = -9999,
|
|
41320
|
+
scoreMax = 9999,
|
|
41252
41321
|
labels,
|
|
41253
41322
|
ariaLabel = "Scoreboard",
|
|
41254
41323
|
className
|
|
@@ -41292,11 +41361,19 @@ function Scoreboard({
|
|
|
41292
41361
|
(0, import_react80.useEffect)(() => {
|
|
41293
41362
|
onTeamsChange?.(teams);
|
|
41294
41363
|
}, [teams, onTeamsChange]);
|
|
41295
|
-
const updateScore = (0, import_react80.useCallback)(
|
|
41296
|
-
|
|
41297
|
-
(
|
|
41298
|
-
|
|
41299
|
-
|
|
41364
|
+
const updateScore = (0, import_react80.useCallback)(
|
|
41365
|
+
(index, delta) => {
|
|
41366
|
+
setTeams(
|
|
41367
|
+
(prev) => prev.map(
|
|
41368
|
+
(t, i) => i === index ? {
|
|
41369
|
+
...t,
|
|
41370
|
+
score: Math.min(scoreMax, Math.max(scoreMin, t.score + delta))
|
|
41371
|
+
} : t
|
|
41372
|
+
)
|
|
41373
|
+
);
|
|
41374
|
+
},
|
|
41375
|
+
[scoreMin, scoreMax]
|
|
41376
|
+
);
|
|
41300
41377
|
const updateName = (0, import_react80.useCallback)((index, name) => {
|
|
41301
41378
|
setTeams((prev) => prev.map((t, i) => i === index ? { ...t, name } : t));
|
|
41302
41379
|
}, []);
|
|
@@ -41319,19 +41396,21 @@ function Scoreboard({
|
|
|
41319
41396
|
[minTeams]
|
|
41320
41397
|
);
|
|
41321
41398
|
const resetScores = (0, import_react80.useCallback)(() => {
|
|
41399
|
+
if (onBeforeReset && !onBeforeReset()) return;
|
|
41322
41400
|
setTeams((prev) => prev.map((t) => ({ ...t, score: 0 })));
|
|
41323
41401
|
setRound(1);
|
|
41324
41402
|
setHistory([]);
|
|
41325
41403
|
setHistoryOpen(false);
|
|
41326
41404
|
onReset?.();
|
|
41327
|
-
}, [onReset]);
|
|
41405
|
+
}, [onReset, onBeforeReset]);
|
|
41328
41406
|
const newGame = (0, import_react80.useCallback)(() => {
|
|
41407
|
+
if (onBeforeNewGame && !onBeforeNewGame()) return;
|
|
41329
41408
|
setTeams(createDefaultTeams(seedCount, L.teamNamePrefix));
|
|
41330
41409
|
setRound(1);
|
|
41331
41410
|
setHistory([]);
|
|
41332
41411
|
setHistoryOpen(false);
|
|
41333
41412
|
onNewGame?.();
|
|
41334
|
-
}, [seedCount, L.teamNamePrefix, onNewGame]);
|
|
41413
|
+
}, [seedCount, L.teamNamePrefix, onNewGame, onBeforeNewGame]);
|
|
41335
41414
|
const nextRound = (0, import_react80.useCallback)(() => {
|
|
41336
41415
|
const snapshot = {
|
|
41337
41416
|
round,
|