@digilogiclabs/saas-factory-ui 2.1.0 → 2.2.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 CHANGED
@@ -5691,6 +5691,15 @@ interface RoundRobinSchedulerProps {
5691
5691
  minTeams?: number;
5692
5692
  /** Initial roster. Uncontrolled. */
5693
5693
  defaultTeams?: string[];
5694
+ /**
5695
+ * Resume a previously generated schedule (the rounds consumers persist
5696
+ * from `onGenerate`). One-shot: read on mount, ignored afterwards.
5697
+ * Applied only when the round count matches what the current
5698
+ * `defaultTeams` roster would generate and every non-BYE name resolves
5699
+ * against that roster; otherwise ignored (empty schedule, as if the
5700
+ * prop were omitted). Does NOT re-emit `onGenerate`.
5701
+ */
5702
+ resumeRounds?: RoundRobinRound[];
5694
5703
  /** Called whenever the team roster changes. */
5695
5704
  onTeamsChange?: (teams: string[]) => void;
5696
5705
  /** Called when a new schedule is generated. */
@@ -5705,7 +5714,7 @@ interface RoundRobinSchedulerProps {
5705
5714
  * roster from a spreadsheet. Default `true`. */
5706
5715
  enableImport?: boolean;
5707
5716
  }
5708
- declare function RoundRobinScheduler({ theme, darkMode, minTeams, defaultTeams, onTeamsChange, onGenerate, labels, ariaLabel, className, enableImport, }: RoundRobinSchedulerProps): react_jsx_runtime.JSX.Element;
5717
+ declare function RoundRobinScheduler({ theme, darkMode, minTeams, defaultTeams, resumeRounds, onTeamsChange, onGenerate, labels, ariaLabel, className, enableImport, }: RoundRobinSchedulerProps): react_jsx_runtime.JSX.Element;
5709
5718
  declare namespace RoundRobinScheduler {
5710
5719
  var displayName: string;
5711
5720
  }
@@ -5751,6 +5760,13 @@ interface ScoreboardProps {
5751
5760
  /** Optional initial team state — name/score pairs. Overrides initialTeamCount
5752
5761
  * if provided. */
5753
5762
  defaultTeams?: ScoreboardTeam[];
5763
+ /** Resume the round counter from a persisted session. One-shot: read on
5764
+ * mount, ignored afterwards. Clamped to a minimum of 1. Default 1. */
5765
+ initialRound?: number;
5766
+ /** Resume prior round snapshots (the values consumers persist from
5767
+ * `onRoundAdvance`) from a persisted session. One-shot: read on mount,
5768
+ * ignored afterwards. Default empty. */
5769
+ initialHistory?: ScoreboardRoundSnapshot[];
5754
5770
  /** Called every time scores or names change. */
5755
5771
  onTeamsChange?: (teams: ScoreboardTeam[]) => void;
5756
5772
  /** Called with the snapshot when Next Round is pressed. */
@@ -5764,7 +5780,7 @@ interface ScoreboardProps {
5764
5780
  /** CSS class on root element. */
5765
5781
  className?: string;
5766
5782
  }
5767
- declare function Scoreboard({ theme, darkMode, initialTeamCount, minTeams, maxTeams, scoreButtons, defaultTeams, onTeamsChange, onRoundAdvance, onNewGame, labels, ariaLabel, className, }: ScoreboardProps): react_jsx_runtime.JSX.Element;
5783
+ declare function Scoreboard({ theme, darkMode, initialTeamCount, minTeams, maxTeams, scoreButtons, defaultTeams, initialRound, initialHistory, onTeamsChange, onRoundAdvance, onNewGame, labels, ariaLabel, className, }: ScoreboardProps): react_jsx_runtime.JSX.Element;
5768
5784
  declare namespace Scoreboard {
5769
5785
  var displayName: string;
5770
5786
  }
package/dist/index.d.ts CHANGED
@@ -5691,6 +5691,15 @@ interface RoundRobinSchedulerProps {
5691
5691
  minTeams?: number;
5692
5692
  /** Initial roster. Uncontrolled. */
5693
5693
  defaultTeams?: string[];
5694
+ /**
5695
+ * Resume a previously generated schedule (the rounds consumers persist
5696
+ * from `onGenerate`). One-shot: read on mount, ignored afterwards.
5697
+ * Applied only when the round count matches what the current
5698
+ * `defaultTeams` roster would generate and every non-BYE name resolves
5699
+ * against that roster; otherwise ignored (empty schedule, as if the
5700
+ * prop were omitted). Does NOT re-emit `onGenerate`.
5701
+ */
5702
+ resumeRounds?: RoundRobinRound[];
5694
5703
  /** Called whenever the team roster changes. */
5695
5704
  onTeamsChange?: (teams: string[]) => void;
5696
5705
  /** Called when a new schedule is generated. */
@@ -5705,7 +5714,7 @@ interface RoundRobinSchedulerProps {
5705
5714
  * roster from a spreadsheet. Default `true`. */
5706
5715
  enableImport?: boolean;
5707
5716
  }
5708
- declare function RoundRobinScheduler({ theme, darkMode, minTeams, defaultTeams, onTeamsChange, onGenerate, labels, ariaLabel, className, enableImport, }: RoundRobinSchedulerProps): react_jsx_runtime.JSX.Element;
5717
+ declare function RoundRobinScheduler({ theme, darkMode, minTeams, defaultTeams, resumeRounds, onTeamsChange, onGenerate, labels, ariaLabel, className, enableImport, }: RoundRobinSchedulerProps): react_jsx_runtime.JSX.Element;
5709
5718
  declare namespace RoundRobinScheduler {
5710
5719
  var displayName: string;
5711
5720
  }
@@ -5751,6 +5760,13 @@ interface ScoreboardProps {
5751
5760
  /** Optional initial team state — name/score pairs. Overrides initialTeamCount
5752
5761
  * if provided. */
5753
5762
  defaultTeams?: ScoreboardTeam[];
5763
+ /** Resume the round counter from a persisted session. One-shot: read on
5764
+ * mount, ignored afterwards. Clamped to a minimum of 1. Default 1. */
5765
+ initialRound?: number;
5766
+ /** Resume prior round snapshots (the values consumers persist from
5767
+ * `onRoundAdvance`) from a persisted session. One-shot: read on mount,
5768
+ * ignored afterwards. Default empty. */
5769
+ initialHistory?: ScoreboardRoundSnapshot[];
5754
5770
  /** Called every time scores or names change. */
5755
5771
  onTeamsChange?: (teams: ScoreboardTeam[]) => void;
5756
5772
  /** Called with the snapshot when Next Round is pressed. */
@@ -5764,7 +5780,7 @@ interface ScoreboardProps {
5764
5780
  /** CSS class on root element. */
5765
5781
  className?: string;
5766
5782
  }
5767
- declare function Scoreboard({ theme, darkMode, initialTeamCount, minTeams, maxTeams, scoreButtons, defaultTeams, onTeamsChange, onRoundAdvance, onNewGame, labels, ariaLabel, className, }: ScoreboardProps): react_jsx_runtime.JSX.Element;
5783
+ declare function Scoreboard({ theme, darkMode, initialTeamCount, minTeams, maxTeams, scoreButtons, defaultTeams, initialRound, initialHistory, onTeamsChange, onRoundAdvance, onNewGame, labels, ariaLabel, className, }: ScoreboardProps): react_jsx_runtime.JSX.Element;
5768
5784
  declare namespace Scoreboard {
5769
5785
  var displayName: string;
5770
5786
  }
package/dist/index.js CHANGED
@@ -40659,6 +40659,27 @@ function generateSchedule(teams, roundLabel) {
40659
40659
  }
40660
40660
  return rounds;
40661
40661
  }
40662
+ function hydrateResumeRounds(resume, teams) {
40663
+ if (!resume?.length || teams.length < 2) return [];
40664
+ const expected = teams.length % 2 === 0 ? teams.length - 1 : teams.length;
40665
+ if (resume.length !== expected) return [];
40666
+ const roster = new Set(teams.map((t) => t.toLowerCase()));
40667
+ for (const round of resume) {
40668
+ for (const m of round.matchups) {
40669
+ for (const side of [m.home, m.away]) {
40670
+ if (side !== BYE_TOKEN && !roster.has(side.toLowerCase())) return [];
40671
+ }
40672
+ }
40673
+ }
40674
+ return resume.map((round) => ({
40675
+ label: round.label,
40676
+ matchups: round.matchups.map((m) => ({
40677
+ home: m.home,
40678
+ away: m.away,
40679
+ isBye: m.home === BYE_TOKEN || m.away === BYE_TOKEN
40680
+ }))
40681
+ }));
40682
+ }
40662
40683
  var DEFAULT_LABELS4 = {
40663
40684
  inputPlaceholder: "Team or player name (comma-separated for batch)",
40664
40685
  addButton: "Add",
@@ -40679,6 +40700,7 @@ function RoundRobinScheduler({
40679
40700
  darkMode,
40680
40701
  minTeams = 3,
40681
40702
  defaultTeams = [],
40703
+ resumeRounds,
40682
40704
  onTeamsChange,
40683
40705
  onGenerate,
40684
40706
  labels,
@@ -40692,7 +40714,9 @@ function RoundRobinScheduler({
40692
40714
  const L = { ...DEFAULT_LABELS4, ...labels };
40693
40715
  const [teams, setTeams] = (0, import_react77.useState)(defaultTeams);
40694
40716
  const [input, setInput] = (0, import_react77.useState)("");
40695
- const [rounds, setRounds] = (0, import_react77.useState)([]);
40717
+ const [rounds, setRounds] = (0, import_react77.useState)(
40718
+ () => hydrateResumeRounds(resumeRounds, defaultTeams)
40719
+ );
40696
40720
  const inputRef = (0, import_react77.useRef)(null);
40697
40721
  (0, import_react77.useEffect)(() => {
40698
40722
  onTeamsChange?.(teams);
@@ -41213,6 +41237,8 @@ function Scoreboard({
41213
41237
  maxTeams = 8,
41214
41238
  scoreButtons = [-1, 1, 5, 10],
41215
41239
  defaultTeams,
41240
+ initialRound = 1,
41241
+ initialHistory,
41216
41242
  onTeamsChange,
41217
41243
  onRoundAdvance,
41218
41244
  onNewGame,
@@ -41228,8 +41254,12 @@ function Scoreboard({
41228
41254
  const [teams, setTeams] = (0, import_react78.useState)(
41229
41255
  () => defaultTeams && defaultTeams.length >= minTeams ? defaultTeams.slice(0, maxTeams) : createDefaultTeams(seedCount, L.teamNamePrefix)
41230
41256
  );
41231
- const [round, setRound] = (0, import_react78.useState)(1);
41232
- const [history, setHistory] = (0, import_react78.useState)([]);
41257
+ const [round, setRound] = (0, import_react78.useState)(
41258
+ () => Number.isFinite(initialRound) ? Math.max(1, Math.floor(initialRound)) : 1
41259
+ );
41260
+ const [history, setHistory] = (0, import_react78.useState)(
41261
+ () => initialHistory && initialHistory.length > 0 ? initialHistory.slice() : []
41262
+ );
41233
41263
  const [historyOpen, setHistoryOpen] = (0, import_react78.useState)(false);
41234
41264
  const rootRef = (0, import_react78.useRef)(null);
41235
41265
  const [containerWidth, setContainerWidth] = (0, import_react78.useState)(0);