@digilogiclabs/saas-factory-ui 2.6.0 → 2.7.1

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.
@@ -30544,6 +30544,7 @@ function DiceRoller({
30544
30544
  iconEmoji = "\u{1F3B2}",
30545
30545
  showHistory = false,
30546
30546
  historyMax = 8,
30547
+ initialHistory,
30547
30548
  rollRef,
30548
30549
  arenaHeight: arenaHeightProp,
30549
30550
  hideResults = false,
@@ -30555,7 +30556,9 @@ function DiceRoller({
30555
30556
  const dark = useDarkMode(darkMode);
30556
30557
  const [rolling, setRolling] = useState66(false);
30557
30558
  const [results, setResults] = useState66(null);
30558
- const [history, setHistory] = useState66([]);
30559
+ const [history, setHistory] = useState66(
30560
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax) : []
30561
+ );
30559
30562
  const dieWrapperRefs = useRef40([]);
30560
30563
  const cubeRefs = useRef40([]);
30561
30564
  const shadowRefs = useRef40([]);
@@ -30729,7 +30732,10 @@ function DiceRoller({
30729
30732
  defaultPositions,
30730
30733
  half
30731
30734
  ]);
30735
+ const prevSidesRef = useRef40(sides);
30732
30736
  useEffect51(() => {
30737
+ if (prevSidesRef.current === sides) return;
30738
+ prevSidesRef.current = sides;
30733
30739
  setHistory([]);
30734
30740
  }, [sides]);
30735
30741
  const roll = useCallback41(() => {
@@ -32811,6 +32817,8 @@ function CoinFlipper({
32811
32817
  tailsLabel = "Tails",
32812
32818
  showHistory = false,
32813
32819
  historyMax = 20,
32820
+ initialHistory,
32821
+ initialStats,
32814
32822
  flipRef,
32815
32823
  ariaLabel,
32816
32824
  className = ""
@@ -32819,8 +32827,23 @@ function CoinFlipper({
32819
32827
  const tc = typeof theme5 === "string" ? PRESETS3[theme5] || PRESETS3.gold : theme5;
32820
32828
  const [result, setResult] = useState68(null);
32821
32829
  const [flipping, setFlipping] = useState68(false);
32822
- const [history, setHistory] = useState68([]);
32823
- const [stats, setStats] = useState68({ heads: 0, tails: 0 });
32830
+ const [history, setHistory] = useState68(
32831
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax).map((result2, i) => ({ result: result2, id: -(i + 1) })) : []
32832
+ );
32833
+ const [stats, setStats] = useState68(() => {
32834
+ if (initialStats) {
32835
+ return {
32836
+ heads: Math.max(0, Math.floor(initialStats.heads)),
32837
+ tails: Math.max(0, Math.floor(initialStats.tails))
32838
+ };
32839
+ }
32840
+ if (initialHistory && initialHistory.length > 0) {
32841
+ const seeded = initialHistory.slice(0, historyMax);
32842
+ const heads = seeded.filter((r) => r === "heads").length;
32843
+ return { heads, tails: seeded.length - heads };
32844
+ }
32845
+ return { heads: 0, tails: 0 };
32846
+ });
32824
32847
  const flipIdRef = useRef42(0);
32825
32848
  const coinRef = useRef42(null);
32826
32849
  const shadowRef = useRef42(null);
@@ -33755,6 +33778,23 @@ function ReelStage({
33755
33778
  }
33756
33779
  );
33757
33780
  }
33781
+ function computeDraftSeed(participants, drawnIds, removeWinners) {
33782
+ if (!removeWinners || !drawnIds || drawnIds.length === 0) return null;
33783
+ if (new Set(drawnIds).size !== drawnIds.length) return null;
33784
+ const byId = new Map(participants.map((p) => [p.id, p]));
33785
+ const drawn = [];
33786
+ for (const id of drawnIds) {
33787
+ const p = byId.get(id);
33788
+ if (!p) return null;
33789
+ drawn.push(p);
33790
+ }
33791
+ const drawnSet = new Set(drawnIds);
33792
+ return {
33793
+ pool: participants.filter((p) => !drawnSet.has(p.id)),
33794
+ // Same cap as the live history (see the pop/promote paths).
33795
+ history: drawn.slice(0, 20)
33796
+ };
33797
+ }
33758
33798
  function RandomPlayerPicker({
33759
33799
  participants,
33760
33800
  mode = "wheel",
@@ -33769,6 +33809,7 @@ function RandomPlayerPicker({
33769
33809
  trigger = "button",
33770
33810
  label = "Spin",
33771
33811
  removeWinners = false,
33812
+ initialDrawnIds,
33772
33813
  spinDuration = 5e3,
33773
33814
  minRevolutions = 4,
33774
33815
  maxRevolutions = 7,
@@ -33795,12 +33836,21 @@ function RandomPlayerPicker({
33795
33836
  const reducedMotion = usePrefersReducedMotion();
33796
33837
  const intensityCfg = INTENSITY_CONFIG[intensity];
33797
33838
  const physicsDriven = intensity === "dramatic" && !reducedMotion;
33798
- const [pool, setPool] = useState70(participants);
33839
+ const [draftSeed] = useState70(
33840
+ () => computeDraftSeed(participants, initialDrawnIds, removeWinners)
33841
+ );
33842
+ const [pool, setPool] = useState70(
33843
+ draftSeed ? draftSeed.pool : participants
33844
+ );
33799
33845
  const [rotation, setRotation] = useState70(0);
33800
33846
  const [reelY, setReelY] = useState70(0);
33801
33847
  const [spinning, setSpinning] = useState70(false);
33802
- const [winner, setWinner] = useState70(null);
33803
- const [history, setHistory] = useState70([]);
33848
+ const [winner, setWinner] = useState70(
33849
+ draftSeed ? draftSeed.history[0] ?? null : null
33850
+ );
33851
+ const [history, setHistory] = useState70(
33852
+ draftSeed ? draftSeed.history : []
33853
+ );
33804
33854
  const [revealKey, setRevealKey] = useState70(0);
33805
33855
  const [particles, setParticles] = useState70([]);
33806
33856
  const winnerTimer = useRef43(null);
@@ -33812,7 +33862,9 @@ function RandomPlayerPicker({
33812
33862
  const tickAudioRef = useRef43(null);
33813
33863
  const winAudioRef = useRef43(null);
33814
33864
  const containerRef = useRef43(null);
33815
- const prevIdsRef = useRef43("");
33865
+ const prevIdsRef = useRef43(
33866
+ draftSeed ? participants.map((p) => p.id).join("|") : ""
33867
+ );
33816
33868
  const wheelSvgRef = useRef43(null);
33817
33869
  const reelTapeRef = useRef43(null);
33818
33870
  const rafRef = useRef43(null);
@@ -40767,6 +40819,7 @@ function RoundRobinScheduler({
40767
40819
  resumeRounds,
40768
40820
  onTeamsChange,
40769
40821
  onGenerate,
40822
+ onBeforeScheduleDiscard,
40770
40823
  labels,
40771
40824
  ariaLabel = "Round robin scheduler",
40772
40825
  className,
@@ -40802,23 +40855,29 @@ function RoundRobinScheduler({
40802
40855
  },
40803
40856
  [maxTeams, nameMaxLength]
40804
40857
  );
40858
+ const gateDiscard = useCallback51(
40859
+ (action) => rounds.length === 0 || !onBeforeScheduleDiscard || onBeforeScheduleDiscard(action),
40860
+ [rounds.length, onBeforeScheduleDiscard]
40861
+ );
40805
40862
  const addTeams = useCallback51(
40806
40863
  (raw) => {
40807
40864
  const names = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
40808
40865
  if (names.length === 0) return;
40866
+ if (!gateDiscard("add")) return;
40809
40867
  setTeams((prev) => mergeNames(prev, names));
40810
40868
  setInput("");
40811
40869
  setRounds([]);
40812
40870
  },
40813
- [mergeNames]
40871
+ [mergeNames, gateDiscard]
40814
40872
  );
40815
40873
  const importTeams = useCallback51(
40816
40874
  (incoming) => {
40817
40875
  if (incoming.length === 0) return;
40876
+ if (!gateDiscard("import")) return;
40818
40877
  setTeams((prev) => mergeNames(prev, incoming));
40819
40878
  setRounds([]);
40820
40879
  },
40821
- [mergeNames]
40880
+ [mergeNames, gateDiscard]
40822
40881
  );
40823
40882
  const handleKeyDown = useCallback51(
40824
40883
  (e) => {
@@ -40829,10 +40888,14 @@ function RoundRobinScheduler({
40829
40888
  },
40830
40889
  [addTeams, input]
40831
40890
  );
40832
- const removeTeam = useCallback51((idx) => {
40833
- setTeams((prev) => prev.filter((_, i) => i !== idx));
40834
- setRounds([]);
40835
- }, []);
40891
+ const removeTeam = useCallback51(
40892
+ (idx) => {
40893
+ if (!gateDiscard("remove")) return;
40894
+ setTeams((prev) => prev.filter((_, i) => i !== idx));
40895
+ setRounds([]);
40896
+ },
40897
+ [gateDiscard]
40898
+ );
40836
40899
  const handleGenerate = useCallback51(() => {
40837
40900
  if (teams.length < minTeams) return;
40838
40901
  const result = generateSchedule(teams, L.roundLabel);
@@ -40840,15 +40903,17 @@ function RoundRobinScheduler({
40840
40903
  onGenerate?.(result);
40841
40904
  }, [teams, minTeams, L.roundLabel, onGenerate]);
40842
40905
  const handleShuffle = useCallback51(() => {
40906
+ if (!gateDiscard("shuffle")) return;
40843
40907
  setTeams((prev) => shuffle(prev));
40844
40908
  setRounds([]);
40845
- }, []);
40909
+ }, [gateDiscard]);
40846
40910
  const handleClear = useCallback51(() => {
40911
+ if (!gateDiscard("clear")) return;
40847
40912
  setTeams([]);
40848
40913
  setRounds([]);
40849
40914
  setInput("");
40850
40915
  inputRef.current?.focus();
40851
- }, []);
40916
+ }, [gateDiscard]);
40852
40917
  const canGenerate = teams.length >= minTeams;
40853
40918
  const rootStyle = {
40854
40919
  borderRadius: 16,
@@ -41314,6 +41379,8 @@ function Scoreboard({
41314
41379
  onRoundAdvance,
41315
41380
  onNewGame,
41316
41381
  onReset,
41382
+ onBeforeReset,
41383
+ onBeforeNewGame,
41317
41384
  nameMaxLength,
41318
41385
  labels,
41319
41386
  ariaLabel = "Scoreboard",
@@ -41385,19 +41452,21 @@ function Scoreboard({
41385
41452
  [minTeams]
41386
41453
  );
41387
41454
  const resetScores = useCallback52(() => {
41455
+ if (onBeforeReset && !onBeforeReset()) return;
41388
41456
  setTeams((prev) => prev.map((t) => ({ ...t, score: 0 })));
41389
41457
  setRound(1);
41390
41458
  setHistory([]);
41391
41459
  setHistoryOpen(false);
41392
41460
  onReset?.();
41393
- }, [onReset]);
41461
+ }, [onReset, onBeforeReset]);
41394
41462
  const newGame = useCallback52(() => {
41463
+ if (onBeforeNewGame && !onBeforeNewGame()) return;
41395
41464
  setTeams(createDefaultTeams(seedCount, L.teamNamePrefix));
41396
41465
  setRound(1);
41397
41466
  setHistory([]);
41398
41467
  setHistoryOpen(false);
41399
41468
  onNewGame?.();
41400
- }, [seedCount, L.teamNamePrefix, onNewGame]);
41469
+ }, [seedCount, L.teamNamePrefix, onNewGame, onBeforeNewGame]);
41401
41470
  const nextRound = useCallback52(() => {
41402
41471
  const snapshot = {
41403
41472
  round,