@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.
package/dist/index.mjs CHANGED
@@ -30656,6 +30656,7 @@ function DiceRoller({
30656
30656
  iconEmoji = "\u{1F3B2}",
30657
30657
  showHistory = false,
30658
30658
  historyMax = 8,
30659
+ initialHistory,
30659
30660
  rollRef,
30660
30661
  arenaHeight: arenaHeightProp,
30661
30662
  hideResults = false,
@@ -30667,7 +30668,9 @@ function DiceRoller({
30667
30668
  const dark = useDarkMode(darkMode);
30668
30669
  const [rolling, setRolling] = useState70(false);
30669
30670
  const [results, setResults] = useState70(null);
30670
- const [history, setHistory] = useState70([]);
30671
+ const [history, setHistory] = useState70(
30672
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax) : []
30673
+ );
30671
30674
  const dieWrapperRefs = useRef39([]);
30672
30675
  const cubeRefs = useRef39([]);
30673
30676
  const shadowRefs = useRef39([]);
@@ -30841,7 +30844,10 @@ function DiceRoller({
30841
30844
  defaultPositions,
30842
30845
  half
30843
30846
  ]);
30847
+ const prevSidesRef = useRef39(sides);
30844
30848
  useEffect54(() => {
30849
+ if (prevSidesRef.current === sides) return;
30850
+ prevSidesRef.current = sides;
30845
30851
  setHistory([]);
30846
30852
  }, [sides]);
30847
30853
  const roll = useCallback44(() => {
@@ -32923,6 +32929,8 @@ function CoinFlipper({
32923
32929
  tailsLabel = "Tails",
32924
32930
  showHistory = false,
32925
32931
  historyMax = 20,
32932
+ initialHistory,
32933
+ initialStats,
32926
32934
  flipRef,
32927
32935
  ariaLabel,
32928
32936
  className = ""
@@ -32931,8 +32939,23 @@ function CoinFlipper({
32931
32939
  const tc = typeof theme5 === "string" ? PRESETS3[theme5] || PRESETS3.gold : theme5;
32932
32940
  const [result, setResult] = useState72(null);
32933
32941
  const [flipping, setFlipping] = useState72(false);
32934
- const [history, setHistory] = useState72([]);
32935
- const [stats, setStats] = useState72({ heads: 0, tails: 0 });
32942
+ const [history, setHistory] = useState72(
32943
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice(0, historyMax).map((result2, i) => ({ result: result2, id: -(i + 1) })) : []
32944
+ );
32945
+ const [stats, setStats] = useState72(() => {
32946
+ if (initialStats) {
32947
+ return {
32948
+ heads: Math.max(0, Math.floor(initialStats.heads)),
32949
+ tails: Math.max(0, Math.floor(initialStats.tails))
32950
+ };
32951
+ }
32952
+ if (initialHistory && initialHistory.length > 0) {
32953
+ const seeded = initialHistory.slice(0, historyMax);
32954
+ const heads = seeded.filter((r) => r === "heads").length;
32955
+ return { heads, tails: seeded.length - heads };
32956
+ }
32957
+ return { heads: 0, tails: 0 };
32958
+ });
32936
32959
  const flipIdRef = useRef41(0);
32937
32960
  const coinRef = useRef41(null);
32938
32961
  const shadowRef = useRef41(null);
@@ -33850,6 +33873,23 @@ function ReelStage({
33850
33873
  }
33851
33874
  );
33852
33875
  }
33876
+ function computeDraftSeed(participants, drawnIds, removeWinners) {
33877
+ if (!removeWinners || !drawnIds || drawnIds.length === 0) return null;
33878
+ if (new Set(drawnIds).size !== drawnIds.length) return null;
33879
+ const byId = new Map(participants.map((p) => [p.id, p]));
33880
+ const drawn = [];
33881
+ for (const id of drawnIds) {
33882
+ const p = byId.get(id);
33883
+ if (!p) return null;
33884
+ drawn.push(p);
33885
+ }
33886
+ const drawnSet = new Set(drawnIds);
33887
+ return {
33888
+ pool: participants.filter((p) => !drawnSet.has(p.id)),
33889
+ // Same cap as the live history (see the pop/promote paths).
33890
+ history: drawn.slice(0, 20)
33891
+ };
33892
+ }
33853
33893
  function RandomPlayerPicker({
33854
33894
  participants,
33855
33895
  mode = "wheel",
@@ -33864,6 +33904,7 @@ function RandomPlayerPicker({
33864
33904
  trigger = "button",
33865
33905
  label = "Spin",
33866
33906
  removeWinners = false,
33907
+ initialDrawnIds,
33867
33908
  spinDuration = 5e3,
33868
33909
  minRevolutions = 4,
33869
33910
  maxRevolutions = 7,
@@ -33890,12 +33931,21 @@ function RandomPlayerPicker({
33890
33931
  const reducedMotion = usePrefersReducedMotion();
33891
33932
  const intensityCfg = INTENSITY_CONFIG[intensity];
33892
33933
  const physicsDriven = intensity === "dramatic" && !reducedMotion;
33893
- const [pool, setPool] = useState73(participants);
33934
+ const [draftSeed] = useState73(
33935
+ () => computeDraftSeed(participants, initialDrawnIds, removeWinners)
33936
+ );
33937
+ const [pool, setPool] = useState73(
33938
+ draftSeed ? draftSeed.pool : participants
33939
+ );
33894
33940
  const [rotation, setRotation] = useState73(0);
33895
33941
  const [reelY, setReelY] = useState73(0);
33896
33942
  const [spinning, setSpinning] = useState73(false);
33897
- const [winner, setWinner] = useState73(null);
33898
- const [history, setHistory] = useState73([]);
33943
+ const [winner, setWinner] = useState73(
33944
+ draftSeed ? draftSeed.history[0] ?? null : null
33945
+ );
33946
+ const [history, setHistory] = useState73(
33947
+ draftSeed ? draftSeed.history : []
33948
+ );
33899
33949
  const [revealKey, setRevealKey] = useState73(0);
33900
33950
  const [particles, setParticles] = useState73([]);
33901
33951
  const winnerTimer = useRef42(null);
@@ -33907,7 +33957,9 @@ function RandomPlayerPicker({
33907
33957
  const tickAudioRef = useRef42(null);
33908
33958
  const winAudioRef = useRef42(null);
33909
33959
  const containerRef = useRef42(null);
33910
- const prevIdsRef = useRef42("");
33960
+ const prevIdsRef = useRef42(
33961
+ draftSeed ? participants.map((p) => p.id).join("|") : ""
33962
+ );
33911
33963
  const wheelSvgRef = useRef42(null);
33912
33964
  const reelTapeRef = useRef42(null);
33913
33965
  const rafRef = useRef42(null);
@@ -41067,6 +41119,7 @@ function RoundRobinScheduler({
41067
41119
  resumeRounds,
41068
41120
  onTeamsChange,
41069
41121
  onGenerate,
41122
+ onBeforeScheduleDiscard,
41070
41123
  labels,
41071
41124
  ariaLabel = "Round robin scheduler",
41072
41125
  className,
@@ -41102,23 +41155,29 @@ function RoundRobinScheduler({
41102
41155
  },
41103
41156
  [maxTeams, nameMaxLength]
41104
41157
  );
41158
+ const gateDiscard = useCallback54(
41159
+ (action) => rounds.length === 0 || !onBeforeScheduleDiscard || onBeforeScheduleDiscard(action),
41160
+ [rounds.length, onBeforeScheduleDiscard]
41161
+ );
41105
41162
  const addTeams = useCallback54(
41106
41163
  (raw) => {
41107
41164
  const names = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
41108
41165
  if (names.length === 0) return;
41166
+ if (!gateDiscard("add")) return;
41109
41167
  setTeams((prev) => mergeNames(prev, names));
41110
41168
  setInput("");
41111
41169
  setRounds([]);
41112
41170
  },
41113
- [mergeNames]
41171
+ [mergeNames, gateDiscard]
41114
41172
  );
41115
41173
  const importTeams = useCallback54(
41116
41174
  (incoming) => {
41117
41175
  if (incoming.length === 0) return;
41176
+ if (!gateDiscard("import")) return;
41118
41177
  setTeams((prev) => mergeNames(prev, incoming));
41119
41178
  setRounds([]);
41120
41179
  },
41121
- [mergeNames]
41180
+ [mergeNames, gateDiscard]
41122
41181
  );
41123
41182
  const handleKeyDown = useCallback54(
41124
41183
  (e) => {
@@ -41129,10 +41188,14 @@ function RoundRobinScheduler({
41129
41188
  },
41130
41189
  [addTeams, input]
41131
41190
  );
41132
- const removeTeam = useCallback54((idx) => {
41133
- setTeams((prev) => prev.filter((_, i) => i !== idx));
41134
- setRounds([]);
41135
- }, []);
41191
+ const removeTeam = useCallback54(
41192
+ (idx) => {
41193
+ if (!gateDiscard("remove")) return;
41194
+ setTeams((prev) => prev.filter((_, i) => i !== idx));
41195
+ setRounds([]);
41196
+ },
41197
+ [gateDiscard]
41198
+ );
41136
41199
  const handleGenerate = useCallback54(() => {
41137
41200
  if (teams.length < minTeams) return;
41138
41201
  const result = generateSchedule(teams, L.roundLabel);
@@ -41140,15 +41203,17 @@ function RoundRobinScheduler({
41140
41203
  onGenerate?.(result);
41141
41204
  }, [teams, minTeams, L.roundLabel, onGenerate]);
41142
41205
  const handleShuffle = useCallback54(() => {
41206
+ if (!gateDiscard("shuffle")) return;
41143
41207
  setTeams((prev) => shuffle(prev));
41144
41208
  setRounds([]);
41145
- }, []);
41209
+ }, [gateDiscard]);
41146
41210
  const handleClear = useCallback54(() => {
41211
+ if (!gateDiscard("clear")) return;
41147
41212
  setTeams([]);
41148
41213
  setRounds([]);
41149
41214
  setInput("");
41150
41215
  inputRef.current?.focus();
41151
- }, []);
41216
+ }, [gateDiscard]);
41152
41217
  const canGenerate = teams.length >= minTeams;
41153
41218
  const rootStyle = {
41154
41219
  borderRadius: 16,
@@ -41614,6 +41679,8 @@ function Scoreboard({
41614
41679
  onRoundAdvance,
41615
41680
  onNewGame,
41616
41681
  onReset,
41682
+ onBeforeReset,
41683
+ onBeforeNewGame,
41617
41684
  nameMaxLength,
41618
41685
  labels,
41619
41686
  ariaLabel = "Scoreboard",
@@ -41685,19 +41752,21 @@ function Scoreboard({
41685
41752
  [minTeams]
41686
41753
  );
41687
41754
  const resetScores = useCallback55(() => {
41755
+ if (onBeforeReset && !onBeforeReset()) return;
41688
41756
  setTeams((prev) => prev.map((t) => ({ ...t, score: 0 })));
41689
41757
  setRound(1);
41690
41758
  setHistory([]);
41691
41759
  setHistoryOpen(false);
41692
41760
  onReset?.();
41693
- }, [onReset]);
41761
+ }, [onReset, onBeforeReset]);
41694
41762
  const newGame = useCallback55(() => {
41763
+ if (onBeforeNewGame && !onBeforeNewGame()) return;
41695
41764
  setTeams(createDefaultTeams(seedCount, L.teamNamePrefix));
41696
41765
  setRound(1);
41697
41766
  setHistory([]);
41698
41767
  setHistoryOpen(false);
41699
41768
  onNewGame?.();
41700
- }, [seedCount, L.teamNamePrefix, onNewGame]);
41769
+ }, [seedCount, L.teamNamePrefix, onNewGame, onBeforeNewGame]);
41701
41770
  const nextRound = useCallback55(() => {
41702
41771
  const snapshot = {
41703
41772
  round,