@academy-sdk/sdk 0.1.1 → 0.2.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.
Files changed (239) hide show
  1. package/dist/academy-sdk-sdk-v1.0.0.zip +0 -0
  2. package/dist/bundle.js +70 -0
  3. package/dist/manifest.json +5 -0
  4. package/dist/styles.css +3307 -0
  5. package/package.json +41 -46
  6. package/src/components/atoms/Avatar.tsx +38 -0
  7. package/src/components/atoms/Badge.tsx +32 -0
  8. package/src/components/atoms/Button.tsx +48 -0
  9. package/src/components/atoms/Card.tsx +33 -0
  10. package/src/components/atoms/Input.tsx +39 -0
  11. package/src/components/atoms/ProgressBar.tsx +52 -0
  12. package/src/components/atoms/Tabs.tsx +47 -0
  13. package/{dist/components/atoms/index.d.ts → src/components/atoms/index.ts} +0 -1
  14. package/{dist/components/index.d.ts → src/components/index.ts} +7 -1
  15. package/src/components/molecules/CourseCard.tsx +215 -0
  16. package/src/components/molecules/EmptyState.tsx +23 -0
  17. package/src/components/molecules/LoadingSpinner.tsx +27 -0
  18. package/src/components/molecules/PageHeader.tsx +22 -0
  19. package/src/components/molecules/Pagination.tsx +82 -0
  20. package/src/components/molecules/SearchInput.tsx +35 -0
  21. package/{dist/components/molecules/index.d.ts → src/components/molecules/index.ts} +0 -1
  22. package/src/components/organisms/CourseSidebar.tsx +276 -0
  23. package/src/components/organisms/LearnerNavbar.tsx +129 -0
  24. package/src/components/organisms/LearnerSidebar.tsx +148 -0
  25. package/src/components/organisms/LessonBookmarks.tsx +128 -0
  26. package/src/components/organisms/LessonNotes.tsx +153 -0
  27. package/{dist/components/organisms/index.d.ts → src/components/organisms/index.ts} +0 -1
  28. package/src/components/pages/BundleDetailPage.tsx +388 -0
  29. package/src/components/pages/CatalogBundlesPage.tsx +96 -0
  30. package/src/components/pages/CatalogCoursesPage.tsx +299 -0
  31. package/src/components/pages/CourseDetailPage.tsx +582 -0
  32. package/src/components/pages/CoursePlayerPage.tsx +481 -0
  33. package/src/components/pages/CreatorProfilePage.tsx +161 -0
  34. package/src/components/pages/LearnerSettingsPage.tsx +58 -0
  35. package/src/components/pages/ManualReviewDetailPage.tsx +254 -0
  36. package/src/components/pages/ManualReviewPage.tsx +228 -0
  37. package/src/components/pages/MessagesPage.tsx +285 -0
  38. package/src/components/pages/MyLearningPage.tsx +239 -0
  39. package/src/components/pages/PaymentCancelPage.tsx +74 -0
  40. package/src/components/pages/PaymentSuccessPage.tsx +73 -0
  41. package/{dist/components/pages/index.d.ts → src/components/pages/index.ts} +0 -1
  42. package/src/components/utils.ts +6 -0
  43. package/src/contracts/components.contract.ts +89 -0
  44. package/{dist/contracts/index.d.ts → src/contracts/index.ts} +0 -1
  45. package/src/contracts/layout.contract.ts +36 -0
  46. package/src/contracts/pages.contract.ts +275 -0
  47. package/src/contracts/template.contract.ts +100 -0
  48. package/src/default-template.tsx +52 -0
  49. package/{dist/hooks/index.d.ts → src/hooks/index.ts} +15 -1
  50. package/src/hooks/sdk-context.tsx +152 -0
  51. package/src/hooks/useAiCoach.ts +27 -0
  52. package/src/hooks/useBookmarks.ts +35 -0
  53. package/{dist/hooks/useCourseSearch.d.ts → src/hooks/useCourseSearch.ts} +8 -5
  54. package/{dist/hooks/useDebounce.d.ts → src/hooks/useDebounce.ts} +8 -2
  55. package/{dist/hooks/useMyBundles.d.ts → src/hooks/useMyBundles.ts} +8 -6
  56. package/{dist/hooks/useMyCourses.d.ts → src/hooks/useMyCourses.ts} +8 -6
  57. package/src/hooks/useNotes.ts +35 -0
  58. package/src/hooks/useNotifications.ts +16 -0
  59. package/{dist/hooks/useTheme.d.ts → src/hooks/useTheme.ts} +8 -5
  60. package/src/hooks/useToast.ts +17 -0
  61. package/{dist/hooks/useUser.d.ts → src/hooks/useUser.ts} +13 -9
  62. package/src/index.ts +33 -0
  63. package/src/layouts/DefaultLayout.tsx +58 -0
  64. package/src/manifest.json +5 -0
  65. package/src/styles.css +43 -0
  66. package/src/types/ai-coach.ts +25 -0
  67. package/src/types/bookmarks.ts +20 -0
  68. package/src/types/bundle.ts +119 -0
  69. package/src/types/common.ts +24 -0
  70. package/src/types/course.ts +135 -0
  71. package/src/types/enrollment.ts +35 -0
  72. package/{dist/types/index.d.ts → src/types/index.ts} +0 -1
  73. package/src/types/lesson.ts +106 -0
  74. package/src/types/manual-review.ts +116 -0
  75. package/src/types/messaging.ts +109 -0
  76. package/src/types/notification.ts +30 -0
  77. package/src/types/payment.ts +40 -0
  78. package/src/types/progress.ts +19 -0
  79. package/src/types/rating.ts +20 -0
  80. package/src/types/search.ts +31 -0
  81. package/src/types/user.ts +16 -0
  82. package/src/utils/formatters.ts +74 -0
  83. package/src/utils/index.ts +8 -0
  84. package/dist/components/atoms/Avatar.d.ts +0 -9
  85. package/dist/components/atoms/Avatar.d.ts.map +0 -1
  86. package/dist/components/atoms/Badge.d.ts +0 -10
  87. package/dist/components/atoms/Badge.d.ts.map +0 -1
  88. package/dist/components/atoms/Button.d.ts +0 -11
  89. package/dist/components/atoms/Button.d.ts.map +0 -1
  90. package/dist/components/atoms/Card.d.ts +0 -11
  91. package/dist/components/atoms/Card.d.ts.map +0 -1
  92. package/dist/components/atoms/Input.d.ts +0 -7
  93. package/dist/components/atoms/Input.d.ts.map +0 -1
  94. package/dist/components/atoms/ProgressBar.d.ts +0 -11
  95. package/dist/components/atoms/ProgressBar.d.ts.map +0 -1
  96. package/dist/components/atoms/Tabs.d.ts +0 -16
  97. package/dist/components/atoms/Tabs.d.ts.map +0 -1
  98. package/dist/components/atoms/index.cjs +0 -318
  99. package/dist/components/atoms/index.d.ts.map +0 -1
  100. package/dist/components/atoms/index.js +0 -288
  101. package/dist/components/index.cjs +0 -1275
  102. package/dist/components/index.d.ts.map +0 -1
  103. package/dist/components/index.js +0 -1245
  104. package/dist/components/molecules/CourseCard.d.ts +0 -25
  105. package/dist/components/molecules/CourseCard.d.ts.map +0 -1
  106. package/dist/components/molecules/EmptyState.d.ts +0 -10
  107. package/dist/components/molecules/EmptyState.d.ts.map +0 -1
  108. package/dist/components/molecules/LoadingSpinner.d.ts +0 -7
  109. package/dist/components/molecules/LoadingSpinner.d.ts.map +0 -1
  110. package/dist/components/molecules/PageHeader.d.ts +0 -8
  111. package/dist/components/molecules/PageHeader.d.ts.map +0 -1
  112. package/dist/components/molecules/Pagination.d.ts +0 -13
  113. package/dist/components/molecules/Pagination.d.ts.map +0 -1
  114. package/dist/components/molecules/SearchInput.d.ts +0 -8
  115. package/dist/components/molecules/SearchInput.d.ts.map +0 -1
  116. package/dist/components/molecules/index.cjs +0 -334
  117. package/dist/components/molecules/index.d.ts.map +0 -1
  118. package/dist/components/molecules/index.js +0 -311
  119. package/dist/components/organisms/CourseSidebar.d.ts +0 -37
  120. package/dist/components/organisms/CourseSidebar.d.ts.map +0 -1
  121. package/dist/components/organisms/LearnerNavbar.d.ts +0 -8
  122. package/dist/components/organisms/LearnerNavbar.d.ts.map +0 -1
  123. package/dist/components/organisms/LearnerSidebar.d.ts +0 -16
  124. package/dist/components/organisms/LearnerSidebar.d.ts.map +0 -1
  125. package/dist/components/organisms/LessonBookmarks.d.ts +0 -8
  126. package/dist/components/organisms/LessonBookmarks.d.ts.map +0 -1
  127. package/dist/components/organisms/LessonNotes.d.ts +0 -8
  128. package/dist/components/organisms/LessonNotes.d.ts.map +0 -1
  129. package/dist/components/organisms/index.cjs +0 -855
  130. package/dist/components/organisms/index.d.ts.map +0 -1
  131. package/dist/components/organisms/index.js +0 -825
  132. package/dist/components/pages/BundleDetailPage.d.ts +0 -3
  133. package/dist/components/pages/BundleDetailPage.d.ts.map +0 -1
  134. package/dist/components/pages/CatalogBundlesPage.d.ts +0 -3
  135. package/dist/components/pages/CatalogBundlesPage.d.ts.map +0 -1
  136. package/dist/components/pages/CatalogCoursesPage.d.ts +0 -3
  137. package/dist/components/pages/CatalogCoursesPage.d.ts.map +0 -1
  138. package/dist/components/pages/CourseDetailPage.d.ts +0 -3
  139. package/dist/components/pages/CourseDetailPage.d.ts.map +0 -1
  140. package/dist/components/pages/CoursePlayerPage.d.ts +0 -8
  141. package/dist/components/pages/CoursePlayerPage.d.ts.map +0 -1
  142. package/dist/components/pages/CreatorProfilePage.d.ts +0 -3
  143. package/dist/components/pages/CreatorProfilePage.d.ts.map +0 -1
  144. package/dist/components/pages/LearnerSettingsPage.d.ts +0 -3
  145. package/dist/components/pages/LearnerSettingsPage.d.ts.map +0 -1
  146. package/dist/components/pages/ManualReviewDetailPage.d.ts +0 -3
  147. package/dist/components/pages/ManualReviewDetailPage.d.ts.map +0 -1
  148. package/dist/components/pages/ManualReviewPage.d.ts +0 -3
  149. package/dist/components/pages/ManualReviewPage.d.ts.map +0 -1
  150. package/dist/components/pages/MessagesPage.d.ts +0 -3
  151. package/dist/components/pages/MessagesPage.d.ts.map +0 -1
  152. package/dist/components/pages/MyLearningPage.d.ts +0 -3
  153. package/dist/components/pages/MyLearningPage.d.ts.map +0 -1
  154. package/dist/components/pages/PaymentCancelPage.d.ts +0 -3
  155. package/dist/components/pages/PaymentCancelPage.d.ts.map +0 -1
  156. package/dist/components/pages/PaymentSuccessPage.d.ts +0 -3
  157. package/dist/components/pages/PaymentSuccessPage.d.ts.map +0 -1
  158. package/dist/components/pages/index.cjs +0 -3306
  159. package/dist/components/pages/index.d.ts.map +0 -1
  160. package/dist/components/pages/index.js +0 -3315
  161. package/dist/components/utils.d.ts +0 -3
  162. package/dist/components/utils.d.ts.map +0 -1
  163. package/dist/contracts/components.contract.d.ts +0 -87
  164. package/dist/contracts/components.contract.d.ts.map +0 -1
  165. package/dist/contracts/index.cjs +0 -52
  166. package/dist/contracts/index.d.ts.map +0 -1
  167. package/dist/contracts/index.js +0 -29
  168. package/dist/contracts/layout.contract.d.ts +0 -35
  169. package/dist/contracts/layout.contract.d.ts.map +0 -1
  170. package/dist/contracts/pages.contract.d.ts +0 -192
  171. package/dist/contracts/pages.contract.d.ts.map +0 -1
  172. package/dist/contracts/template.contract.d.ts +0 -49
  173. package/dist/contracts/template.contract.d.ts.map +0 -1
  174. package/dist/hooks/index.cjs +0 -165
  175. package/dist/hooks/index.d.ts.map +0 -1
  176. package/dist/hooks/index.js +0 -142
  177. package/dist/hooks/sdk-context.d.ts +0 -125
  178. package/dist/hooks/sdk-context.d.ts.map +0 -1
  179. package/dist/hooks/useAiCoach.d.ts +0 -32
  180. package/dist/hooks/useAiCoach.d.ts.map +0 -1
  181. package/dist/hooks/useBookmarks.d.ts +0 -31
  182. package/dist/hooks/useBookmarks.d.ts.map +0 -1
  183. package/dist/hooks/useCourseSearch.d.ts.map +0 -1
  184. package/dist/hooks/useDebounce.d.ts.map +0 -1
  185. package/dist/hooks/useMyBundles.d.ts.map +0 -1
  186. package/dist/hooks/useMyCourses.d.ts.map +0 -1
  187. package/dist/hooks/useNotes.d.ts +0 -31
  188. package/dist/hooks/useNotes.d.ts.map +0 -1
  189. package/dist/hooks/useNotifications.d.ts +0 -19
  190. package/dist/hooks/useNotifications.d.ts.map +0 -1
  191. package/dist/hooks/useTheme.d.ts.map +0 -1
  192. package/dist/hooks/useToast.d.ts +0 -17
  193. package/dist/hooks/useToast.d.ts.map +0 -1
  194. package/dist/hooks/useUser.d.ts.map +0 -1
  195. package/dist/index.cjs +0 -630
  196. package/dist/index.d.ts +0 -17
  197. package/dist/index.d.ts.map +0 -1
  198. package/dist/index.js +0 -600
  199. package/dist/layouts/DefaultLayout.d.ts +0 -9
  200. package/dist/layouts/DefaultLayout.d.ts.map +0 -1
  201. package/dist/types/ai-coach.d.ts +0 -22
  202. package/dist/types/ai-coach.d.ts.map +0 -1
  203. package/dist/types/bookmarks.d.ts +0 -19
  204. package/dist/types/bookmarks.d.ts.map +0 -1
  205. package/dist/types/bundle.d.ts +0 -114
  206. package/dist/types/bundle.d.ts.map +0 -1
  207. package/dist/types/common.d.ts +0 -23
  208. package/dist/types/common.d.ts.map +0 -1
  209. package/dist/types/course.d.ts +0 -127
  210. package/dist/types/course.d.ts.map +0 -1
  211. package/dist/types/enrollment.d.ts +0 -34
  212. package/dist/types/enrollment.d.ts.map +0 -1
  213. package/dist/types/index.cjs +0 -18
  214. package/dist/types/index.d.ts.map +0 -1
  215. package/dist/types/index.js +0 -0
  216. package/dist/types/lesson.d.ts +0 -105
  217. package/dist/types/lesson.d.ts.map +0 -1
  218. package/dist/types/manual-review.d.ts +0 -123
  219. package/dist/types/manual-review.d.ts.map +0 -1
  220. package/dist/types/messaging.d.ts +0 -101
  221. package/dist/types/messaging.d.ts.map +0 -1
  222. package/dist/types/notification.d.ts +0 -28
  223. package/dist/types/notification.d.ts.map +0 -1
  224. package/dist/types/payment.d.ts +0 -38
  225. package/dist/types/payment.d.ts.map +0 -1
  226. package/dist/types/progress.d.ts +0 -18
  227. package/dist/types/progress.d.ts.map +0 -1
  228. package/dist/types/rating.d.ts +0 -20
  229. package/dist/types/rating.d.ts.map +0 -1
  230. package/dist/types/search.d.ts +0 -28
  231. package/dist/types/search.d.ts.map +0 -1
  232. package/dist/types/user.d.ts +0 -15
  233. package/dist/types/user.d.ts.map +0 -1
  234. package/dist/utils/formatters.d.ts +0 -25
  235. package/dist/utils/formatters.d.ts.map +0 -1
  236. package/dist/utils/index.cjs +0 -80
  237. package/dist/utils/index.d.ts +0 -2
  238. package/dist/utils/index.d.ts.map +0 -1
  239. package/dist/utils/index.js +0 -57
@@ -0,0 +1,152 @@
1
+ 'use client';
2
+
3
+ import { createContext, useContext, type ReactNode } from 'react';
4
+ import type { User, Membership } from '../types';
5
+
6
+ /**
7
+ * SDK Hook implementations provided by the platform.
8
+ * Template developers don't interact with this directly — they use the individual hooks.
9
+ */
10
+ export interface SDKHookImplementations {
11
+ // User & Auth
12
+ useUser: () => { user: User | null; isAuthenticated: boolean; memberships: Membership[] };
13
+ useLogout: () => { logout: () => void };
14
+
15
+ // My Learning
16
+ useMyCourses: (status?: string, page?: number, limit?: number) => {
17
+ courses: any[];
18
+ meta: any | null;
19
+ isLoading: boolean;
20
+ };
21
+ useMyBundles: (status?: string, page?: number, limit?: number, search?: string) => {
22
+ bundles: any[];
23
+ meta: any | null;
24
+ isLoading: boolean;
25
+ };
26
+
27
+ // Search
28
+ useCourseSearch: (query: string) => {
29
+ results: any | null;
30
+ isSearching: boolean;
31
+ };
32
+
33
+ // Notes
34
+ useLessonNotes: (activityId: string) => {
35
+ data: any[];
36
+ isLoading: boolean;
37
+ error: Error | null;
38
+ refetch: () => Promise<void>;
39
+ };
40
+ useCreateNote: () => {
41
+ createNote: (payload: any) => Promise<any>;
42
+ isLoading: boolean;
43
+ };
44
+ useUpdateNote: () => {
45
+ updateNote: (noteId: string, payload: any) => Promise<any>;
46
+ isLoading: boolean;
47
+ };
48
+ useDeleteNote: () => {
49
+ deleteNote: (noteId: string) => Promise<boolean>;
50
+ isLoading: boolean;
51
+ };
52
+
53
+ // Bookmarks
54
+ useLessonBookmarks: (activityId: string) => {
55
+ data: any[];
56
+ isLoading: boolean;
57
+ error: Error | null;
58
+ refetch: () => Promise<void>;
59
+ };
60
+ useCreateBookmark: () => {
61
+ createBookmark: (payload: any) => Promise<any>;
62
+ isLoading: boolean;
63
+ };
64
+ useUpdateBookmark: () => {
65
+ updateBookmark: (id: string, payload: any) => Promise<any>;
66
+ isLoading: boolean;
67
+ };
68
+ useDeleteBookmark: () => {
69
+ deleteBookmark: (id: string) => Promise<boolean>;
70
+ isLoading: boolean;
71
+ };
72
+
73
+ // AI Coach
74
+ useAiCoachAvailability: (courseId?: string | null) => {
75
+ loading: boolean;
76
+ active: boolean;
77
+ coach: any | null;
78
+ error: Error | null;
79
+ };
80
+ useAiCoachChat: (courseId: string | null | undefined) => {
81
+ messages: any[];
82
+ threadId: string | null;
83
+ isStreaming: boolean;
84
+ error: Error | null;
85
+ sendMessage: (text: string) => Promise<void>;
86
+ stopStreaming: () => void;
87
+ };
88
+ useAiCoachHistory: (courseId: string | null | undefined, enabled: boolean) => {
89
+ loading: boolean;
90
+ threadId: string | null;
91
+ messages: any[];
92
+ groupedHistory: any[];
93
+ hasMore: boolean;
94
+ loadMore: () => Promise<void>;
95
+ };
96
+
97
+ // Notifications
98
+ useNotifications: () => {
99
+ notifications: any[];
100
+ unreadCount: number;
101
+ isLoading: boolean;
102
+ isLoadingMore: boolean;
103
+ hasMore: boolean;
104
+ loadMore: () => void;
105
+ refresh: () => void;
106
+ markConversationRead: (conversationId: string) => Promise<void>;
107
+ };
108
+
109
+ // Theme
110
+ useTheme: () => {
111
+ theme: string;
112
+ setTheme: (theme: string) => void;
113
+ };
114
+
115
+ // Debounce utility hook
116
+ useDebounce: <T>(value: T, delay: number) => T;
117
+
118
+ // Toast notifications
119
+ useToast: () => {
120
+ toast: (props: { title?: string; description?: string; variant?: 'default' | 'destructive' }) => void;
121
+ };
122
+ }
123
+
124
+ const SDKContext = createContext<SDKHookImplementations | null>(null);
125
+
126
+ export interface SDKProviderProps {
127
+ implementations: SDKHookImplementations;
128
+ children: ReactNode;
129
+ }
130
+
131
+ /**
132
+ * SDKProvider wraps learner routes and provides hook implementations.
133
+ * Used by the platform internally — template developers don't need this.
134
+ */
135
+ export function SDKProvider({ implementations, children }: SDKProviderProps) {
136
+ return <SDKContext.Provider value={implementations}>{children}</SDKContext.Provider>;
137
+ }
138
+
139
+ /**
140
+ * Internal hook to access SDK implementations.
141
+ * @internal
142
+ */
143
+ export function useSDK(): SDKHookImplementations {
144
+ const ctx = useContext(SDKContext);
145
+ if (!ctx) {
146
+ throw new Error(
147
+ 'useSDK must be used within an SDKProvider. ' +
148
+ 'Make sure your learner routes are wrapped with <SDKProvider>.'
149
+ );
150
+ }
151
+ return ctx;
152
+ }
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
5
+ /**
6
+ * Check if AI Coach is available for a course.
7
+ */
8
+ export function useAiCoachAvailability(courseId?: string | null) {
9
+ const sdk = useSDK();
10
+ return sdk.useAiCoachAvailability(courseId);
11
+ }
12
+
13
+ /**
14
+ * Chat with the AI Coach.
15
+ */
16
+ export function useAiCoachChat(courseId: string | null | undefined) {
17
+ const sdk = useSDK();
18
+ return sdk.useAiCoachChat(courseId);
19
+ }
20
+
21
+ /**
22
+ * Get AI Coach chat history.
23
+ */
24
+ export function useAiCoachHistory(courseId: string | null | undefined, enabled: boolean) {
25
+ const sdk = useSDK();
26
+ return sdk.useAiCoachHistory(courseId, enabled);
27
+ }
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
5
+ /**
6
+ * Fetch bookmarks for a lesson/activity.
7
+ */
8
+ export function useLessonBookmarks(activityId: string) {
9
+ const sdk = useSDK();
10
+ return sdk.useLessonBookmarks(activityId);
11
+ }
12
+
13
+ /**
14
+ * Create a new bookmark.
15
+ */
16
+ export function useCreateBookmark() {
17
+ const sdk = useSDK();
18
+ return sdk.useCreateBookmark();
19
+ }
20
+
21
+ /**
22
+ * Update an existing bookmark.
23
+ */
24
+ export function useUpdateBookmark() {
25
+ const sdk = useSDK();
26
+ return sdk.useUpdateBookmark();
27
+ }
28
+
29
+ /**
30
+ * Delete a bookmark.
31
+ */
32
+ export function useDeleteBookmark() {
33
+ const sdk = useSDK();
34
+ return sdk.useDeleteBookmark();
35
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Search enrolled courses.
3
7
  *
@@ -8,8 +12,7 @@
8
12
  * const { results, isSearching } = useCourseSearch(debouncedQuery);
9
13
  * ```
10
14
  */
11
- export declare function useCourseSearch(query: string): {
12
- results: any | null;
13
- isSearching: boolean;
14
- };
15
- //# sourceMappingURL=useCourseSearch.d.ts.map
15
+ export function useCourseSearch(query: string) {
16
+ const sdk = useSDK();
17
+ return sdk.useCourseSearch(query);
18
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Debounce a value.
3
7
  *
@@ -9,5 +13,7 @@
9
13
  * const debouncedSearch = useDebounce(searchQuery, 500);
10
14
  * ```
11
15
  */
12
- export declare function useDebounce<T>(value: T, delay: number): T;
13
- //# sourceMappingURL=useDebounce.d.ts.map
16
+ export function useDebounce<T>(value: T, delay: number): T {
17
+ const sdk = useSDK();
18
+ return sdk.useDebounce(value, delay);
19
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Fetch the current user's enrolled bundles.
3
7
  *
@@ -11,9 +15,7 @@
11
15
  * const { bundles, meta, isLoading } = useMyBundles(undefined, 1, 12);
12
16
  * ```
13
17
  */
14
- export declare function useMyBundles(status?: string, page?: number, limit?: number, search?: string): {
15
- bundles: any[];
16
- meta: any | null;
17
- isLoading: boolean;
18
- };
19
- //# sourceMappingURL=useMyBundles.d.ts.map
18
+ export function useMyBundles(status?: string, page?: number, limit?: number, search?: string) {
19
+ const sdk = useSDK();
20
+ return sdk.useMyBundles(status, page, limit, search);
21
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Fetch the current user's enrolled courses.
3
7
  *
@@ -10,9 +14,7 @@
10
14
  * const { courses, meta, isLoading } = useMyCourses('IN_PROGRESS', 1, 12);
11
15
  * ```
12
16
  */
13
- export declare function useMyCourses(status?: string, page?: number, limit?: number): {
14
- courses: any[];
15
- meta: any | null;
16
- isLoading: boolean;
17
- };
18
- //# sourceMappingURL=useMyCourses.d.ts.map
17
+ export function useMyCourses(status?: string, page?: number, limit?: number) {
18
+ const sdk = useSDK();
19
+ return sdk.useMyCourses(status, page, limit);
20
+ }
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
5
+ /**
6
+ * Fetch notes for a lesson/activity.
7
+ */
8
+ export function useLessonNotes(activityId: string) {
9
+ const sdk = useSDK();
10
+ return sdk.useLessonNotes(activityId);
11
+ }
12
+
13
+ /**
14
+ * Create a new note.
15
+ */
16
+ export function useCreateNote() {
17
+ const sdk = useSDK();
18
+ return sdk.useCreateNote();
19
+ }
20
+
21
+ /**
22
+ * Update an existing note.
23
+ */
24
+ export function useUpdateNote() {
25
+ const sdk = useSDK();
26
+ return sdk.useUpdateNote();
27
+ }
28
+
29
+ /**
30
+ * Delete a note.
31
+ */
32
+ export function useDeleteNote() {
33
+ const sdk = useSDK();
34
+ return sdk.useDeleteNote();
35
+ }
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
5
+ /**
6
+ * Manage notifications (message notifications).
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const { notifications, unreadCount, markConversationRead } = useNotifications();
11
+ * ```
12
+ */
13
+ export function useNotifications() {
14
+ const sdk = useSDK();
15
+ return sdk.useNotifications();
16
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Access and change the current theme.
3
7
  *
@@ -7,8 +11,7 @@
7
11
  * return <button onClick={() => setTheme('dark')}>Dark Mode</button>;
8
12
  * ```
9
13
  */
10
- export declare function useTheme(): {
11
- theme: string;
12
- setTheme: (theme: string) => void;
13
- };
14
- //# sourceMappingURL=useTheme.d.ts.map
14
+ export function useTheme() {
15
+ const sdk = useSDK();
16
+ return sdk.useTheme();
17
+ }
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
5
+ /**
6
+ * Show toast notifications.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * const { toast } = useToast();
11
+ * toast({ title: 'Success', description: 'Course enrolled!' });
12
+ * ```
13
+ */
14
+ export function useToast() {
15
+ const sdk = useSDK();
16
+ return sdk.useToast();
17
+ }
@@ -1,3 +1,7 @@
1
+ 'use client';
2
+
3
+ import { useSDK } from './sdk-context';
4
+
1
5
  /**
2
6
  * Get the current authenticated user.
3
7
  *
@@ -9,11 +13,11 @@
9
13
  * }
10
14
  * ```
11
15
  */
12
- export declare function useUser(): {
13
- user: import("..").User | null;
14
- isAuthenticated: boolean;
15
- memberships: import("..").Membership[];
16
- };
16
+ export function useUser() {
17
+ const sdk = useSDK();
18
+ return sdk.useUser();
19
+ }
20
+
17
21
  /**
18
22
  * Get the logout function.
19
23
  *
@@ -23,7 +27,7 @@ export declare function useUser(): {
23
27
  * return <button onClick={logout}>Log out</button>;
24
28
  * ```
25
29
  */
26
- export declare function useLogout(): {
27
- logout: () => void;
28
- };
29
- //# sourceMappingURL=useUser.d.ts.map
30
+ export function useLogout() {
31
+ const sdk = useSDK();
32
+ return sdk.useLogout();
33
+ }
package/src/index.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @academy/sdk
3
+ *
4
+ * SDK for building custom learner templates for the Academy platform.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useMyCourses, useUser } from '@academy/sdk';
9
+ * import type { MyLearningPageProps, TemplateManifest } from '@academy/sdk';
10
+ * ```
11
+ */
12
+
13
+ // Types
14
+ export * from './types';
15
+
16
+ // Hooks
17
+ export * from './hooks';
18
+
19
+ // Contracts
20
+ export * from './contracts';
21
+
22
+ // Utilities
23
+ export * from './utils';
24
+
25
+ // Layouts
26
+ export { DefaultLayout } from './layouts/DefaultLayout';
27
+
28
+ // Components are available via sub-path imports:
29
+ // import { Button, Card } from '@academy/sdk/components/atoms';
30
+ // import { CourseCard, Pagination } from '@academy/sdk/components/molecules';
31
+ // import { LearnerNavbar, LearnerSidebar } from '@academy/sdk/components/organisms';
32
+ // import { MyLearningPage, CatalogCoursesPage } from '@academy/sdk/components/pages';
33
+ // Or import all: import { Button, CourseCard } from '@academy/sdk/components';
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+
3
+ import { useState, type ReactNode } from 'react';
4
+ import { LearnerNavbar } from '../components/organisms/LearnerNavbar';
5
+ import { LearnerSidebar } from '../components/organisms/LearnerSidebar';
6
+
7
+ interface DefaultLayoutProps {
8
+ children: ReactNode;
9
+ currentPath?: string;
10
+ onNavigate?: (path: string) => void;
11
+ }
12
+
13
+ export function DefaultLayout({ children, currentPath = '/my-learning', onNavigate }: DefaultLayoutProps) {
14
+ const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
15
+ const [sidebarOpen, setSidebarOpen] = useState(false);
16
+
17
+ return (
18
+ <div className="min-h-screen bg-theme-bg-primary">
19
+ {/* Fixed Navbar */}
20
+ <div style={{ position: 'fixed', top: 'var(--preview-toolbar-h, 0px)', left: 0, right: 0, zIndex: 40 }}>
21
+ <LearnerNavbar
22
+ onMenuClick={() => {
23
+ if (typeof window !== 'undefined' && window.innerWidth >= 1024) {
24
+ setSidebarCollapsed(c => !c);
25
+ } else {
26
+ setSidebarOpen(o => !o);
27
+ }
28
+ }}
29
+ />
30
+ </div>
31
+
32
+ {/* Content below navbar (h-20 = 80px) + preview toolbar offset */}
33
+ <div style={{ paddingTop: 'calc(80px + var(--preview-toolbar-h, 0px))', display: 'flex', minHeight: '100vh' }}>
34
+ {/* Sidebar */}
35
+ <LearnerSidebar
36
+ currentPath={currentPath}
37
+ isCollapsed={sidebarCollapsed}
38
+ isOpen={sidebarOpen}
39
+ onClose={() => setSidebarOpen(false)}
40
+ onToggle={() => setSidebarCollapsed(c => !c)}
41
+ onNavigate={onNavigate ?? (() => {})}
42
+ />
43
+
44
+ {/* Main content */}
45
+ <main
46
+ style={{
47
+ flex: 1,
48
+ minWidth: 0,
49
+ transition: 'margin-left 0.3s',
50
+ }}
51
+ className="px-4 sm:px-6 lg:px-8 py-6"
52
+ >
53
+ {children}
54
+ </main>
55
+ </div>
56
+ </div>
57
+ );
58
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@academy-sdk/sdk",
3
+ "version": "1.0.0",
4
+ "description": "SDK for building custom learner templates for the Academy platform"
5
+ }
package/src/styles.css ADDED
@@ -0,0 +1,43 @@
1
+ @import "tailwindcss";
2
+
3
+ /* Tell Tailwind v4 where to scan for class names */
4
+ @source "../src/**/*.{tsx,ts,js,jsx}";
5
+
6
+ /* Mirror the host app's @theme mappings so custom Tailwind utilities work */
7
+ @theme {
8
+ /* Background colors */
9
+ --color-theme-bg-primary: rgb(var(--bg-primary));
10
+ --color-theme-bg-secondary: rgb(var(--bg-secondary));
11
+ --color-theme-bg-tertiary: rgb(var(--bg-tertiary));
12
+
13
+ /* Text colors */
14
+ --color-theme-text-primary: rgb(var(--text-primary));
15
+ --color-theme-text-secondary: rgb(var(--text-secondary));
16
+ --color-theme-text-muted: rgb(var(--text-muted));
17
+
18
+ /* Border colors */
19
+ --color-theme-border-primary: rgb(var(--border-primary));
20
+
21
+ /* Accent colors */
22
+ --color-theme-accent-primary: rgb(var(--accent-primary));
23
+ --color-theme-accent-secondary: rgb(var(--accent-secondary));
24
+
25
+ /* Marketing success stats gradient */
26
+ --color-theme-success-gradient-from: rgb(var(--success-gradient-from));
27
+ --color-theme-success-gradient-to: rgb(var(--success-gradient-to));
28
+ }
29
+
30
+ /* Default (light) theme — fallback when host doesn't inject theme variables */
31
+ :root {
32
+ --bg-primary: 249 250 251;
33
+ --bg-secondary: 255 255 255;
34
+ --bg-tertiary: 243 244 246;
35
+ --text-primary: 17 24 39;
36
+ --text-secondary: 75 85 99;
37
+ --text-muted: 156 163 175;
38
+ --border-primary: 229 231 235;
39
+ --accent-primary: 73 187 189;
40
+ --accent-secondary: 73 187 189;
41
+ --success-gradient-from: 19 108 181;
42
+ --success-gradient-to: 73 187 189;
43
+ }
@@ -0,0 +1,25 @@
1
+ export type ChatRole = 'user' | 'assistant';
2
+
3
+ export interface ChatMessage {
4
+ id: string;
5
+ role: ChatRole;
6
+ content: string;
7
+ createdAt: number;
8
+ isStreaming?: boolean;
9
+ sources?: unknown[];
10
+ }
11
+
12
+ export interface AICoachInfo {
13
+ id: string;
14
+ name: string;
15
+ }
16
+
17
+ export interface AICoachAvailability {
18
+ active: boolean;
19
+ coach: AICoachInfo | null;
20
+ }
21
+
22
+ export interface AICoachHistoryGroup {
23
+ date: string;
24
+ messages: ChatMessage[];
25
+ }
@@ -0,0 +1,20 @@
1
+ export interface Bookmark {
2
+ id: string;
3
+ activityId: string;
4
+ userId: string;
5
+ second: number;
6
+ label?: string;
7
+ createdAt: string;
8
+ updatedAt: string;
9
+ }
10
+
11
+ export interface CreateBookmarkPayload {
12
+ activityId: string;
13
+ second: number;
14
+ label?: string;
15
+ }
16
+
17
+ export interface UpdateBookmarkPayload {
18
+ second?: number;
19
+ label?: string;
20
+ }