@sudobility/sudojo_lib 0.0.4

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.
Files changed (141) hide show
  1. package/dist/hooks/index.d.ts +27 -0
  2. package/dist/hooks/index.d.ts.map +1 -0
  3. package/dist/hooks/index.js +27 -0
  4. package/dist/hooks/index.js.map +1 -0
  5. package/dist/hooks/useDailyGame.d.ts +64 -0
  6. package/dist/hooks/useDailyGame.d.ts.map +1 -0
  7. package/dist/hooks/useDailyGame.js +120 -0
  8. package/dist/hooks/useDailyGame.js.map +1 -0
  9. package/dist/hooks/useGame.d.ts +104 -0
  10. package/dist/hooks/useGame.d.ts.map +1 -0
  11. package/dist/hooks/useGame.js +546 -0
  12. package/dist/hooks/useGame.js.map +1 -0
  13. package/dist/hooks/useGamePersistence.d.ts +63 -0
  14. package/dist/hooks/useGamePersistence.d.ts.map +1 -0
  15. package/dist/hooks/useGamePersistence.js +124 -0
  16. package/dist/hooks/useGamePersistence.js.map +1 -0
  17. package/dist/hooks/useGameTeaching.d.ts +89 -0
  18. package/dist/hooks/useGameTeaching.d.ts.map +1 -0
  19. package/dist/hooks/useGameTeaching.js +230 -0
  20. package/dist/hooks/useGameTeaching.js.map +1 -0
  21. package/dist/hooks/useGameTimer.d.ts +43 -0
  22. package/dist/hooks/useGameTimer.d.ts.map +1 -0
  23. package/dist/hooks/useGameTimer.js +68 -0
  24. package/dist/hooks/useGameTimer.js.map +1 -0
  25. package/dist/hooks/useHint.d.ts +105 -0
  26. package/dist/hooks/useHint.d.ts.map +1 -0
  27. package/dist/hooks/useHint.js +179 -0
  28. package/dist/hooks/useHint.js.map +1 -0
  29. package/dist/hooks/useLearning.d.ts +100 -0
  30. package/dist/hooks/useLearning.d.ts.map +1 -0
  31. package/dist/hooks/useLearning.js +127 -0
  32. package/dist/hooks/useLearning.js.map +1 -0
  33. package/dist/hooks/useLevelGame.d.ts +68 -0
  34. package/dist/hooks/useLevelGame.d.ts.map +1 -0
  35. package/dist/hooks/useLevelGame.js +128 -0
  36. package/dist/hooks/useLevelGame.js.map +1 -0
  37. package/dist/hooks/useLevels.d.ts +93 -0
  38. package/dist/hooks/useLevels.d.ts.map +1 -0
  39. package/dist/hooks/useLevels.js +98 -0
  40. package/dist/hooks/useLevels.js.map +1 -0
  41. package/dist/hooks/useLocalStorage.d.ts +26 -0
  42. package/dist/hooks/useLocalStorage.d.ts.map +1 -0
  43. package/dist/hooks/useLocalStorage.js +75 -0
  44. package/dist/hooks/useLocalStorage.js.map +1 -0
  45. package/dist/hooks/useSudoku.d.ts +125 -0
  46. package/dist/hooks/useSudoku.d.ts.map +1 -0
  47. package/dist/hooks/useSudoku.js +655 -0
  48. package/dist/hooks/useSudoku.js.map +1 -0
  49. package/dist/hooks/useTechniques.d.ts +92 -0
  50. package/dist/hooks/useTechniques.d.ts.map +1 -0
  51. package/dist/hooks/useTechniques.js +108 -0
  52. package/dist/hooks/useTechniques.js.map +1 -0
  53. package/dist/index.d.ts +42 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +64 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/test/setup.d.ts +2 -0
  58. package/dist/test/setup.d.ts.map +1 -0
  59. package/dist/test/setup.js +35 -0
  60. package/dist/test/setup.js.map +1 -0
  61. package/dist/types/display.d.ts +142 -0
  62. package/dist/types/display.d.ts.map +1 -0
  63. package/dist/types/display.js +94 -0
  64. package/dist/types/display.js.map +1 -0
  65. package/dist/types/game.d.ts +201 -0
  66. package/dist/types/game.d.ts.map +1 -0
  67. package/dist/types/game.js +26 -0
  68. package/dist/types/game.js.map +1 -0
  69. package/dist/types/gamePersistence.d.ts +31 -0
  70. package/dist/types/gamePersistence.d.ts.map +1 -0
  71. package/dist/types/gamePersistence.js +15 -0
  72. package/dist/types/gamePersistence.js.map +1 -0
  73. package/dist/types/index.d.ts +18 -0
  74. package/dist/types/index.d.ts.map +1 -0
  75. package/dist/types/index.js +11 -0
  76. package/dist/types/index.js.map +1 -0
  77. package/dist/types/progress.d.ts +43 -0
  78. package/dist/types/progress.d.ts.map +1 -0
  79. package/dist/types/progress.js +19 -0
  80. package/dist/types/progress.js.map +1 -0
  81. package/dist/types/settings.d.ts +19 -0
  82. package/dist/types/settings.d.ts.map +1 -0
  83. package/dist/types/settings.js +12 -0
  84. package/dist/types/settings.js.map +1 -0
  85. package/dist/types/subscription.d.ts +27 -0
  86. package/dist/types/subscription.d.ts.map +1 -0
  87. package/dist/types/subscription.js +8 -0
  88. package/dist/types/subscription.js.map +1 -0
  89. package/dist/types/sudoku.d.ts +147 -0
  90. package/dist/types/sudoku.d.ts.map +1 -0
  91. package/dist/types/sudoku.js +125 -0
  92. package/dist/types/sudoku.js.map +1 -0
  93. package/dist/utils/auth.d.ts +25 -0
  94. package/dist/utils/auth.d.ts.map +1 -0
  95. package/dist/utils/auth.js +47 -0
  96. package/dist/utils/auth.js.map +1 -0
  97. package/dist/utils/board.d.ts +116 -0
  98. package/dist/utils/board.d.ts.map +1 -0
  99. package/dist/utils/board.js +291 -0
  100. package/dist/utils/board.js.map +1 -0
  101. package/dist/utils/index.d.ts +18 -0
  102. package/dist/utils/index.d.ts.map +1 -0
  103. package/dist/utils/index.js +23 -0
  104. package/dist/utils/index.js.map +1 -0
  105. package/dist/utils/progress.d.ts +44 -0
  106. package/dist/utils/progress.d.ts.map +1 -0
  107. package/dist/utils/progress.js +104 -0
  108. package/dist/utils/progress.js.map +1 -0
  109. package/dist/utils/scramble.d.ts +35 -0
  110. package/dist/utils/scramble.d.ts.map +1 -0
  111. package/dist/utils/scramble.js +270 -0
  112. package/dist/utils/scramble.js.map +1 -0
  113. package/dist/utils/subscription.d.ts +82 -0
  114. package/dist/utils/subscription.d.ts.map +1 -0
  115. package/dist/utils/subscription.js +117 -0
  116. package/dist/utils/subscription.js.map +1 -0
  117. package/dist/utils/sudokuPresenter.d.ts +62 -0
  118. package/dist/utils/sudokuPresenter.d.ts.map +1 -0
  119. package/dist/utils/sudokuPresenter.js +403 -0
  120. package/dist/utils/sudokuPresenter.js.map +1 -0
  121. package/dist/utils/sudokuScrambler.d.ts +61 -0
  122. package/dist/utils/sudokuScrambler.d.ts.map +1 -0
  123. package/dist/utils/sudokuScrambler.js +223 -0
  124. package/dist/utils/sudokuScrambler.js.map +1 -0
  125. package/dist/utils/technique.d.ts +41 -0
  126. package/dist/utils/technique.d.ts.map +1 -0
  127. package/dist/utils/technique.js +106 -0
  128. package/dist/utils/technique.js.map +1 -0
  129. package/dist/utils/theme.d.ts +31 -0
  130. package/dist/utils/theme.d.ts.map +1 -0
  131. package/dist/utils/theme.js +40 -0
  132. package/dist/utils/theme.js.map +1 -0
  133. package/dist/utils/time.d.ts +22 -0
  134. package/dist/utils/time.d.ts.map +1 -0
  135. package/dist/utils/time.js +41 -0
  136. package/dist/utils/time.js.map +1 -0
  137. package/dist/utils/validation.d.ts +107 -0
  138. package/dist/utils/validation.d.ts.map +1 -0
  139. package/dist/utils/validation.js +248 -0
  140. package/dist/utils/validation.js.map +1 -0
  141. package/package.json +79 -0
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Hook for getting hints from the Sudoku solver
3
+ *
4
+ * Matches Kotlin HintInteractor behavior:
5
+ * - Stores all hint steps from the API response
6
+ * - Tracks current step index
7
+ * - next() advances to next step (if available)
8
+ * - previous() goes back to previous step
9
+ * - getHint() fetches new hints OR advances to next step if hints exist
10
+ */
11
+ import { type ClientConfig, type SolverHintStep } from '@sudobility/sudojo_client';
12
+ import type { NetworkClient } from '@sudobility/types';
13
+ /** Board data returned when applying a hint */
14
+ export interface HintBoardData {
15
+ /** 81-character user input string */
16
+ user: string;
17
+ /** Pencilmarks string (comma-separated) */
18
+ pencilmarks: string | null;
19
+ /** Whether auto-pencilmarks are enabled */
20
+ autoPencilmarks: boolean;
21
+ }
22
+ export interface UseHintOptions {
23
+ /** Network client for API calls */
24
+ networkClient: NetworkClient;
25
+ /** Solver client configuration */
26
+ config: ClientConfig;
27
+ /** Original puzzle string (81 chars) */
28
+ puzzle: string;
29
+ /** Current user input string (81 chars) */
30
+ userInput: string;
31
+ /** Current pencilmarks (comma-separated or empty) */
32
+ pencilmarks?: string;
33
+ /** Whether auto-pencilmarks were generated */
34
+ autoPencilmarks?: boolean;
35
+ }
36
+ export interface UseHintResult {
37
+ /** Current hint step being displayed */
38
+ hint: SolverHintStep | null;
39
+ /** All hint steps (for showing progress like "Step 1 of 3") */
40
+ hints: SolverHintStep[] | null;
41
+ /** Current step index (0-based) */
42
+ stepIndex: number;
43
+ /** Total number of steps */
44
+ totalSteps: number;
45
+ /** Whether a hint request is in progress */
46
+ isLoading: boolean;
47
+ /** Error message if hint request failed */
48
+ error: string | null;
49
+ /** Request hints or advance to next step */
50
+ getHint: () => Promise<void>;
51
+ /** Go to next hint step */
52
+ nextStep: () => void;
53
+ /** Go to previous hint step */
54
+ previousStep: () => void;
55
+ /** Clear all hints */
56
+ clearHint: () => void;
57
+ /** Apply the hint to the board - returns board data and clears hint */
58
+ applyHint: () => HintBoardData | null;
59
+ /** Whether there are more steps after current */
60
+ hasNextStep: boolean;
61
+ /** Whether there are steps before current */
62
+ hasPreviousStep: boolean;
63
+ /** Whether the hint can be applied (on last step) */
64
+ canApply: boolean;
65
+ }
66
+ /**
67
+ * Hook for getting hints from the solver API
68
+ *
69
+ * Matches Kotlin HintInteractor behavior:
70
+ * - First call to getHint() fetches hints from API
71
+ * - Subsequent calls advance to next step (if available)
72
+ * - Use nextStep()/previousStep() to navigate manually
73
+ * - clearHint() resets everything
74
+ *
75
+ * @param options - Puzzle state for hint generation
76
+ * @returns Hint state and controls
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * const { hint, isLoading, getHint, nextStep, clearHint, applyHint } = useHint({
81
+ * networkClient,
82
+ * config,
83
+ * puzzle: originalPuzzle,
84
+ * userInput: currentInput,
85
+ * pencilmarks: currentPencilmarks,
86
+ * });
87
+ *
88
+ * // Get hint button
89
+ * <Button onClick={getHint} disabled={isLoading}>Get Hint</Button>
90
+ *
91
+ * // Display hint
92
+ * {hint && <HintDisplay step={hint} />}
93
+ *
94
+ * // Apply hint to board
95
+ * const handleApply = () => {
96
+ * const boardData = applyHint();
97
+ * if (boardData) {
98
+ * setUserInput(boardData.user);
99
+ * setPencilmarks(boardData.pencilmarks);
100
+ * }
101
+ * };
102
+ * ```
103
+ */
104
+ export declare function useHint({ networkClient, config, puzzle, userInput, pencilmarks, autoPencilmarks, }: UseHintOptions): UseHintResult;
105
+ //# sourceMappingURL=useHint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHint.d.ts","sourceRoot":"","sources":["../../src/hooks/useHint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EACL,KAAK,YAAY,EAIjB,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2CAA2C;IAC3C,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,kCAAkC;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,+DAA+D;IAC/D,KAAK,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAC/B,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,4CAA4C;IAC5C,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,+BAA+B;IAC/B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,sBAAsB;IACtB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,uEAAuE;IACvE,SAAS,EAAE,MAAM,aAAa,GAAG,IAAI,CAAC;IACtC,iDAAiD;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,6CAA6C;IAC7C,eAAe,EAAE,OAAO,CAAC;IACzB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,OAAO,CAAC,EACtB,aAAa,EACb,MAAM,EACN,MAAM,EACN,SAAS,EACT,WAAW,EACX,eAAuB,GACxB,EAAE,cAAc,GAAG,aAAa,CA2IhC"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Hook for getting hints from the Sudoku solver
3
+ *
4
+ * Matches Kotlin HintInteractor behavior:
5
+ * - Stores all hint steps from the API response
6
+ * - Tracks current step index
7
+ * - next() advances to next step (if available)
8
+ * - previous() goes back to previous step
9
+ * - getHint() fetches new hints OR advances to next step if hints exist
10
+ */
11
+ import { useCallback, useRef, useState } from 'react';
12
+ import { createSudojoSolverClient, } from '@sudobility/sudojo_client';
13
+ /**
14
+ * Hook for getting hints from the solver API
15
+ *
16
+ * Matches Kotlin HintInteractor behavior:
17
+ * - First call to getHint() fetches hints from API
18
+ * - Subsequent calls advance to next step (if available)
19
+ * - Use nextStep()/previousStep() to navigate manually
20
+ * - clearHint() resets everything
21
+ *
22
+ * @param options - Puzzle state for hint generation
23
+ * @returns Hint state and controls
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * const { hint, isLoading, getHint, nextStep, clearHint, applyHint } = useHint({
28
+ * networkClient,
29
+ * config,
30
+ * puzzle: originalPuzzle,
31
+ * userInput: currentInput,
32
+ * pencilmarks: currentPencilmarks,
33
+ * });
34
+ *
35
+ * // Get hint button
36
+ * <Button onClick={getHint} disabled={isLoading}>Get Hint</Button>
37
+ *
38
+ * // Display hint
39
+ * {hint && <HintDisplay step={hint} />}
40
+ *
41
+ * // Apply hint to board
42
+ * const handleApply = () => {
43
+ * const boardData = applyHint();
44
+ * if (boardData) {
45
+ * setUserInput(boardData.user);
46
+ * setPencilmarks(boardData.pencilmarks);
47
+ * }
48
+ * };
49
+ * ```
50
+ */
51
+ export function useHint({ networkClient, config, puzzle, userInput, pencilmarks, autoPencilmarks = false, }) {
52
+ const [hints, setHints] = useState(null);
53
+ const [stepIndex, setStepIndex] = useState(0);
54
+ const [isLoading, setIsLoading] = useState(false);
55
+ const [error, setError] = useState(null);
56
+ // Track puzzle state to detect when we need to re-fetch
57
+ const lastPuzzleStateRef = useRef('');
58
+ // Store board data from API response for applying hint
59
+ const boardDataRef = useRef(null);
60
+ // Compute current hint step
61
+ const hint = hints?.[stepIndex] ?? null;
62
+ const totalSteps = hints?.length ?? 0;
63
+ const hasNextStep = stepIndex < totalSteps - 1;
64
+ const hasPreviousStep = stepIndex > 0;
65
+ // Can apply when on last step and have board data
66
+ const canApply = hints !== null &&
67
+ stepIndex === totalSteps - 1 &&
68
+ boardDataRef.current !== null;
69
+ // Fetch hints from API
70
+ const fetchHints = useCallback(async () => {
71
+ setIsLoading(true);
72
+ setError(null);
73
+ try {
74
+ const client = createSudojoSolverClient(networkClient, config);
75
+ const solveOptions = {
76
+ original: puzzle,
77
+ user: userInput,
78
+ autoPencilmarks,
79
+ ...(pencilmarks !== undefined && { pencilmarks }),
80
+ };
81
+ const response = await client.solve(solveOptions);
82
+ if (response.success && response.data?.hints?.length) {
83
+ setHints(response.data.hints);
84
+ setStepIndex(0);
85
+ // Store board data for applying hint later
86
+ boardDataRef.current = response.data.board ?? null;
87
+ // Track the puzzle state we fetched for
88
+ lastPuzzleStateRef.current = `${puzzle}|${userInput}|${pencilmarks ?? ''}`;
89
+ }
90
+ else if (response.error) {
91
+ setError(response.error);
92
+ setHints(null);
93
+ boardDataRef.current = null;
94
+ }
95
+ else {
96
+ setError('No hints available');
97
+ setHints(null);
98
+ boardDataRef.current = null;
99
+ }
100
+ }
101
+ catch (err) {
102
+ setError(err instanceof Error ? err.message : 'Failed to get hint');
103
+ setHints(null);
104
+ boardDataRef.current = null;
105
+ }
106
+ finally {
107
+ setIsLoading(false);
108
+ }
109
+ }, [networkClient, config, puzzle, userInput, pencilmarks, autoPencilmarks]);
110
+ // Get hint: fetch if no hints or puzzle changed, otherwise advance
111
+ const getHint = useCallback(async () => {
112
+ const currentPuzzleState = `${puzzle}|${userInput}|${pencilmarks ?? ''}`;
113
+ if (hints === null || lastPuzzleStateRef.current !== currentPuzzleState) {
114
+ // No hints or puzzle state changed - fetch new hints
115
+ await fetchHints();
116
+ }
117
+ else if (hasNextStep) {
118
+ // Have hints and more steps - advance to next
119
+ setStepIndex(prev => prev + 1);
120
+ }
121
+ // If at last step and hints exist, do nothing (stay on last step)
122
+ }, [hints, hasNextStep, fetchHints, puzzle, userInput, pencilmarks]);
123
+ // Navigate to next step
124
+ const nextStep = useCallback(() => {
125
+ if (hasNextStep) {
126
+ setStepIndex(prev => prev + 1);
127
+ }
128
+ }, [hasNextStep]);
129
+ // Navigate to previous step
130
+ const previousStep = useCallback(() => {
131
+ if (hasPreviousStep) {
132
+ setStepIndex(prev => prev - 1);
133
+ }
134
+ }, [hasPreviousStep]);
135
+ // Clear all hints
136
+ const clearHint = useCallback(() => {
137
+ setHints(null);
138
+ setStepIndex(0);
139
+ setError(null);
140
+ lastPuzzleStateRef.current = '';
141
+ boardDataRef.current = null;
142
+ }, []);
143
+ // Apply the hint to the board - returns board data and clears hint
144
+ const applyHint = useCallback(() => {
145
+ const board = boardDataRef.current;
146
+ if (!board?.user) {
147
+ return null;
148
+ }
149
+ const result = {
150
+ user: board.user,
151
+ pencilmarks: board.pencilmarks?.pencilmarks ?? null,
152
+ autoPencilmarks: board.pencilmarks?.auto ?? false,
153
+ };
154
+ // Clear hints after applying (matches Kotlin: result = null)
155
+ setHints(null);
156
+ setStepIndex(0);
157
+ setError(null);
158
+ lastPuzzleStateRef.current = '';
159
+ boardDataRef.current = null;
160
+ return result;
161
+ }, []);
162
+ return {
163
+ hint,
164
+ hints,
165
+ stepIndex,
166
+ totalSteps,
167
+ isLoading,
168
+ error,
169
+ getHint,
170
+ nextStep,
171
+ previousStep,
172
+ clearHint,
173
+ applyHint,
174
+ hasNextStep,
175
+ hasPreviousStep,
176
+ canApply,
177
+ };
178
+ }
179
+ //# sourceMappingURL=useHint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHint.js","sourceRoot":"","sources":["../../src/hooks/useHint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Hook for fetching and managing learning materials for techniques
3
+ */
4
+ import type { Learning } from '@sudobility/sudojo_types';
5
+ import type { NetworkClient } from '@sudobility/types';
6
+ import { type SudojoAuth, type SudojoConfig } from '@sudobility/sudojo_client';
7
+ export interface UseLearningOptions {
8
+ /** Network client for API calls */
9
+ networkClient: NetworkClient;
10
+ /** Sudojo API configuration */
11
+ config: SudojoConfig;
12
+ /** Auth credentials (optional for public data) */
13
+ auth?: SudojoAuth;
14
+ /** Optional technique UUID to filter learning materials */
15
+ techniqueUuid?: string;
16
+ /** Optional language code to filter learning materials */
17
+ languageCode?: string;
18
+ /** Whether to enable the query */
19
+ enabled?: boolean;
20
+ }
21
+ export interface UseLearningResult {
22
+ /** All learning materials (optionally filtered) */
23
+ learningMaterials: Learning[];
24
+ /** Whether learning materials are loading */
25
+ isLoading: boolean;
26
+ /** Error if loading failed */
27
+ error: Error | null;
28
+ /** Refetch learning materials */
29
+ refetch: () => void;
30
+ /** Get learning material by UUID */
31
+ getLearningByUuid: (uuid: string) => Learning | undefined;
32
+ /** Learning materials sorted by index */
33
+ sortedLearning: Learning[];
34
+ /** Group learning materials by technique UUID */
35
+ learningByTechnique: Map<string, Learning[]>;
36
+ /** Group learning materials by language code */
37
+ learningByLanguage: Map<string, Learning[]>;
38
+ }
39
+ /**
40
+ * Hook for fetching and managing learning materials
41
+ *
42
+ * @param options - Hook options
43
+ * @returns Learning materials data and utilities
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * function LearningContent({ techniqueUuid }: { techniqueUuid: string }) {
48
+ * const { learningMaterials, isLoading, sortedLearning } = useLearning({
49
+ * networkClient,
50
+ * config: { baseUrl: 'https://api.sudojo.com' },
51
+ * techniqueUuid,
52
+ * languageCode: 'en',
53
+ * });
54
+ *
55
+ * if (isLoading) return <Loading />;
56
+ *
57
+ * return (
58
+ * <div>
59
+ * {sortedLearning.map(item => (
60
+ * <div key={item.uuid}>
61
+ * <p>{item.text}</p>
62
+ * {item.image_url && <img src={item.image_url} alt="" />}
63
+ * </div>
64
+ * ))}
65
+ * </div>
66
+ * );
67
+ * }
68
+ * ```
69
+ */
70
+ export declare function useLearning(options: UseLearningOptions): UseLearningResult;
71
+ export interface UseLearningItemOptions {
72
+ /** Network client for API calls */
73
+ networkClient: NetworkClient;
74
+ /** Sudojo API configuration */
75
+ config: SudojoConfig;
76
+ /** Auth credentials (optional for public data) */
77
+ auth?: SudojoAuth;
78
+ /** Learning item UUID to fetch */
79
+ learningUuid: string;
80
+ /** Whether to enable the query */
81
+ enabled?: boolean;
82
+ }
83
+ export interface UseLearningItemResult {
84
+ /** The fetched learning item */
85
+ learningItem: Learning | null;
86
+ /** Whether learning item is loading */
87
+ isLoading: boolean;
88
+ /** Error if loading failed */
89
+ error: Error | null;
90
+ /** Refetch learning item */
91
+ refetch: () => void;
92
+ }
93
+ /**
94
+ * Hook for fetching a single learning item by UUID
95
+ *
96
+ * @param options - Hook options
97
+ * @returns Learning item data
98
+ */
99
+ export declare function useLearningItem(options: UseLearningItemOptions): UseLearningItemResult;
100
+ //# sourceMappingURL=useLearning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLearning.d.ts","sourceRoot":"","sources":["../../src/hooks/useLearning.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EACL,KAAK,UAAU,EACf,KAAK,YAAY,EAGlB,MAAM,2BAA2B,CAAC;AAKnC,MAAM,WAAW,kBAAkB;IACjC,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,kDAAkD;IAClD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,mDAAmD;IACnD,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,iCAAiC;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,GAAG,SAAS,CAAC;IAC1D,yCAAyC;IACzC,cAAc,EAAE,QAAQ,EAAE,CAAC;IAC3B,iDAAiD;IACjD,mBAAmB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC7C,gDAAgD;IAChD,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAiF1E;AAED,MAAM,WAAW,sBAAsB;IACrC,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,kDAAkD;IAClD,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,kCAAkC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,YAAY,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC9B,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,4BAA4B;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAC9B,qBAAqB,CAgCvB"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Hook for fetching and managing learning materials for techniques
3
+ */
4
+ import { useMemo } from 'react';
5
+ import { useSudojoLearning, useSudojoLearningItem, } from '@sudobility/sudojo_client';
6
+ /** Default empty auth for public endpoints */
7
+ const DEFAULT_AUTH = { accessToken: '' };
8
+ /**
9
+ * Hook for fetching and managing learning materials
10
+ *
11
+ * @param options - Hook options
12
+ * @returns Learning materials data and utilities
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * function LearningContent({ techniqueUuid }: { techniqueUuid: string }) {
17
+ * const { learningMaterials, isLoading, sortedLearning } = useLearning({
18
+ * networkClient,
19
+ * config: { baseUrl: 'https://api.sudojo.com' },
20
+ * techniqueUuid,
21
+ * languageCode: 'en',
22
+ * });
23
+ *
24
+ * if (isLoading) return <Loading />;
25
+ *
26
+ * return (
27
+ * <div>
28
+ * {sortedLearning.map(item => (
29
+ * <div key={item.uuid}>
30
+ * <p>{item.text}</p>
31
+ * {item.image_url && <img src={item.image_url} alt="" />}
32
+ * </div>
33
+ * ))}
34
+ * </div>
35
+ * );
36
+ * }
37
+ * ```
38
+ */
39
+ export function useLearning(options) {
40
+ const { networkClient, config, auth = DEFAULT_AUTH, techniqueUuid, languageCode, enabled = true, } = options;
41
+ const queryParams = useMemo(() => {
42
+ // Only return params if at least one filter is provided
43
+ if (!techniqueUuid && !languageCode)
44
+ return undefined;
45
+ return {
46
+ technique_uuid: techniqueUuid ?? null,
47
+ language_code: languageCode ?? null,
48
+ };
49
+ }, [techniqueUuid, languageCode]);
50
+ const { data, isLoading, error, refetch } = useSudojoLearning(networkClient, config, auth, queryParams, { enabled });
51
+ const learningMaterials = useMemo(() => {
52
+ if (!data?.success || !data.data)
53
+ return [];
54
+ return data.data;
55
+ }, [data]);
56
+ const sortedLearning = useMemo(() => {
57
+ return [...learningMaterials].sort((a, b) => {
58
+ // First sort by technique UUID, then by index
59
+ if (a.technique_uuid !== b.technique_uuid) {
60
+ return (a.technique_uuid ?? '').localeCompare(b.technique_uuid ?? '');
61
+ }
62
+ return a.index - b.index;
63
+ });
64
+ }, [learningMaterials]);
65
+ const getLearningByUuid = useMemo(() => {
66
+ const learningMap = new Map(learningMaterials.map(l => [l.uuid, l]));
67
+ return (uuid) => learningMap.get(uuid);
68
+ }, [learningMaterials]);
69
+ const learningByTechnique = useMemo(() => {
70
+ const byTechnique = new Map();
71
+ for (const learning of sortedLearning) {
72
+ const key = learning.technique_uuid ?? '';
73
+ const existing = byTechnique.get(key) ?? [];
74
+ existing.push(learning);
75
+ byTechnique.set(key, existing);
76
+ }
77
+ return byTechnique;
78
+ }, [sortedLearning]);
79
+ const learningByLanguage = useMemo(() => {
80
+ const byLanguage = new Map();
81
+ for (const learning of sortedLearning) {
82
+ const key = learning.language_code;
83
+ const existing = byLanguage.get(key) ?? [];
84
+ existing.push(learning);
85
+ byLanguage.set(key, existing);
86
+ }
87
+ return byLanguage;
88
+ }, [sortedLearning]);
89
+ return {
90
+ learningMaterials,
91
+ isLoading,
92
+ error: error ?? null,
93
+ refetch: () => {
94
+ refetch();
95
+ },
96
+ getLearningByUuid,
97
+ sortedLearning,
98
+ learningByTechnique,
99
+ learningByLanguage,
100
+ };
101
+ }
102
+ /**
103
+ * Hook for fetching a single learning item by UUID
104
+ *
105
+ * @param options - Hook options
106
+ * @returns Learning item data
107
+ */
108
+ export function useLearningItem(options) {
109
+ const { networkClient, config, auth = DEFAULT_AUTH, learningUuid, enabled = true, } = options;
110
+ const { data, isLoading, error, refetch } = useSudojoLearningItem(networkClient, config, auth, learningUuid, {
111
+ enabled: enabled && !!learningUuid,
112
+ });
113
+ const learningItem = useMemo(() => {
114
+ if (!data?.success || !data.data)
115
+ return null;
116
+ return data.data;
117
+ }, [data]);
118
+ return {
119
+ learningItem,
120
+ isLoading,
121
+ error: error ?? null,
122
+ refetch: () => {
123
+ refetch();
124
+ },
125
+ };
126
+ }
127
+ //# sourceMappingURL=useLearning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLearning.js","sourceRoot":"","sources":["../../src/hooks/useLearning.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Hook for fetching and managing game board for a specific level
3
+ * Handles auth and subscription status with automatic refresh
4
+ */
5
+ import type { Board } from '@sudobility/sudojo_types';
6
+ import type { NetworkClient } from '@sudobility/types';
7
+ import { type SudojoAuth, type SudojoConfig } from '@sudobility/sudojo_client';
8
+ /** Game fetch status indicating what screen to show */
9
+ export type GameFetchStatus = 'loading' | 'success' | 'auth_required' | 'subscription_required' | 'error';
10
+ export interface UseLevelGameOptions {
11
+ /** Network client for API calls */
12
+ networkClient: NetworkClient;
13
+ /** Sudojo API configuration */
14
+ config: SudojoConfig;
15
+ /** Auth credentials with access token */
16
+ auth: SudojoAuth;
17
+ /** Level UUID to fetch game for */
18
+ levelId: string;
19
+ /** Whether subscription is currently active */
20
+ subscriptionActive?: boolean;
21
+ /** Whether to enable the query */
22
+ enabled?: boolean;
23
+ }
24
+ export interface UseLevelGameResult {
25
+ /** The game board data */
26
+ board: Board | null;
27
+ /** Current status of the game fetch */
28
+ status: GameFetchStatus;
29
+ /** Whether data is loading */
30
+ isLoading: boolean;
31
+ /** Error if fetch failed */
32
+ error: Error | null;
33
+ /** Refetch the game board */
34
+ refetch: () => void;
35
+ /** Fetch a new random board for this level */
36
+ nextPuzzle: () => void;
37
+ }
38
+ /**
39
+ * Hook for fetching a game board for a specific level
40
+ *
41
+ * Automatically refetches when auth token or subscription status changes.
42
+ * Returns status indicating whether auth or subscription is required.
43
+ *
44
+ * @param options - Hook options
45
+ * @returns Game board data and status
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * function LevelPlayPage({ levelId }: { levelId: string }) {
50
+ * const { board, status, refetch, nextPuzzle } = useLevelGame({
51
+ * networkClient,
52
+ * config,
53
+ * auth,
54
+ * levelId,
55
+ * subscriptionActive: subscription.isActive,
56
+ * });
57
+ *
58
+ * if (status === 'loading') return <Loading />;
59
+ * if (status === 'auth_required') return <AuthRequired onLogin={openAuthModal} />;
60
+ * if (status === 'subscription_required') return <SubscriptionPaywall onSuccess={refetch} />;
61
+ * if (status === 'error') return <Error />;
62
+ *
63
+ * return <SudokuGame puzzle={board.board} solution={board.solution} />;
64
+ * }
65
+ * ```
66
+ */
67
+ export declare function useLevelGame(options: UseLevelGameOptions): UseLevelGameResult;
68
+ //# sourceMappingURL=useLevelGame.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLevelGame.d.ts","sourceRoot":"","sources":["../../src/hooks/useLevelGame.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EACL,KAAK,UAAU,EACf,KAAK,YAAY,EAElB,MAAM,2BAA2B,CAAC;AAGnC,uDAAuD;AACvD,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,SAAS,GACT,eAAe,GACf,uBAAuB,GACvB,OAAO,CAAC;AAuDZ,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,aAAa,EAAE,aAAa,CAAC;IAC7B,+BAA+B;IAC/B,MAAM,EAAE,YAAY,CAAC;IACrB,yCAAyC;IACzC,IAAI,EAAE,UAAU,CAAC;IACjB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,0BAA0B;IAC1B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,uCAAuC;IACvC,MAAM,EAAE,eAAe,CAAC;IACxB,8BAA8B;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAmF7E"}