@academy-sdk/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/dist/bundle.js +70 -0
  2. package/dist/manifest.json +5 -0
  3. package/dist/styles.css +3307 -0
  4. package/package.json +40 -46
  5. package/src/components/atoms/Avatar.tsx +38 -0
  6. package/src/components/atoms/Badge.tsx +32 -0
  7. package/src/components/atoms/Button.tsx +48 -0
  8. package/src/components/atoms/Card.tsx +33 -0
  9. package/src/components/atoms/Input.tsx +39 -0
  10. package/src/components/atoms/ProgressBar.tsx +52 -0
  11. package/src/components/atoms/Tabs.tsx +47 -0
  12. package/src/components/atoms/index.ts +10 -0
  13. package/src/components/index.ts +11 -0
  14. package/src/components/molecules/CourseCard.tsx +215 -0
  15. package/src/components/molecules/EmptyState.tsx +23 -0
  16. package/src/components/molecules/LoadingSpinner.tsx +27 -0
  17. package/src/components/molecules/PageHeader.tsx +22 -0
  18. package/src/components/molecules/Pagination.tsx +82 -0
  19. package/src/components/molecules/SearchInput.tsx +35 -0
  20. package/src/components/molecules/index.ts +12 -0
  21. package/src/components/organisms/CourseSidebar.tsx +276 -0
  22. package/src/components/organisms/LearnerNavbar.tsx +129 -0
  23. package/src/components/organisms/LearnerSidebar.tsx +148 -0
  24. package/src/components/organisms/LessonBookmarks.tsx +128 -0
  25. package/src/components/organisms/LessonNotes.tsx +153 -0
  26. package/src/components/organisms/index.ts +10 -0
  27. package/src/components/pages/BundleDetailPage.tsx +388 -0
  28. package/src/components/pages/CatalogBundlesPage.tsx +96 -0
  29. package/src/components/pages/CatalogCoursesPage.tsx +299 -0
  30. package/src/components/pages/CourseDetailPage.tsx +582 -0
  31. package/src/components/pages/CoursePlayerPage.tsx +481 -0
  32. package/src/components/pages/CreatorProfilePage.tsx +161 -0
  33. package/src/components/pages/LearnerSettingsPage.tsx +58 -0
  34. package/src/components/pages/ManualReviewDetailPage.tsx +254 -0
  35. package/src/components/pages/ManualReviewPage.tsx +228 -0
  36. package/src/components/pages/MessagesPage.tsx +285 -0
  37. package/src/components/pages/MyLearningPage.tsx +239 -0
  38. package/src/components/pages/PaymentCancelPage.tsx +74 -0
  39. package/src/components/pages/PaymentSuccessPage.tsx +73 -0
  40. package/src/components/pages/index.ts +13 -0
  41. package/src/components/utils.ts +6 -0
  42. package/src/contracts/components.contract.ts +89 -0
  43. package/src/contracts/index.ts +4 -0
  44. package/src/contracts/layout.contract.ts +36 -0
  45. package/src/contracts/pages.contract.ts +275 -0
  46. package/src/contracts/template.contract.ts +100 -0
  47. package/src/default-template.tsx +52 -0
  48. package/src/hooks/index.ts +28 -0
  49. package/src/hooks/sdk-context.tsx +152 -0
  50. package/src/hooks/useAiCoach.ts +27 -0
  51. package/src/hooks/useBookmarks.ts +35 -0
  52. package/src/hooks/useCourseSearch.ts +18 -0
  53. package/src/hooks/useDebounce.ts +19 -0
  54. package/src/hooks/useMyBundles.ts +21 -0
  55. package/src/hooks/useMyCourses.ts +20 -0
  56. package/src/hooks/useNotes.ts +35 -0
  57. package/src/hooks/useNotifications.ts +16 -0
  58. package/src/hooks/useTheme.ts +17 -0
  59. package/src/hooks/useToast.ts +17 -0
  60. package/src/hooks/useUser.ts +33 -0
  61. package/src/index.ts +33 -0
  62. package/src/layouts/DefaultLayout.tsx +58 -0
  63. package/src/manifest.json +5 -0
  64. package/src/styles.css +43 -0
  65. package/src/types/ai-coach.ts +25 -0
  66. package/src/types/bookmarks.ts +20 -0
  67. package/src/types/bundle.ts +119 -0
  68. package/src/types/common.ts +24 -0
  69. package/src/types/course.ts +135 -0
  70. package/src/types/enrollment.ts +35 -0
  71. package/src/types/index.ts +15 -0
  72. package/src/types/lesson.ts +106 -0
  73. package/src/types/manual-review.ts +116 -0
  74. package/src/types/messaging.ts +109 -0
  75. package/src/types/notification.ts +30 -0
  76. package/src/types/payment.ts +40 -0
  77. package/src/types/progress.ts +19 -0
  78. package/src/types/rating.ts +20 -0
  79. package/src/types/search.ts +31 -0
  80. package/src/types/user.ts +16 -0
  81. package/src/utils/formatters.ts +74 -0
  82. package/src/utils/index.ts +8 -0
  83. package/dist/components/atoms/index.cjs +0 -318
  84. package/dist/components/atoms/index.js +0 -288
  85. package/dist/components/index.cjs +0 -1275
  86. package/dist/components/index.js +0 -1245
  87. package/dist/components/molecules/index.cjs +0 -334
  88. package/dist/components/molecules/index.js +0 -311
  89. package/dist/components/organisms/index.cjs +0 -855
  90. package/dist/components/organisms/index.js +0 -825
  91. package/dist/components/pages/index.cjs +0 -3306
  92. package/dist/components/pages/index.js +0 -3315
  93. package/dist/contracts/index.cjs +0 -52
  94. package/dist/contracts/index.js +0 -29
  95. package/dist/hooks/index.cjs +0 -165
  96. package/dist/hooks/index.js +0 -142
  97. package/dist/index.cjs +0 -630
  98. package/dist/index.js +0 -600
  99. package/dist/types/index.cjs +0 -18
  100. package/dist/types/index.js +0 -0
  101. package/dist/utils/index.cjs +0 -80
  102. package/dist/utils/index.js +0 -57
@@ -0,0 +1,40 @@
1
+ export interface PaymentProvider {
2
+ id: string;
3
+ name: string;
4
+ type: string;
5
+ isActive: boolean;
6
+ }
7
+
8
+ export interface CheckoutConfig {
9
+ courseId?: string;
10
+ bundleId?: string;
11
+ paymentMode: 'ONE_TIME' | 'INSTALLMENT' | 'SUBSCRIPTION';
12
+ successUrl: string;
13
+ cancelUrl: string;
14
+ couponCode?: string;
15
+ paymentProvider?: string;
16
+ }
17
+
18
+ export interface Coupon {
19
+ id: string;
20
+ code: string;
21
+ description?: string;
22
+ discountType: 'FIXED' | 'PERCENTAGE';
23
+ discountValue: number;
24
+ maxDiscountAmount?: number;
25
+ minimumPurchase?: number;
26
+ currency?: string;
27
+ courseId?: string;
28
+ bundleId?: string;
29
+ status: 'SCHEDULED' | 'ACTIVE' | 'EXPIRED' | 'EXHAUSTED' | 'DISABLED';
30
+ isActive: boolean;
31
+ }
32
+
33
+ export interface ValidateCouponResponse {
34
+ valid: boolean;
35
+ coupon?: Coupon;
36
+ message?: string;
37
+ originalAmount?: number;
38
+ discountAmount?: number;
39
+ finalAmount?: number;
40
+ }
@@ -0,0 +1,19 @@
1
+ export interface CreateProgressPayload {
2
+ enrollmentId: string;
3
+ activityId: string;
4
+ }
5
+
6
+ export interface UpdateProgressPayload {
7
+ progressSecond: number;
8
+ completed?: boolean;
9
+ }
10
+
11
+ export interface ProgressResponse {
12
+ progressId: string;
13
+ enrollmentId: string;
14
+ activityId: string;
15
+ progressSecond: number;
16
+ completed: boolean;
17
+ createdAt: string;
18
+ updatedAt: string;
19
+ }
@@ -0,0 +1,20 @@
1
+ export interface Rating {
2
+ id: string;
3
+ userName: string;
4
+ userAvatar?: string;
5
+ rating: number;
6
+ comment: string;
7
+ date: string;
8
+ }
9
+
10
+ export interface RatingSummary {
11
+ averageRating: number;
12
+ totalRatings: number;
13
+ starDistribution: {
14
+ 5: number;
15
+ 4: number;
16
+ 3: number;
17
+ 2: number;
18
+ 1: number;
19
+ };
20
+ }
@@ -0,0 +1,31 @@
1
+ export interface SearchHighlight {
2
+ title?: string;
3
+ }
4
+
5
+ export interface SearchActivity {
6
+ id: string;
7
+ title: string;
8
+ highlight?: SearchHighlight;
9
+ }
10
+
11
+ export interface SearchSection {
12
+ id: string;
13
+ title: string;
14
+ highlight?: SearchHighlight;
15
+ activities?: SearchActivity[];
16
+ }
17
+
18
+ export interface SearchCourse {
19
+ id: string;
20
+ title: string;
21
+ enrollmentId: string;
22
+ highlight?: SearchHighlight;
23
+ sections: SearchSection[];
24
+ }
25
+
26
+ export interface SearchResponse {
27
+ page: number;
28
+ limit: number;
29
+ total: number;
30
+ data: SearchCourse[];
31
+ }
@@ -0,0 +1,16 @@
1
+ export type UserRole = 'CREATOR' | 'ADMIN' | 'STUDENT' | 'PLATFORM_ADMIN';
2
+
3
+ export interface User {
4
+ id: string;
5
+ email: string;
6
+ name: string;
7
+ userRole: UserRole;
8
+ profileImage?: string;
9
+ }
10
+
11
+ export interface Membership {
12
+ tenantId: string;
13
+ tenantName: string;
14
+ tenantSlug: string;
15
+ role: UserRole;
16
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Format seconds into MM:SS or HH:MM:SS string.
3
+ */
4
+ export function formatDuration(seconds: number): string {
5
+ if (!seconds || seconds < 0) return '0:00';
6
+
7
+ const hours = Math.floor(seconds / 3600);
8
+ const minutes = Math.floor((seconds % 3600) / 60);
9
+ const secs = Math.floor(seconds % 60);
10
+
11
+ if (hours > 0) {
12
+ return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
13
+ }
14
+ return `${minutes}:${secs.toString().padStart(2, '0')}`;
15
+ }
16
+
17
+ /**
18
+ * Format a price with currency symbol.
19
+ */
20
+ export function formatPrice(amount: number, currency: string = 'USD'): string {
21
+ return new Intl.NumberFormat('en-US', {
22
+ style: 'currency',
23
+ currency,
24
+ minimumFractionDigits: 0,
25
+ maximumFractionDigits: 2,
26
+ }).format(amount);
27
+ }
28
+
29
+ /**
30
+ * Format a date string to a human-readable format.
31
+ */
32
+ export function formatDate(dateString: string, options?: Intl.DateTimeFormatOptions): string {
33
+ const date = new Date(dateString);
34
+ return date.toLocaleDateString('en-US', options ?? {
35
+ year: 'numeric',
36
+ month: 'short',
37
+ day: 'numeric',
38
+ });
39
+ }
40
+
41
+ /**
42
+ * Format a relative time (e.g., "2 hours ago").
43
+ */
44
+ export function formatRelativeTime(dateString: string): string {
45
+ const date = new Date(dateString);
46
+ const now = new Date();
47
+ const diffMs = now.getTime() - date.getTime();
48
+ const diffSecs = Math.floor(diffMs / 1000);
49
+ const diffMins = Math.floor(diffSecs / 60);
50
+ const diffHours = Math.floor(diffMins / 60);
51
+ const diffDays = Math.floor(diffHours / 24);
52
+
53
+ if (diffSecs < 60) return 'just now';
54
+ if (diffMins < 60) return `${diffMins}m ago`;
55
+ if (diffHours < 24) return `${diffHours}h ago`;
56
+ if (diffDays < 7) return `${diffDays}d ago`;
57
+ return formatDate(dateString);
58
+ }
59
+
60
+ /**
61
+ * Calculate progress percentage.
62
+ */
63
+ export function calculateProgress(completed: number, total: number): number {
64
+ if (total === 0) return 0;
65
+ return Math.round((completed / total) * 100);
66
+ }
67
+
68
+ /**
69
+ * Truncate text to a max length.
70
+ */
71
+ export function truncateText(text: string, maxLength: number): string {
72
+ if (text.length <= maxLength) return text;
73
+ return text.slice(0, maxLength).trimEnd() + '...';
74
+ }
@@ -0,0 +1,8 @@
1
+ export {
2
+ formatDuration,
3
+ formatPrice,
4
+ formatDate,
5
+ formatRelativeTime,
6
+ calculateProgress,
7
+ truncateText,
8
+ } from './formatters';
@@ -1,318 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
- var __getProtoOf = Object.getPrototypeOf;
10
- var __hasOwnProp = Object.prototype.hasOwnProperty;
11
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
- var __spreadValues = (a, b) => {
14
- for (var prop in b || (b = {}))
15
- if (__hasOwnProp.call(b, prop))
16
- __defNormalProp(a, prop, b[prop]);
17
- if (__getOwnPropSymbols)
18
- for (var prop of __getOwnPropSymbols(b)) {
19
- if (__propIsEnum.call(b, prop))
20
- __defNormalProp(a, prop, b[prop]);
21
- }
22
- return a;
23
- };
24
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
- var __objRest = (source, exclude) => {
26
- var target = {};
27
- for (var prop in source)
28
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
29
- target[prop] = source[prop];
30
- if (source != null && __getOwnPropSymbols)
31
- for (var prop of __getOwnPropSymbols(source)) {
32
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
33
- target[prop] = source[prop];
34
- }
35
- return target;
36
- };
37
- var __export = (target, all) => {
38
- for (var name in all)
39
- __defProp(target, name, { get: all[name], enumerable: true });
40
- };
41
- var __copyProps = (to, from, except, desc) => {
42
- if (from && typeof from === "object" || typeof from === "function") {
43
- for (let key of __getOwnPropNames(from))
44
- if (!__hasOwnProp.call(to, key) && key !== except)
45
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
46
- }
47
- return to;
48
- };
49
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
50
- // If the importer is in node compatibility mode or this is not an ESM
51
- // file that has been converted to a CommonJS file using a Babel-
52
- // compatible transform (i.e. "__esModule" has not been set), then set
53
- // "default" to the CommonJS "module.exports" for node compatibility.
54
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
55
- mod
56
- ));
57
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
58
-
59
- // src/components/atoms/index.ts
60
- var atoms_exports = {};
61
- __export(atoms_exports, {
62
- Avatar: () => Avatar,
63
- Badge: () => Badge,
64
- Button: () => Button,
65
- Card: () => Card,
66
- CardContent: () => CardContent,
67
- CardDescription: () => CardDescription,
68
- CardFooter: () => CardFooter,
69
- CardHeader: () => CardHeader,
70
- CardTitle: () => CardTitle,
71
- Input: () => Input,
72
- ProgressBar: () => ProgressBar,
73
- Tabs: () => Tabs,
74
- badgeVariants: () => badgeVariants,
75
- buttonVariants: () => buttonVariants
76
- });
77
- module.exports = __toCommonJS(atoms_exports);
78
-
79
- // src/components/atoms/Button.tsx
80
- var React = __toESM(require("react"));
81
- var import_class_variance_authority = require("class-variance-authority");
82
-
83
- // src/components/utils.ts
84
- var import_clsx = require("clsx");
85
- var import_tailwind_merge = require("tailwind-merge");
86
- function cn(...inputs) {
87
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
88
- }
89
-
90
- // src/components/atoms/Button.tsx
91
- var import_jsx_runtime = require("react/jsx-runtime");
92
- var buttonVariants = (0, import_class_variance_authority.cva)(
93
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 cursor-pointer",
94
- {
95
- variants: {
96
- variant: {
97
- default: "bg-theme-accent-primary text-white hover:opacity-90",
98
- destructive: "bg-red-600 text-white hover:bg-red-700",
99
- outline: "border border-theme-border-primary bg-theme-bg-secondary hover:bg-theme-bg-tertiary text-theme-text-primary",
100
- secondary: "bg-theme-bg-tertiary text-theme-text-primary hover:opacity-80",
101
- ghost: "hover:bg-theme-bg-tertiary text-theme-text-primary",
102
- link: "text-[rgb(var(--accent-primary))] underline-offset-4 hover:underline"
103
- },
104
- size: {
105
- default: "h-10 px-4 py-2",
106
- sm: "h-9 rounded-md px-3",
107
- lg: "h-11 rounded-md px-8",
108
- icon: "h-10 w-10"
109
- }
110
- },
111
- defaultVariants: {
112
- variant: "default",
113
- size: "default"
114
- }
115
- }
116
- );
117
- var Button = React.forwardRef(
118
- (_a, ref) => {
119
- var _b = _a, { className, variant, size } = _b, props = __objRest(_b, ["className", "variant", "size"]);
120
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
121
- "button",
122
- __spreadValues({
123
- className: cn(buttonVariants({ variant, size, className })),
124
- ref
125
- }, props)
126
- );
127
- }
128
- );
129
- Button.displayName = "Button";
130
-
131
- // src/components/atoms/Input.tsx
132
- var React2 = __toESM(require("react"));
133
- var import_jsx_runtime2 = require("react/jsx-runtime");
134
- var Input = React2.forwardRef(
135
- (_a, ref) => {
136
- var _b = _a, { className, type, label } = _b, props = __objRest(_b, ["className", "type", "label"]);
137
- const inputElement = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
138
- "input",
139
- __spreadValues({
140
- type,
141
- className: cn(
142
- "flex h-10 w-full rounded-md border border-theme-border-primary bg-theme-bg-primary px-3 py-2 text-sm text-theme-text-primary file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-[rgb(var(--text-muted))] focus-visible:outline-none focus-visible:border-theme-accent-primary transition-colors disabled:cursor-not-allowed disabled:opacity-50",
143
- className
144
- ),
145
- ref
146
- }, props)
147
- );
148
- if (label) {
149
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-2", children: [
150
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("label", { className: "text-sm font-medium text-theme-text-primary", children: [
151
- label,
152
- props.required && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-red-500 ml-1", children: "*" })
153
- ] }),
154
- inputElement
155
- ] });
156
- }
157
- return inputElement;
158
- }
159
- );
160
- Input.displayName = "Input";
161
-
162
- // src/components/atoms/Card.tsx
163
- var import_jsx_runtime3 = require("react/jsx-runtime");
164
- function Card(_a) {
165
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
166
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
167
- "div",
168
- __spreadValues({
169
- className: cn("rounded-lg border border-theme-border-primary bg-theme-bg-primary shadow-sm", className)
170
- }, props)
171
- );
172
- }
173
- function CardHeader(_a) {
174
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
175
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", __spreadValues({ className: cn("flex flex-col space-y-1.5 p-6", className) }, props));
176
- }
177
- function CardTitle(_a) {
178
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
179
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", __spreadValues({ className: cn("text-2xl font-semibold leading-none tracking-tight", className) }, props));
180
- }
181
- function CardDescription(_a) {
182
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
183
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", __spreadValues({ className: cn("text-sm text-theme-text-secondary", className) }, props));
184
- }
185
- function CardContent(_a) {
186
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
187
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", __spreadValues({ className: cn("p-6 pt-0", className) }, props));
188
- }
189
- function CardFooter(_a) {
190
- var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
191
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", __spreadValues({ className: cn("flex items-center p-6 pt-0", className) }, props));
192
- }
193
-
194
- // src/components/atoms/Badge.tsx
195
- var import_class_variance_authority2 = require("class-variance-authority");
196
- var import_jsx_runtime4 = require("react/jsx-runtime");
197
- var badgeVariants = (0, import_class_variance_authority2.cva)(
198
- "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-offset-2",
199
- {
200
- variants: {
201
- variant: {
202
- default: "bg-theme-accent-primary text-white",
203
- secondary: "bg-theme-bg-tertiary text-theme-text-primary",
204
- success: "border-transparent bg-green-600 text-white",
205
- warning: "border-transparent bg-yellow-500 text-white",
206
- destructive: "border-transparent bg-red-600 text-white",
207
- outline: "text-theme-text-primary border-theme-border-primary"
208
- }
209
- },
210
- defaultVariants: {
211
- variant: "default"
212
- }
213
- }
214
- );
215
- function Badge(_a) {
216
- var _b = _a, { className, variant } = _b, props = __objRest(_b, ["className", "variant"]);
217
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", __spreadValues({ className: cn(badgeVariants({ variant }), className) }, props));
218
- }
219
-
220
- // src/components/atoms/Avatar.tsx
221
- var React3 = __toESM(require("react"));
222
- var import_jsx_runtime5 = require("react/jsx-runtime");
223
- var Avatar = React3.forwardRef(
224
- (_a, ref) => {
225
- var _b = _a, { className, src, alt, fallback } = _b, props = __objRest(_b, ["className", "src", "alt", "fallback"]);
226
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
227
- "div",
228
- __spreadProps(__spreadValues({
229
- ref,
230
- className: cn(
231
- "relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full",
232
- className
233
- )
234
- }, props), {
235
- children: src ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
236
- "img",
237
- {
238
- src,
239
- alt: alt || "Avatar",
240
- className: "aspect-square h-full w-full object-cover"
241
- }
242
- ) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "flex h-full w-full items-center justify-center bg-gray-200 text-gray-600 text-sm font-medium", children: fallback || "?" })
243
- })
244
- );
245
- }
246
- );
247
- Avatar.displayName = "Avatar";
248
-
249
- // src/components/atoms/ProgressBar.tsx
250
- var import_jsx_runtime6 = require("react/jsx-runtime");
251
- var sizeClasses = {
252
- sm: "h-1.5",
253
- md: "h-2.5",
254
- lg: "h-3.5"
255
- };
256
- var variantClasses = {
257
- default: "bg-theme-accent-primary",
258
- success: "bg-green-600",
259
- warning: "bg-yellow-500",
260
- error: "bg-red-600"
261
- };
262
- function ProgressBar(_a) {
263
- var _b = _a, {
264
- value,
265
- max = 100,
266
- showLabel = false,
267
- size = "md",
268
- variant = "default",
269
- className
270
- } = _b, props = __objRest(_b, [
271
- "value",
272
- "max",
273
- "showLabel",
274
- "size",
275
- "variant",
276
- "className"
277
- ]);
278
- const percentage = Math.min(Math.max(value / max * 100, 0), 100);
279
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", __spreadProps(__spreadValues({ className: cn("w-full", className) }, props), { children: [
280
- showLabel && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mb-1 flex items-center justify-between text-sm", children: [
281
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-theme-text-secondary", children: "Progress" }),
282
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "font-medium text-theme-text-primary", children: [
283
- Math.round(percentage),
284
- "%"
285
- ] })
286
- ] }),
287
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("w-full overflow-hidden rounded-full bg-theme-bg-tertiary", sizeClasses[size]), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
288
- "div",
289
- {
290
- className: cn("h-full transition-all duration-300 ease-in-out", variantClasses[variant]),
291
- style: { width: `${percentage}%` }
292
- }
293
- ) })
294
- ] }));
295
- }
296
-
297
- // src/components/atoms/Tabs.tsx
298
- var import_jsx_runtime7 = require("react/jsx-runtime");
299
- function Tabs({ tabs, activeTab, onTabChange, className, actions }) {
300
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: cn("border-b border-theme-border-primary", className), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "px-4 sm:px-6 pt-4", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "p-0.5 flex items-center justify-between overflow-x-auto", children: [
301
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("nav", { className: "flex gap-4 sm:gap-8 min-w-min", children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
302
- "button",
303
- {
304
- onClick: () => onTabChange(tab.id),
305
- className: cn(
306
- "pb-3 px-1 text-sm font-medium border-b-2 transition-all flex items-center gap-2 cursor-pointer whitespace-nowrap",
307
- activeTab === tab.id ? "border-theme-accent-primary text-theme-accent-primary" : "border-transparent text-theme-text-secondary hover:text-theme-text-primary hover:border-theme-accent-primary/40"
308
- ),
309
- children: [
310
- tab.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex-shrink-0", children: tab.icon }),
311
- tab.label
312
- ]
313
- },
314
- tab.id
315
- )) }),
316
- actions && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "pb-3", children: actions })
317
- ] }) }) });
318
- }