@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.
- package/dist/bundle.js +70 -0
- package/dist/manifest.json +5 -0
- package/dist/styles.css +3307 -0
- package/package.json +40 -46
- package/src/components/atoms/Avatar.tsx +38 -0
- package/src/components/atoms/Badge.tsx +32 -0
- package/src/components/atoms/Button.tsx +48 -0
- package/src/components/atoms/Card.tsx +33 -0
- package/src/components/atoms/Input.tsx +39 -0
- package/src/components/atoms/ProgressBar.tsx +52 -0
- package/src/components/atoms/Tabs.tsx +47 -0
- package/src/components/atoms/index.ts +10 -0
- package/src/components/index.ts +11 -0
- package/src/components/molecules/CourseCard.tsx +215 -0
- package/src/components/molecules/EmptyState.tsx +23 -0
- package/src/components/molecules/LoadingSpinner.tsx +27 -0
- package/src/components/molecules/PageHeader.tsx +22 -0
- package/src/components/molecules/Pagination.tsx +82 -0
- package/src/components/molecules/SearchInput.tsx +35 -0
- package/src/components/molecules/index.ts +12 -0
- package/src/components/organisms/CourseSidebar.tsx +276 -0
- package/src/components/organisms/LearnerNavbar.tsx +129 -0
- package/src/components/organisms/LearnerSidebar.tsx +148 -0
- package/src/components/organisms/LessonBookmarks.tsx +128 -0
- package/src/components/organisms/LessonNotes.tsx +153 -0
- package/src/components/organisms/index.ts +10 -0
- package/src/components/pages/BundleDetailPage.tsx +388 -0
- package/src/components/pages/CatalogBundlesPage.tsx +96 -0
- package/src/components/pages/CatalogCoursesPage.tsx +299 -0
- package/src/components/pages/CourseDetailPage.tsx +582 -0
- package/src/components/pages/CoursePlayerPage.tsx +481 -0
- package/src/components/pages/CreatorProfilePage.tsx +161 -0
- package/src/components/pages/LearnerSettingsPage.tsx +58 -0
- package/src/components/pages/ManualReviewDetailPage.tsx +254 -0
- package/src/components/pages/ManualReviewPage.tsx +228 -0
- package/src/components/pages/MessagesPage.tsx +285 -0
- package/src/components/pages/MyLearningPage.tsx +239 -0
- package/src/components/pages/PaymentCancelPage.tsx +74 -0
- package/src/components/pages/PaymentSuccessPage.tsx +73 -0
- package/src/components/pages/index.ts +13 -0
- package/src/components/utils.ts +6 -0
- package/src/contracts/components.contract.ts +89 -0
- package/src/contracts/index.ts +4 -0
- package/src/contracts/layout.contract.ts +36 -0
- package/src/contracts/pages.contract.ts +275 -0
- package/src/contracts/template.contract.ts +100 -0
- package/src/default-template.tsx +52 -0
- package/src/hooks/index.ts +28 -0
- package/src/hooks/sdk-context.tsx +152 -0
- package/src/hooks/useAiCoach.ts +27 -0
- package/src/hooks/useBookmarks.ts +35 -0
- package/src/hooks/useCourseSearch.ts +18 -0
- package/src/hooks/useDebounce.ts +19 -0
- package/src/hooks/useMyBundles.ts +21 -0
- package/src/hooks/useMyCourses.ts +20 -0
- package/src/hooks/useNotes.ts +35 -0
- package/src/hooks/useNotifications.ts +16 -0
- package/src/hooks/useTheme.ts +17 -0
- package/src/hooks/useToast.ts +17 -0
- package/src/hooks/useUser.ts +33 -0
- package/src/index.ts +33 -0
- package/src/layouts/DefaultLayout.tsx +58 -0
- package/src/manifest.json +5 -0
- package/src/styles.css +43 -0
- package/src/types/ai-coach.ts +25 -0
- package/src/types/bookmarks.ts +20 -0
- package/src/types/bundle.ts +119 -0
- package/src/types/common.ts +24 -0
- package/src/types/course.ts +135 -0
- package/src/types/enrollment.ts +35 -0
- package/src/types/index.ts +15 -0
- package/src/types/lesson.ts +106 -0
- package/src/types/manual-review.ts +116 -0
- package/src/types/messaging.ts +109 -0
- package/src/types/notification.ts +30 -0
- package/src/types/payment.ts +40 -0
- package/src/types/progress.ts +19 -0
- package/src/types/rating.ts +20 -0
- package/src/types/search.ts +31 -0
- package/src/types/user.ts +16 -0
- package/src/utils/formatters.ts +74 -0
- package/src/utils/index.ts +8 -0
- package/dist/components/atoms/index.cjs +0 -318
- package/dist/components/atoms/index.js +0 -288
- package/dist/components/index.cjs +0 -1275
- package/dist/components/index.js +0 -1245
- package/dist/components/molecules/index.cjs +0 -334
- package/dist/components/molecules/index.js +0 -311
- package/dist/components/organisms/index.cjs +0 -855
- package/dist/components/organisms/index.js +0 -825
- package/dist/components/pages/index.cjs +0 -3306
- package/dist/components/pages/index.js +0 -3315
- package/dist/contracts/index.cjs +0 -52
- package/dist/contracts/index.js +0 -29
- package/dist/hooks/index.cjs +0 -165
- package/dist/hooks/index.js +0 -142
- package/dist/index.cjs +0 -630
- package/dist/index.js +0 -600
- package/dist/types/index.cjs +0 -18
- package/dist/types/index.js +0 -0
- package/dist/utils/index.cjs +0 -80
- 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
|
+
}
|
|
@@ -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
|
-
}
|