@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
@@ -11,4 +11,3 @@ export { LearnerSettingsPage } from './LearnerSettingsPage';
11
11
  export { PaymentSuccessPage } from './PaymentSuccessPage';
12
12
  export { PaymentCancelPage } from './PaymentCancelPage';
13
13
  export { CreatorProfilePage } from './CreatorProfilePage';
14
- //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,89 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Props for a course card component (used in grids/lists)
5
+ */
6
+ export interface CourseCardProps {
7
+ id: string;
8
+ title: string;
9
+ thumbnail?: string;
10
+ thumbnails?: string[];
11
+ totalLessons: number;
12
+ progress: number;
13
+ status?: 'in-progress' | 'completed';
14
+ isFree: boolean;
15
+ price?: number;
16
+ currency?: string;
17
+ description?: string;
18
+ showPrice?: boolean;
19
+ showProgress?: boolean;
20
+ category?: string;
21
+ duration?: string;
22
+ instructorName?: string;
23
+ instructorAvatar?: string;
24
+ originalPrice?: number;
25
+ isBundle?: boolean;
26
+ onClick?: () => void;
27
+ }
28
+
29
+ /**
30
+ * Props for a video player component
31
+ */
32
+ export interface VideoPlayerProps {
33
+ videoUrl: string;
34
+ provider?: 'YOUTUBE' | 'VIMEO' | 'LOOM' | 'OTHERS';
35
+ startTime?: number;
36
+ onReady?: (player: any) => void;
37
+ onPlay?: () => void;
38
+ onPause?: () => void;
39
+ onEnd?: () => void;
40
+ onStateChange?: (event: any) => void;
41
+ }
42
+
43
+ /**
44
+ * Props for pagination component
45
+ */
46
+ export interface PaginationComponentProps {
47
+ currentPage: number;
48
+ totalPages: number;
49
+ total: number;
50
+ pageSize: number;
51
+ hasNextPage: boolean;
52
+ hasPreviousPage: boolean;
53
+ onPageChange: (page: number) => void;
54
+ maxVisiblePages?: number;
55
+ }
56
+
57
+ /**
58
+ * Props for a page header component
59
+ */
60
+ export interface PageHeaderProps {
61
+ title: string;
62
+ description?: string;
63
+ className?: string;
64
+ }
65
+
66
+ /**
67
+ * Props for search results view
68
+ */
69
+ export interface SearchResultsViewProps {
70
+ results: any;
71
+ isSearching: boolean;
72
+ searchQuery: string;
73
+ onCourseClick: (courseId: string, enrollmentId?: string) => void;
74
+ onLessonClick: (courseId: string, lessonId: string) => void;
75
+ }
76
+
77
+ /**
78
+ * Props for the learner sidebar component override
79
+ */
80
+ export interface LearnerSidebarComponentProps {
81
+ isOpen: boolean;
82
+ isCollapsed: boolean;
83
+ onClose: () => void;
84
+ onToggle: () => void;
85
+ currentPath: string;
86
+ onNavigate: (href: string) => void;
87
+ user: { name: string; email: string; avatar?: string } | null;
88
+ onLogout: () => void;
89
+ }
@@ -2,4 +2,3 @@ export * from './layout.contract';
2
2
  export * from './pages.contract';
3
3
  export * from './components.contract';
4
4
  export * from './template.contract';
5
- //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,36 @@
1
+ import type { ReactNode } from 'react';
2
+ import type { User, Membership } from '../types';
3
+
4
+ /**
5
+ * Props for the top-level learner layout wrapper.
6
+ * The template's layout receives these and renders navbar + sidebar + content.
7
+ */
8
+ export interface LearnerLayoutProps {
9
+ children: ReactNode;
10
+ /** Current authenticated user */
11
+ user: User | null;
12
+ /** User's memberships */
13
+ memberships: Membership[];
14
+ /** Whether sidebar is open (mobile) */
15
+ sidebarOpen: boolean;
16
+ /** Whether sidebar is collapsed (desktop) */
17
+ sidebarCollapsed: boolean;
18
+ /** Toggle sidebar open/close */
19
+ onToggleSidebar: () => void;
20
+ /** Close sidebar (mobile) */
21
+ onCloseSidebar: () => void;
22
+ /** Logout handler */
23
+ onLogout: () => void;
24
+ /** Current pathname for active link highlighting */
25
+ pathname: string;
26
+ }
27
+
28
+ /**
29
+ * Navigation item for the sidebar
30
+ */
31
+ export interface SidebarNavItem {
32
+ label: string;
33
+ href: string;
34
+ icon: string;
35
+ badge?: number;
36
+ }
@@ -0,0 +1,275 @@
1
+ import type { ReactNode } from 'react';
2
+ import type {
3
+ Course,
4
+ CoursePlayerCourse,
5
+ CoursePlayerModule,
6
+ Bundle,
7
+ LearnerBundle,
8
+ LearnerBundleCourse,
9
+ SearchCourse,
10
+ SearchResponse,
11
+ PaginationMeta,
12
+ User,
13
+ LearnerManualReviewSubmission,
14
+ LearnerManualReviewSummary,
15
+ LearnerManualReviewPagination,
16
+ LearnerManualReviewDetailResponse,
17
+ LearnerManualReviewStatus,
18
+ AICoachInfo,
19
+ Rating,
20
+ RatingSummary,
21
+ PaymentProvider,
22
+ Coupon,
23
+ ValidateCouponResponse,
24
+ LessonNote,
25
+ Bookmark,
26
+ FAQItem,
27
+ LessonResources,
28
+ TranscriptItem,
29
+ } from '../types';
30
+
31
+ // ─── My Learning Page ────────────────────────────────────────────
32
+ export interface MyLearningPageProps {
33
+ user: User | null;
34
+ // Courses tab
35
+ courses: any[];
36
+ coursesMeta: PaginationMeta | null;
37
+ coursesLoading: boolean;
38
+ coursesPage: number;
39
+ onCoursesPageChange: (page: number) => void;
40
+ // Bundles tab
41
+ bundles: any[];
42
+ bundlesMeta: PaginationMeta | null;
43
+ bundlesLoading: boolean;
44
+ bundlesPage: number;
45
+ onBundlesPageChange: (page: number) => void;
46
+ // Search
47
+ searchQuery: string;
48
+ onSearchChange: (query: string) => void;
49
+ searchResults: SearchResponse | null;
50
+ isSearching: boolean;
51
+ // Filters
52
+ activeTab: 'courses' | 'bundles';
53
+ onTabChange: (tab: 'courses' | 'bundles') => void;
54
+ statusFilter: string;
55
+ onStatusFilterChange: (status: string) => void;
56
+ // Navigation
57
+ onCourseClick: (courseId: string, enrollmentId?: string) => void;
58
+ onBundleClick: (bundleId: string) => void;
59
+ }
60
+
61
+ // ─── Catalog Courses Page ────────────────────────────────────────
62
+ export interface CatalogCoursesPageProps {
63
+ courses: Course[];
64
+ meta: PaginationMeta | null;
65
+ loading: boolean;
66
+ searchQuery: string;
67
+ page: number;
68
+ onSearchChange: (query: string) => void;
69
+ onPageChange: (page: number) => void;
70
+ onCourseClick: (courseId: string) => void;
71
+ }
72
+
73
+ // ─── Catalog Bundles Page ────────────────────────────────────────
74
+ export interface CatalogBundlesPageProps {
75
+ bundles: Bundle[];
76
+ meta: PaginationMeta | null;
77
+ loading: boolean;
78
+ searchQuery: string;
79
+ page: number;
80
+ onSearchChange: (query: string) => void;
81
+ onPageChange: (page: number) => void;
82
+ onBundleClick: (bundleId: string) => void;
83
+ }
84
+
85
+ // ─── Course Detail Page ──────────────────────────────────────────
86
+ export interface CourseDetailPageProps {
87
+ course: any | null;
88
+ isLoading: boolean;
89
+ notFound: boolean;
90
+ isEnrolled: boolean;
91
+ enrollmentId: string | null;
92
+ // Enrollment actions
93
+ onEnroll: () => Promise<void>;
94
+ onStartLearning: (enrollmentId: string) => void;
95
+ isProcessingEnrollment: boolean;
96
+ // Payment
97
+ paymentProviders: PaymentProvider[];
98
+ onCheckout: (providerId: string) => Promise<void>;
99
+ isProcessingCheckout: boolean;
100
+ // Coupons
101
+ couponCode: string;
102
+ onCouponCodeChange: (code: string) => void;
103
+ onApplyCoupon: () => Promise<void>;
104
+ appliedCoupon: Coupon | null;
105
+ couponError: string | null;
106
+ isApplyingCoupon: boolean;
107
+ discountedPrice: number | undefined;
108
+ // Tabs
109
+ activeTab: 'overview' | 'curriculum';
110
+ onTabChange: (tab: 'overview' | 'curriculum') => void;
111
+ // Related courses
112
+ relatedCourses: any[];
113
+ isRelatedLoading: boolean;
114
+ onRelatedCourseClick: (courseId: string) => void;
115
+ // Ratings
116
+ ratings?: Rating[];
117
+ ratingSummary?: RatingSummary;
118
+ }
119
+
120
+ // ─── Bundle Detail Page ──────────────────────────────────────────
121
+ export interface BundleDetailPageProps {
122
+ bundle: LearnerBundle | null;
123
+ isLoading: boolean;
124
+ notFound: boolean;
125
+ isEnrolled: boolean;
126
+ // Enrollment
127
+ onEnroll: () => Promise<void>;
128
+ isProcessingEnrollment: boolean;
129
+ // Payment
130
+ paymentProviders: PaymentProvider[];
131
+ onCheckout: (providerId: string) => Promise<void>;
132
+ isProcessingCheckout: boolean;
133
+ // Coupons
134
+ couponCode: string;
135
+ onCouponCodeChange: (code: string) => void;
136
+ onApplyCoupon: () => Promise<void>;
137
+ appliedCoupon: Coupon | null;
138
+ couponError: string | null;
139
+ // Course list
140
+ onCourseClick: (courseId: string, enrollmentId?: string) => void;
141
+ }
142
+
143
+ // ─── Course Player Page ──────────────────────────────────────────
144
+ export interface CoursePlayerPageProps {
145
+ // Course data
146
+ course: CoursePlayerCourse | null;
147
+ actualCourseId: string | null;
148
+ isLoading: boolean;
149
+ courseNotFound: boolean;
150
+ // Current lesson
151
+ currentLessonId: string;
152
+ currentModuleIndex: number;
153
+ currentLessonIndex: number;
154
+ // Module navigation
155
+ expandedModules: Set<string>;
156
+ onToggleModule: (moduleId: string) => void;
157
+ onSelectLesson: (lessonId: string) => void;
158
+ // Progress
159
+ completedCount: number;
160
+ totalCount: number;
161
+ isCompleted: boolean;
162
+ // Video
163
+ currentVideoTime: number;
164
+ isPlaying: boolean;
165
+ onVideoReady: (player: any) => void;
166
+ onVideoPlay: () => void;
167
+ onVideoPause: () => void;
168
+ onVideoEnd: () => void;
169
+ onVideoStateChange: (event: any) => void;
170
+ // Tabs
171
+ activeTab: string;
172
+ onTabChange: (tab: string) => void;
173
+ // Notes
174
+ notes: LessonNote[];
175
+ onCreateNote: (text: string, timestamp?: number) => Promise<void>;
176
+ onUpdateNote: (noteId: string, text: string) => Promise<void>;
177
+ onDeleteNote: (noteId: string) => Promise<void>;
178
+ // Bookmarks
179
+ bookmarks: Bookmark[];
180
+ onCreateBookmark: (second: number, label?: string) => Promise<void>;
181
+ onUpdateBookmark: (id: string, label: string) => Promise<void>;
182
+ onDeleteBookmark: (id: string) => Promise<void>;
183
+ // AI Coach
184
+ aiCoachAvailable: boolean;
185
+ aiCoachInfo: AICoachInfo | null;
186
+ // Certificate
187
+ certificateEnabled: boolean;
188
+ onDownloadCertificate: () => Promise<void>;
189
+ // Rating
190
+ showRatingModal: boolean;
191
+ onSubmitRating: (rating: number, review: string) => Promise<void>;
192
+ onCloseRatingModal: () => void;
193
+ // Slack
194
+ slackCommunityEnabled: boolean;
195
+ onJoinSlackChannel: () => Promise<void>;
196
+ // Mobile
197
+ isMobileSidebarOpen: boolean;
198
+ onToggleMobileSidebar: () => void;
199
+ // Get live video time (for notes/bookmarks)
200
+ getLiveCurrentTime: () => number;
201
+ }
202
+
203
+ // ─── Messages Page ───────────────────────────────────────────────
204
+ export interface MessagesPageProps {
205
+ conversations: any[];
206
+ isLoadingConversations: boolean;
207
+ selectedConversation: any | null;
208
+ onSelectConversation: (conv: any) => void;
209
+ messages: any[];
210
+ isLoadingMessages: boolean;
211
+ isLoadingMore: boolean;
212
+ hasMoreMessages: boolean;
213
+ onLoadMoreMessages: () => void;
214
+ onSendMessage: (content: string) => Promise<void>;
215
+ isSending: boolean;
216
+ searchQuery: string;
217
+ onSearchChange: (query: string) => void;
218
+ onDeleteMessage: (messageId: string) => void;
219
+ showNewMessageDialog: boolean;
220
+ onNewMessageDialogChange: (show: boolean) => void;
221
+ onNewMessage: (courseId: string, message: string, conversationId: string, courseName?: string) => void;
222
+ notifications: any[];
223
+ unreadCount: number;
224
+ mobileView: 'list' | 'chat';
225
+ onMobileViewChange: (view: 'list' | 'chat') => void;
226
+ currentUserId: string;
227
+ }
228
+
229
+ // ─── Manual Review Page ──────────────────────────────────────────
230
+ export interface ManualReviewPageProps {
231
+ submissions: LearnerManualReviewSubmission[];
232
+ summary: LearnerManualReviewSummary;
233
+ pagination: LearnerManualReviewPagination;
234
+ isLoading: boolean;
235
+ // Filters
236
+ filterStatus: LearnerManualReviewStatus | 'ALL';
237
+ onFilterStatusChange: (status: LearnerManualReviewStatus | 'ALL') => void;
238
+ searchQuery: string;
239
+ onSearchChange: (query: string) => void;
240
+ currentPage: number;
241
+ onPageChange: (page: number) => void;
242
+ // Navigation
243
+ onSubmissionClick: (submissionId: string) => void;
244
+ }
245
+
246
+ // ─── Manual Review Detail Page ───────────────────────────────────
247
+ export interface ManualReviewDetailPageProps {
248
+ submission: LearnerManualReviewDetailResponse | null;
249
+ isLoading: boolean;
250
+ notFound: boolean;
251
+ onBack: () => void;
252
+ }
253
+
254
+ // ─── Learner Settings Page ───────────────────────────────────────
255
+ export interface LearnerSettingsPageProps {
256
+ user: User | null;
257
+ }
258
+
259
+ // ─── Payment Result Pages ────────────────────────────────────────
260
+ export interface PaymentSuccessPageProps {
261
+ onContinueLearning: () => void;
262
+ }
263
+
264
+ export interface PaymentCancelPageProps {
265
+ onRetry: () => void;
266
+ onGoBack: () => void;
267
+ }
268
+
269
+ // ─── Creator Profile Page ────────────────────────────────────────
270
+ export interface CreatorProfilePageProps {
271
+ creator: any | null;
272
+ courses: Course[];
273
+ isLoading: boolean;
274
+ onCourseClick: (courseId: string) => void;
275
+ }
@@ -0,0 +1,100 @@
1
+ import type { ComponentType } from 'react';
2
+ import type { LearnerLayoutProps } from './layout.contract';
3
+ import type {
4
+ MyLearningPageProps,
5
+ CatalogCoursesPageProps,
6
+ CatalogBundlesPageProps,
7
+ CourseDetailPageProps,
8
+ BundleDetailPageProps,
9
+ CoursePlayerPageProps,
10
+ MessagesPageProps,
11
+ ManualReviewPageProps,
12
+ ManualReviewDetailPageProps,
13
+ LearnerSettingsPageProps,
14
+ PaymentSuccessPageProps,
15
+ PaymentCancelPageProps,
16
+ CreatorProfilePageProps,
17
+ } from './pages.contract';
18
+ import type {
19
+ CourseCardProps,
20
+ VideoPlayerProps,
21
+ PaginationComponentProps,
22
+ PageHeaderProps,
23
+ SearchResultsViewProps,
24
+ LearnerSidebarComponentProps,
25
+ } from './components.contract';
26
+
27
+ /**
28
+ * TemplateManifest defines the complete set of components a template must/can provide.
29
+ *
30
+ * Required: LearnerLayout + all page components
31
+ * Optional: component overrides (will fallback to platform defaults if not provided)
32
+ */
33
+ export interface TemplateManifest {
34
+ /** Unique template name (e.g., "@client/modern-template") */
35
+ name: string;
36
+ /** Template version (semver) */
37
+ version: string;
38
+
39
+ /** The root layout component wrapping all learner pages */
40
+ LearnerLayout: ComponentType<LearnerLayoutProps>;
41
+
42
+ /** Page components — one per learner route */
43
+ pages: {
44
+ MyLearningPage: ComponentType<Partial<MyLearningPageProps>>;
45
+ CatalogCoursesPage: ComponentType<Partial<CatalogCoursesPageProps>>;
46
+ CatalogBundlesPage: ComponentType<Partial<CatalogBundlesPageProps>>;
47
+ CourseDetailPage: ComponentType<Partial<CourseDetailPageProps>>;
48
+ BundleDetailPage: ComponentType<Partial<BundleDetailPageProps>>;
49
+ CoursePlayerPage: ComponentType<Partial<CoursePlayerPageProps>>;
50
+ MessagesPage: ComponentType<Partial<MessagesPageProps>>;
51
+ ManualReviewPage: ComponentType<Partial<ManualReviewPageProps>>;
52
+ ManualReviewDetailPage: ComponentType<Partial<ManualReviewDetailPageProps>>;
53
+ LearnerSettingsPage: ComponentType<Partial<LearnerSettingsPageProps>>;
54
+ PaymentSuccessPage: ComponentType<Partial<PaymentSuccessPageProps>>;
55
+ PaymentCancelPage: ComponentType<Partial<PaymentCancelPageProps>>;
56
+ CreatorProfilePage: ComponentType<Partial<CreatorProfilePageProps>>;
57
+ };
58
+
59
+ /** Optional component overrides — templates can provide custom implementations */
60
+ components?: {
61
+ CourseCard?: ComponentType<CourseCardProps>;
62
+ VideoPlayer?: ComponentType<VideoPlayerProps>;
63
+ Pagination?: ComponentType<PaginationComponentProps>;
64
+ PageHeader?: ComponentType<PageHeaderProps>;
65
+ SearchResultsView?: ComponentType<SearchResultsViewProps>;
66
+ LearnerSidebar?: ComponentType<LearnerSidebarComponentProps>;
67
+ };
68
+ }
69
+
70
+ /**
71
+ * Validates that a template manifest has all required fields.
72
+ * Throws an error if any required page is missing.
73
+ */
74
+ export function validateTemplateManifest(manifest: TemplateManifest): void {
75
+ if (!manifest.name) throw new Error('Template manifest must have a name');
76
+ if (!manifest.version) throw new Error('Template manifest must have a version');
77
+ if (!manifest.LearnerLayout) throw new Error('Template must provide LearnerLayout');
78
+
79
+ const requiredPages = [
80
+ 'MyLearningPage',
81
+ 'CatalogCoursesPage',
82
+ 'CatalogBundlesPage',
83
+ 'CourseDetailPage',
84
+ 'BundleDetailPage',
85
+ 'CoursePlayerPage',
86
+ 'MessagesPage',
87
+ 'ManualReviewPage',
88
+ 'ManualReviewDetailPage',
89
+ 'LearnerSettingsPage',
90
+ 'PaymentSuccessPage',
91
+ 'PaymentCancelPage',
92
+ 'CreatorProfilePage',
93
+ ] as const;
94
+
95
+ for (const page of requiredPages) {
96
+ if (!manifest.pages[page]) {
97
+ throw new Error(`Template must provide pages.${page}`);
98
+ }
99
+ }
100
+ }
@@ -0,0 +1,52 @@
1
+ import type { TemplateManifest } from './contracts';
2
+ import { validateTemplateManifest } from './contracts';
3
+ import manifest from './manifest.json';
4
+ import { DefaultLayout } from './layouts/DefaultLayout';
5
+ import {
6
+ MyLearningPage,
7
+ CatalogCoursesPage,
8
+ CatalogBundlesPage,
9
+ CourseDetailPage,
10
+ BundleDetailPage,
11
+ CoursePlayerPage,
12
+ MessagesPage,
13
+ ManualReviewPage,
14
+ ManualReviewDetailPage,
15
+ LearnerSettingsPage,
16
+ PaymentSuccessPage,
17
+ PaymentCancelPage,
18
+ CreatorProfilePage,
19
+ } from './components/pages';
20
+ import { CourseCard, Pagination, PageHeader } from './components/molecules';
21
+ import { LearnerSidebar } from './components/organisms';
22
+
23
+ const template: TemplateManifest = {
24
+ name: manifest.name,
25
+ version: manifest.version,
26
+ LearnerLayout: DefaultLayout,
27
+ pages: {
28
+ MyLearningPage,
29
+ CatalogCoursesPage,
30
+ CatalogBundlesPage,
31
+ CourseDetailPage,
32
+ BundleDetailPage,
33
+ CoursePlayerPage,
34
+ MessagesPage,
35
+ ManualReviewPage,
36
+ ManualReviewDetailPage,
37
+ LearnerSettingsPage,
38
+ PaymentSuccessPage,
39
+ PaymentCancelPage,
40
+ CreatorProfilePage,
41
+ },
42
+ components: {
43
+ CourseCard,
44
+ Pagination,
45
+ PageHeader,
46
+ LearnerSidebar,
47
+ },
48
+ };
49
+
50
+ validateTemplateManifest(template);
51
+
52
+ export default template;
@@ -1,14 +1,28 @@
1
+ // Context & Provider
1
2
  export { SDKProvider, useSDK } from './sdk-context';
2
3
  export type { SDKHookImplementations, SDKProviderProps } from './sdk-context';
4
+
5
+ // User & Auth
3
6
  export { useUser, useLogout } from './useUser';
7
+
8
+ // Data hooks
4
9
  export { useMyCourses } from './useMyCourses';
5
10
  export { useMyBundles } from './useMyBundles';
6
11
  export { useCourseSearch } from './useCourseSearch';
12
+
13
+ // Lesson features
7
14
  export { useLessonNotes, useCreateNote, useUpdateNote, useDeleteNote } from './useNotes';
8
15
  export { useLessonBookmarks, useCreateBookmark, useUpdateBookmark, useDeleteBookmark } from './useBookmarks';
16
+
17
+ // AI Coach
9
18
  export { useAiCoachAvailability, useAiCoachChat, useAiCoachHistory } from './useAiCoach';
19
+
20
+ // Notifications
10
21
  export { useNotifications } from './useNotifications';
22
+
23
+ // Theme
11
24
  export { useTheme } from './useTheme';
25
+
26
+ // Utilities
12
27
  export { useDebounce } from './useDebounce';
13
28
  export { useToast } from './useToast';
14
- //# sourceMappingURL=index.d.ts.map