@burdenoff/microfe-timecampus 2026.624.1 → 2026.626.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 (109) hide show
  1. package/dist/timecampus/components/EmptyState.js +14 -0
  2. package/dist/timecampus/components/EmptyState.js.map +1 -0
  3. package/dist/timecampus/components/ErrorBoundary.js +2 -2
  4. package/dist/timecampus/components/ErrorBoundary.js.map +1 -1
  5. package/dist/timecampus/components/LoadingSkeleton.js +1 -1
  6. package/dist/timecampus/components/LoadingSkeleton.js.map +1 -1
  7. package/dist/timecampus/components/PageLayout.js +26 -14
  8. package/dist/timecampus/components/PageLayout.js.map +1 -1
  9. package/dist/timecampus/components/StatCard.js +19 -16
  10. package/dist/timecampus/components/StatCard.js.map +1 -1
  11. package/dist/timecampus/pages/HomePage.js +169 -149
  12. package/dist/timecampus/pages/HomePage.js.map +1 -1
  13. package/dist/timecampus/pages/applets/AppletStorePage.js +38 -35
  14. package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
  15. package/dist/timecampus/pages/applets/InstalledAppletsPage.js +42 -36
  16. package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
  17. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +57 -53
  18. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
  19. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +40 -36
  20. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
  21. package/dist/timecampus/pages/channels/ChannelsPage.js +32 -29
  22. package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
  23. package/dist/timecampus/pages/client-portal/ClientPortalPage.js +52 -44
  24. package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
  25. package/dist/timecampus/pages/dashboard/AnalyticsPage.js +65 -38
  26. package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
  27. package/dist/timecampus/pages/dashboard/ReportsPage.js +47 -41
  28. package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
  29. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +16 -14
  30. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
  31. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +40 -36
  32. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
  33. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +34 -28
  34. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
  35. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +49 -41
  36. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
  37. package/dist/timecampus/pages/focus-score/FocusScorePage.js +66 -62
  38. package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
  39. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +37 -33
  40. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
  41. package/dist/timecampus/pages/geofencing/GeofencingPage.js +37 -30
  42. package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
  43. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +35 -31
  44. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
  45. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +37 -34
  46. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
  47. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +35 -31
  48. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
  49. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +45 -41
  50. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
  51. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +17 -15
  52. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
  53. package/dist/timecampus/pages/meetings/MeetingCreatePage.js +36 -32
  54. package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
  55. package/dist/timecampus/pages/meetings/MeetingDetailPage.js +120 -102
  56. package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
  57. package/dist/timecampus/pages/meetings/MeetingsPage.js +46 -36
  58. package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
  59. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +19 -17
  60. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
  61. package/dist/timecampus/pages/pomodoro/PomodoroPage.js +143 -112
  62. package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
  63. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +55 -51
  64. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
  65. package/dist/timecampus/pages/projects/ProjectCreatePage.js +32 -28
  66. package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
  67. package/dist/timecampus/pages/projects/ProjectDetailPage.js +107 -76
  68. package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
  69. package/dist/timecampus/pages/projects/ProjectsPage.js +21 -17
  70. package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
  71. package/dist/timecampus/pages/projects/TasksPage.js +44 -34
  72. package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
  73. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +59 -55
  74. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
  75. package/dist/timecampus/pages/team/TeamAnalyticsPage.js +24 -20
  76. package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
  77. package/dist/timecampus/pages/team/TeamMembersPage.js +47 -41
  78. package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
  79. package/dist/timecampus/pages/team/TeamPage.js +89 -59
  80. package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
  81. package/dist/timecampus/pages/team-activity/TeamActivityPage.js +47 -43
  82. package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
  83. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +39 -35
  84. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
  85. package/dist/timecampus/pages/templates/TemplateApplicationPage.js +24 -20
  86. package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
  87. package/dist/timecampus/pages/templates/TemplateDetailPage.js +66 -48
  88. package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
  89. package/dist/timecampus/pages/templates/TemplatesPage.js +39 -36
  90. package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
  91. package/dist/timecampus/pages/time/TimeEntriesPage.js +53 -44
  92. package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
  93. package/dist/timecampus/pages/time/TimeTrackingPage.js +72 -71
  94. package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
  95. package/dist/timecampus/pages/time/TimerPage.js +100 -66
  96. package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
  97. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +63 -59
  98. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
  99. package/dist/timecampus/pages/widgets/WidgetDetailPage.js +64 -46
  100. package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
  101. package/dist/timecampus/pages/widgets/WidgetsPage.js +44 -37
  102. package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
  103. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +18 -16
  104. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
  105. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +40 -36
  106. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
  107. package/dist/timecampus/pages/workflows/WorkflowsPage.js +47 -37
  108. package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
  109. package/package.json +2 -2
@@ -0,0 +1,14 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { IllustratedEmptyState as t } from "@burdenoff/fe-libs/ui";
3
+ //#region src/timecampus/components/EmptyState.tsx
4
+ var n = ({ title: n, description: r, action: i, className: a, illustration: o = "empty-data" }) => /* @__PURE__ */ e(t, {
5
+ illustration: o,
6
+ title: n,
7
+ description: r,
8
+ action: i,
9
+ className: a
10
+ });
11
+ //#endregion
12
+ export { n as EmptyState };
13
+
14
+ //# sourceMappingURL=EmptyState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/timecampus/components/EmptyState.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { IllustratedEmptyState } from \"@burdenoff/fe-libs/ui\";\n\ninterface EmptyStateProps {\n /** Retained for backward compatibility; superseded by the illustration. */\n icon?: ReactNode;\n title: string;\n description?: string;\n action?: ReactNode;\n className?: string;\n /**\n * Illustration name served from the host shell's /illustrations/<name>.webp.\n * Defaults to the neutral \"empty-data\" asset.\n */\n illustration?: string;\n}\n\nexport const EmptyState: FC<EmptyStateProps> = ({\n title,\n description,\n action,\n className,\n illustration = \"empty-data\",\n}) => {\n return (\n <IllustratedEmptyState\n illustration={illustration}\n title={title}\n description={description}\n action={action}\n className={className}\n />\n );\n};\n"],"mappings":";;;AAiBA,IAAa,KAAmC,EAC9C,UACA,gBACA,WACA,cACA,kBAAe,mBAGb,kBAAC,GAAD;CACgB;CACP;CACM;CACL;CACG;CACX,CAAA"}
@@ -26,9 +26,9 @@ var a = class extends e {
26
26
  };
27
27
  render() {
28
28
  return this.state.hasError ? this.props.fallback ? this.props.fallback : /* @__PURE__ */ i("div", {
29
- className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-12 text-center dark:border-red-800 dark:bg-red-900/10",
29
+ className: "flex flex-col items-center justify-center rounded-lg border border-dashed border-status-error-bg/50 bg-status-error-bg p-12 text-center",
30
30
  children: [
31
- /* @__PURE__ */ r(t, { className: "mb-4 h-12 w-12 text-red-500" }),
31
+ /* @__PURE__ */ r(t, { className: "mb-4 h-12 w-12 text-status-error-text" }),
32
32
  /* @__PURE__ */ r("h3", {
33
33
  className: "text-lg font-medium text-text-primary",
34
34
  children: "Something went wrong"
@@ -1 +1 @@
1
- {"version":3,"file":"ErrorBoundary.js","names":[],"sources":["../../../src/timecampus/components/ErrorBoundary.tsx"],"sourcesContent":["import { Component, type ReactNode, type ErrorInfo } from \"react\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\"[TimeCampus ErrorBoundary]\", error, errorInfo);\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) return this.props.fallback;\n\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-red-300 bg-red-50 p-12 text-center dark:border-red-800 dark:bg-red-900/10\">\n <AlertTriangle className=\"mb-4 h-12 w-12 text-red-500\" />\n <h3 className=\"text-lg font-medium text-text-primary\">\n Something went wrong\n </h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">\n {this.state.error?.message ??\n \"An unexpected error occurred while rendering this section.\"}\n </p>\n <button\n onClick={this.handleReset}\n className=\"mt-4 flex items-center gap-1.5 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90\"\n >\n <RefreshCw className=\"h-4 w-4\" /> Try Again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n"],"mappings":";;;;AAaA,IAAa,IAAb,cAAmC,EAGjC;CACA,YAAY,GAA2B;AAErC,EADA,MAAM,EAAM,EACZ,KAAK,QAAQ;GAAE,UAAU;GAAO,OAAO;GAAM;;CAG/C,OAAO,yBAAyB,GAAkC;AAChE,SAAO;GAAE,UAAU;GAAM;GAAO;;CAGlC,kBAAkB,GAAc,GAAsB;AACpD,UAAQ,MAAM,8BAA8B,GAAO,EAAU;;CAG/D,oBAAoB;AAClB,OAAK,SAAS;GAAE,UAAU;GAAO,OAAO;GAAM,CAAC;;CAGjD,SAAS;AAwBP,SAvBI,KAAK,MAAM,WACT,KAAK,MAAM,WAAiB,KAAK,MAAM,WAGzC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAe,WAAU,+BAAgC,CAAA;IACzD,kBAAC,MAAD;KAAI,WAAU;eAAwC;KAEjD,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,KAAK,MAAM,OAAO,WACjB;KACA,CAAA;IACJ,kBAAC,UAAD;KACE,SAAS,KAAK;KACd,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,aAC1B;;IACL;OAIH,KAAK,MAAM"}
1
+ {"version":3,"file":"ErrorBoundary.js","names":[],"sources":["../../../src/timecampus/components/ErrorBoundary.tsx"],"sourcesContent":["import { Component, type ReactNode, type ErrorInfo } from \"react\";\nimport { AlertTriangle, RefreshCw } from \"lucide-react\";\n\ninterface ErrorBoundaryProps {\n children: ReactNode;\n fallback?: ReactNode;\n}\n\ninterface ErrorBoundaryState {\n hasError: boolean;\n error: Error | null;\n}\n\nexport class ErrorBoundary extends Component<\n ErrorBoundaryProps,\n ErrorBoundaryState\n> {\n constructor(props: ErrorBoundaryProps) {\n super(props);\n this.state = { hasError: false, error: null };\n }\n\n static getDerivedStateFromError(error: Error): ErrorBoundaryState {\n return { hasError: true, error };\n }\n\n componentDidCatch(error: Error, errorInfo: ErrorInfo) {\n console.error(\"[TimeCampus ErrorBoundary]\", error, errorInfo);\n }\n\n handleReset = () => {\n this.setState({ hasError: false, error: null });\n };\n\n render() {\n if (this.state.hasError) {\n if (this.props.fallback) return this.props.fallback;\n\n return (\n <div className=\"flex flex-col items-center justify-center rounded-lg border border-dashed border-status-error-bg/50 bg-status-error-bg p-12 text-center\">\n <AlertTriangle className=\"mb-4 h-12 w-12 text-status-error-text\" />\n <h3 className=\"text-lg font-medium text-text-primary\">\n Something went wrong\n </h3>\n <p className=\"mt-1 max-w-md text-sm text-text-secondary\">\n {this.state.error?.message ??\n \"An unexpected error occurred while rendering this section.\"}\n </p>\n <button\n onClick={this.handleReset}\n className=\"mt-4 flex items-center gap-1.5 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background hover:opacity-90\"\n >\n <RefreshCw className=\"h-4 w-4\" /> Try Again\n </button>\n </div>\n );\n }\n\n return this.props.children;\n }\n}\n"],"mappings":";;;;AAaA,IAAa,IAAb,cAAmC,EAGjC;CACA,YAAY,GAA2B;AAErC,EADA,MAAM,EAAM,EACZ,KAAK,QAAQ;GAAE,UAAU;GAAO,OAAO;GAAM;;CAG/C,OAAO,yBAAyB,GAAkC;AAChE,SAAO;GAAE,UAAU;GAAM;GAAO;;CAGlC,kBAAkB,GAAc,GAAsB;AACpD,UAAQ,MAAM,8BAA8B,GAAO,EAAU;;CAG/D,oBAAoB;AAClB,OAAK,SAAS;GAAE,UAAU;GAAO,OAAO;GAAM,CAAC;;CAGjD,SAAS;AAwBP,SAvBI,KAAK,MAAM,WACT,KAAK,MAAM,WAAiB,KAAK,MAAM,WAGzC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAe,WAAU,yCAA0C,CAAA;IACnE,kBAAC,MAAD;KAAI,WAAU;eAAwC;KAEjD,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eACV,KAAK,MAAM,OAAO,WACjB;KACA,CAAA;IACJ,kBAAC,UAAD;KACE,SAAS,KAAK;KACd,WAAU;eAFZ,CAIE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,aAC1B;;IACL;OAIH,KAAK,MAAM"}
@@ -1,7 +1,7 @@
1
1
  import { cn as e } from "../utils/helpers.js";
2
2
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
3
  //#region src/timecampus/components/LoadingSkeleton.tsx
4
- var r = ({ className: n }) => /* @__PURE__ */ t("div", { className: e("animate-pulse rounded-md bg-bg-sunken", n) }), i = ({ variant: i = "card", count: a = 3, className: o }) => i === "table" ? /* @__PURE__ */ t("div", {
4
+ var r = ({ className: n }) => /* @__PURE__ */ t("div", { className: e("relative overflow-hidden rounded-md bg-bg-sunken", "after:absolute after:inset-0 after:-translate-x-full after:bg-gradient-to-r after:from-transparent after:via-bg-surface/60 after:to-transparent motion-safe:after:animate-vc-shimmer", n) }), i = ({ variant: i = "card", count: a = 3, className: o }) => i === "table" ? /* @__PURE__ */ t("div", {
5
5
  className: e("space-y-3", o),
6
6
  children: /* @__PURE__ */ n("div", {
7
7
  className: "overflow-hidden rounded-lg border border-border-subtle",
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingSkeleton.js","names":[],"sources":["../../../src/timecampus/components/LoadingSkeleton.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { cn } from \"../utils/helpers\";\n\ninterface SkeletonProps {\n className?: string;\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ className }) => (\n <div className={cn(\"animate-pulse rounded-md bg-bg-sunken\", className)} />\n);\n\ninterface LoadingSkeletonProps {\n variant?: \"card\" | \"table\" | \"list\" | \"detail\";\n count?: number;\n className?: string;\n}\n\nexport const LoadingSkeleton: FC<LoadingSkeletonProps> = ({\n variant = \"card\",\n count = 3,\n className,\n}) => {\n if (variant === \"table\") {\n return (\n <div className={cn(\"space-y-3\", className)}>\n <div className=\"overflow-hidden rounded-lg border border-border-subtle\">\n <div className=\"border-b border-border-subtle bg-bg-sunken/50 px-4 py-3\">\n <div className=\"flex gap-4\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Skeleton key={i} className=\"h-4 w-20\" />\n ))}\n </div>\n </div>\n {Array.from({ length: count }).map((_, i) => (\n <div\n key={i}\n className=\"flex gap-4 border-b border-border-subtle px-4 py-3 last:border-b-0\"\n >\n {Array.from({ length: 5 }).map((_, j) => (\n <Skeleton key={j} className=\"h-4 w-20\" />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n if (variant === \"list\") {\n return (\n <div className={cn(\"space-y-2\", className)}>\n {Array.from({ length: count }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-3 rounded-lg border border-border-subtle p-4\"\n >\n <Skeleton className=\"h-10 w-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-6 w-16 rounded-full\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (variant === \"detail\") {\n return (\n <div className={cn(\"space-y-6\", className)}>\n <div className=\"space-y-2\">\n <Skeleton className=\"h-8 w-1/3\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div key={i} className=\"rounded-lg border border-border-subtle p-4\">\n <Skeleton className=\"h-3 w-20\" />\n <Skeleton className=\"mt-2 h-7 w-16\" />\n </div>\n ))}\n </div>\n <div className=\"rounded-lg border border-border-subtle p-6\">\n <Skeleton className=\"h-5 w-1/4\" />\n <div className=\"mt-4 space-y-3\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-4 w-4/6\" />\n </div>\n </div>\n </div>\n );\n }\n\n // Default: card grid\n return (\n <div className={cn(\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\", className)}>\n {Array.from({ length: count }).map((_, i) => (\n <div key={i} className=\"rounded-lg border border-border-subtle p-4\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"mt-2 h-3 w-1/2\" />\n <Skeleton className=\"mt-4 h-8 w-24\" />\n <div className=\"mt-3 flex justify-between\">\n <Skeleton className=\"h-5 w-16 rounded-full\" />\n <Skeleton className=\"h-7 w-14 rounded-md\" />\n </div>\n </div>\n ))}\n </div>\n );\n};\n"],"mappings":";;;AAOA,IAAM,KAA+B,EAAE,mBACrC,kBAAC,OAAD,EAAK,WAAW,EAAG,yCAAyC,EAAU,EAAI,CAAA,EAS/D,KAA6C,EACxD,aAAU,QACV,WAAQ,GACR,mBAEI,MAAY,UAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WACxC,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAkB,WAAU,YAAa,EAA1B,EAA0B,CACzC;IACE,CAAA;GACF,CAAA,EACL,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;GAEE,WAAU;aAET,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAkB,WAAU,YAAa,EAA1B,EAA0B,CACzC;GACE,EANC,EAMD,CACN,CACE;;CACF,CAAA,GAIN,MAAY,SAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WACvC,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;EAEE,WAAU;YAFZ;GAIE,kBAAC,GAAD,EAAU,WAAU,0BAA2B,CAAA;GAC/C,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,CAC9B;;GACN,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA;GAC1C;IATC,EASD,CACN;CACE,CAAA,GAIN,MAAY,WAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WAA1C;EACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,CAC9B;;EACN,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD;IAAa,WAAU;cAAvB,CACE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA,EACjC,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA,CAClC;MAHI,EAGJ,CACN;GACE,CAAA;EACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;KACnC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;KAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;KAC9B;MACF;;EACF;KAMR,kBAAC,OAAD;CAAK,WAAW,EAAG,4CAA4C,EAAU;WACtE,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;EAAa,WAAU;YAAvB;GACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;GAClC,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA;GACvC,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA;GACtC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA,EAC9C,kBAAC,GAAD,EAAU,WAAU,uBAAwB,CAAA,CACxC;;GACF;IARI,EAQJ,CACN;CACE,CAAA"}
1
+ {"version":3,"file":"LoadingSkeleton.js","names":[],"sources":["../../../src/timecampus/components/LoadingSkeleton.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { cn } from \"../utils/helpers\";\n\ninterface SkeletonProps {\n className?: string;\n}\n\nconst Skeleton: FC<SkeletonProps> = ({ className }) => (\n <div\n className={cn(\n \"relative overflow-hidden rounded-md bg-bg-sunken\",\n \"after:absolute after:inset-0 after:-translate-x-full after:bg-gradient-to-r after:from-transparent after:via-bg-surface/60 after:to-transparent motion-safe:after:animate-vc-shimmer\",\n className,\n )}\n />\n);\n\ninterface LoadingSkeletonProps {\n variant?: \"card\" | \"table\" | \"list\" | \"detail\";\n count?: number;\n className?: string;\n}\n\nexport const LoadingSkeleton: FC<LoadingSkeletonProps> = ({\n variant = \"card\",\n count = 3,\n className,\n}) => {\n if (variant === \"table\") {\n return (\n <div className={cn(\"space-y-3\", className)}>\n <div className=\"overflow-hidden rounded-lg border border-border-subtle\">\n <div className=\"border-b border-border-subtle bg-bg-sunken/50 px-4 py-3\">\n <div className=\"flex gap-4\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Skeleton key={i} className=\"h-4 w-20\" />\n ))}\n </div>\n </div>\n {Array.from({ length: count }).map((_, i) => (\n <div\n key={i}\n className=\"flex gap-4 border-b border-border-subtle px-4 py-3 last:border-b-0\"\n >\n {Array.from({ length: 5 }).map((_, j) => (\n <Skeleton key={j} className=\"h-4 w-20\" />\n ))}\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n if (variant === \"list\") {\n return (\n <div className={cn(\"space-y-2\", className)}>\n {Array.from({ length: count }).map((_, i) => (\n <div\n key={i}\n className=\"flex items-center gap-3 rounded-lg border border-border-subtle p-4\"\n >\n <Skeleton className=\"h-10 w-10 rounded-full\" />\n <div className=\"flex-1 space-y-2\">\n <Skeleton className=\"h-4 w-1/3\" />\n <Skeleton className=\"h-3 w-2/3\" />\n </div>\n <Skeleton className=\"h-6 w-16 rounded-full\" />\n </div>\n ))}\n </div>\n );\n }\n\n if (variant === \"detail\") {\n return (\n <div className={cn(\"space-y-6\", className)}>\n <div className=\"space-y-2\">\n <Skeleton className=\"h-8 w-1/3\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n <div className=\"grid gap-4 sm:grid-cols-3\">\n {Array.from({ length: 3 }).map((_, i) => (\n <div key={i} className=\"rounded-lg border border-border-subtle p-4\">\n <Skeleton className=\"h-3 w-20\" />\n <Skeleton className=\"mt-2 h-7 w-16\" />\n </div>\n ))}\n </div>\n <div className=\"rounded-lg border border-border-subtle p-6\">\n <Skeleton className=\"h-5 w-1/4\" />\n <div className=\"mt-4 space-y-3\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-5/6\" />\n <Skeleton className=\"h-4 w-4/6\" />\n </div>\n </div>\n </div>\n );\n }\n\n // Default: card grid\n return (\n <div className={cn(\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\", className)}>\n {Array.from({ length: count }).map((_, i) => (\n <div key={i} className=\"rounded-lg border border-border-subtle p-4\">\n <Skeleton className=\"h-4 w-2/3\" />\n <Skeleton className=\"mt-2 h-3 w-1/2\" />\n <Skeleton className=\"mt-4 h-8 w-24\" />\n <div className=\"mt-3 flex justify-between\">\n <Skeleton className=\"h-5 w-16 rounded-full\" />\n <Skeleton className=\"h-7 w-14 rounded-md\" />\n </div>\n </div>\n ))}\n </div>\n );\n};\n"],"mappings":";;;AAOA,IAAM,KAA+B,EAAE,mBACrC,kBAAC,OAAD,EACE,WAAW,EACT,oDACA,wLACA,EACD,EACD,CAAA,EASS,KAA6C,EACxD,aAAU,QACV,WAAQ,GACR,mBAEI,MAAY,UAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WACxC,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAkB,WAAU,YAAa,EAA1B,EAA0B,CACzC;IACE,CAAA;GACF,CAAA,EACL,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;GAEE,WAAU;aAET,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,GAAD,EAAkB,WAAU,YAAa,EAA1B,EAA0B,CACzC;GACE,EANC,EAMD,CACN,CACE;;CACF,CAAA,GAIN,MAAY,SAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WACvC,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;EAEE,WAAU;YAFZ;GAIE,kBAAC,GAAD,EAAU,WAAU,0BAA2B,CAAA;GAC/C,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,CAC9B;;GACN,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA;GAC1C;IATC,EASD,CACN;CACE,CAAA,GAIN,MAAY,WAEZ,kBAAC,OAAD;CAAK,WAAW,EAAG,aAAa,EAAU;WAA1C;EACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,CAC9B;;EACN,kBAAC,OAAD;GAAK,WAAU;aACZ,MAAM,KAAK,EAAE,QAAQ,GAAG,CAAC,CAAC,KAAK,GAAG,MACjC,kBAAC,OAAD;IAAa,WAAU;cAAvB,CACE,kBAAC,GAAD,EAAU,WAAU,YAAa,CAAA,EACjC,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA,CAClC;MAHI,EAGJ,CACN;GACE,CAAA;EACN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA,EAClC,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAU,WAAU,cAAe,CAAA;KACnC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;KAClC,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;KAC9B;MACF;;EACF;KAMR,kBAAC,OAAD;CAAK,WAAW,EAAG,4CAA4C,EAAU;WACtE,MAAM,KAAK,EAAE,QAAQ,GAAO,CAAC,CAAC,KAAK,GAAG,MACrC,kBAAC,OAAD;EAAa,WAAU;YAAvB;GACE,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;GAClC,kBAAC,GAAD,EAAU,WAAU,kBAAmB,CAAA;GACvC,kBAAC,GAAD,EAAU,WAAU,iBAAkB,CAAA;GACtC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAU,WAAU,yBAA0B,CAAA,EAC9C,kBAAC,GAAD,EAAU,WAAU,uBAAwB,CAAA,CACxC;;GACF;IARI,EAQJ,CACN;CACE,CAAA"}
@@ -1,23 +1,35 @@
1
1
  import { cn as e } from "../utils/helpers.js";
2
2
  import { jsx as t, jsxs as n } from "react/jsx-runtime";
3
+ import { GradientText as r, PagePurpose as i } from "@burdenoff/fe-libs/ui";
3
4
  //#region src/timecampus/components/PageLayout.tsx
4
- var r = ({ title: r, description: i, actions: a, children: o, className: s }) => /* @__PURE__ */ n("div", {
5
- className: e("min-h-full p-4 sm:p-6", s),
5
+ var a = ({ title: a, description: o, purpose: s, purposeLearnMoreHref: c, actions: l, children: u, className: d }) => /* @__PURE__ */ n("div", {
6
+ className: e("min-h-full p-4 sm:p-6", d),
6
7
  children: [/* @__PURE__ */ n("div", {
7
- className: "mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
8
- children: [/* @__PURE__ */ n("div", { children: [/* @__PURE__ */ t("h1", {
9
- className: "text-2xl font-bold text-text-primary",
10
- children: r
11
- }), i && /* @__PURE__ */ t("p", {
12
- className: "mt-1 text-sm text-text-secondary",
13
- children: i
14
- })] }), a && /* @__PURE__ */ t("div", {
15
- className: "flex items-center gap-2",
16
- children: a
8
+ className: "mb-6 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
9
+ children: [/* @__PURE__ */ n("div", {
10
+ className: "min-w-0",
11
+ children: [
12
+ /* @__PURE__ */ t("h1", {
13
+ className: "text-2xl font-bold text-text-primary",
14
+ children: /* @__PURE__ */ t(r, { children: a })
15
+ }),
16
+ o && /* @__PURE__ */ t("p", {
17
+ className: "mt-1 text-sm text-text-secondary",
18
+ children: o
19
+ }),
20
+ s && /* @__PURE__ */ t(i, {
21
+ className: "mt-2 max-w-3xl",
22
+ learnMoreHref: c,
23
+ children: s
24
+ })
25
+ ]
26
+ }), l && /* @__PURE__ */ t("div", {
27
+ className: "flex flex-wrap items-center gap-2",
28
+ children: l
17
29
  })]
18
- }), o]
30
+ }), u]
19
31
  });
20
32
  //#endregion
21
- export { r as PageLayout };
33
+ export { a as PageLayout };
22
34
 
23
35
  //# sourceMappingURL=PageLayout.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/timecampus/components/PageLayout.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../utils/helpers\";\n\ninterface PageLayoutProps {\n title: string;\n description?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n actions,\n children,\n className,\n}) => {\n return (\n <div className={cn(\"min-h-full p-4 sm:p-6\", className)}>\n <div className=\"mb-6 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-bold text-text-primary\">{title}</h1>\n {description && (\n <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>\n )}\n </div>\n {actions && <div className=\"flex items-center gap-2\">{actions}</div>}\n </div>\n {children}\n </div>\n );\n};\n"],"mappings":";;;AAWA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,aACA,mBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,yBAAyB,EAAU;WAAtD,CACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,MAAD;GAAI,WAAU;aAAwC;GAAW,CAAA,EAChE,KACC,kBAAC,KAAD;GAAG,WAAU;aAAoC;GAAgB,CAAA,CAE/D,EAAA,CAAA,EACL,KAAW,kBAAC,OAAD;GAAK,WAAU;aAA2B;GAAc,CAAA,CAChE;KACL,EACG"}
1
+ {"version":3,"file":"PageLayout.js","names":[],"sources":["../../../src/timecampus/components/PageLayout.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { GradientText, PagePurpose } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/helpers\";\n\ninterface PageLayoutProps {\n title: string;\n description?: string;\n /**\n * The page's \"story\": a concise, plain-language explanation of what this\n * page/feature is for and the real-world use-case. Rendered just under the\n * header so every page is self-explanatory to a new user. Prefer this over a\n * terse `description` for primary pages.\n */\n purpose?: ReactNode;\n /** Optional \"Learn more\" link rendered inline with the purpose copy. */\n purposeLearnMoreHref?: string;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n}\n\nexport const PageLayout: FC<PageLayoutProps> = ({\n title,\n description,\n purpose,\n purposeLearnMoreHref,\n actions,\n children,\n className,\n}) => {\n return (\n <div className={cn(\"min-h-full p-4 sm:p-6\", className)}>\n <div className=\"mb-6 flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>{title}</GradientText>\n </h1>\n {description && (\n <p className=\"mt-1 text-sm text-text-secondary\">{description}</p>\n )}\n {purpose && (\n <PagePurpose\n className=\"mt-2 max-w-3xl\"\n learnMoreHref={purposeLearnMoreHref}\n >\n {purpose}\n </PagePurpose>\n )}\n </div>\n {actions && (\n <div className=\"flex flex-wrap items-center gap-2\">{actions}</div>\n )}\n </div>\n {children}\n </div>\n );\n};\n"],"mappings":";;;;AAqBA,IAAa,KAAmC,EAC9C,UACA,gBACA,YACA,yBACA,YACA,aACA,mBAGE,kBAAC,OAAD;CAAK,WAAW,EAAG,yBAAyB,EAAU;WAAtD,CACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,MAAD;KAAI,WAAU;eACZ,kBAAC,GAAD,EAAA,UAAe,GAAqB,CAAA;KACjC,CAAA;IACJ,KACC,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA;IAElE,KACC,kBAAC,GAAD;KACE,WAAU;KACV,eAAe;eAEd;KACW,CAAA;IAEZ;MACL,KACC,kBAAC,OAAD;GAAK,WAAU;aAAqC;GAAc,CAAA,CAEhE;KACL,EACG"}
@@ -1,9 +1,12 @@
1
1
  import { cn as e } from "../utils/helpers.js";
2
2
  import { ArrowDown as t, ArrowUp as n } from "lucide-react";
3
3
  import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ import { GlassCard as a } from "@burdenoff/fe-libs/ui";
4
5
  //#region src/timecampus/components/StatCard.tsx
5
- var a = ({ title: a, value: o, icon: s, trend: c, description: l, className: u, iconBgColor: d }) => /* @__PURE__ */ r("div", {
6
- className: e("rounded-xl border border-border-subtle bg-bg-surface p-4 sm:p-6", u),
6
+ var o = ({ title: o, value: s, icon: c, trend: l, description: u, className: d, iconBgColor: f, featured: p = !1 }) => /* @__PURE__ */ r(a, {
7
+ treatment: p ? "glass" : "metric",
8
+ glow: p,
9
+ className: e("p-4 sm:p-6", d),
7
10
  children: /* @__PURE__ */ i("div", {
8
11
  className: "flex items-start justify-between",
9
12
  children: [/* @__PURE__ */ i("div", {
@@ -11,38 +14,38 @@ var a = ({ title: a, value: o, icon: s, trend: c, description: l, className: u,
11
14
  children: [
12
15
  /* @__PURE__ */ r("p", {
13
16
  className: "text-sm font-medium text-text-secondary truncate",
14
- children: a
17
+ children: o
15
18
  }),
16
19
  /* @__PURE__ */ r("p", {
17
- className: "mt-2 text-2xl font-bold text-text-primary",
18
- children: o
20
+ className: "mt-2 text-2xl font-bold tabular-nums text-text-primary",
21
+ children: s
19
22
  }),
20
- c && /* @__PURE__ */ i("div", {
23
+ l && /* @__PURE__ */ i("div", {
21
24
  className: "mt-2 flex items-center gap-1",
22
25
  children: [
23
- c.value >= 0 ? /* @__PURE__ */ r(n, { className: "h-3 w-3 text-emerald-500" }) : /* @__PURE__ */ r(t, { className: "h-3 w-3 text-red-500" }),
26
+ l.value >= 0 ? /* @__PURE__ */ r(n, { className: "h-3 w-3 text-status-success-text" }) : /* @__PURE__ */ r(t, { className: "h-3 w-3 text-status-error-text" }),
24
27
  /* @__PURE__ */ i("span", {
25
- className: e("text-xs font-medium", c.value >= 0 ? "text-emerald-600 dark:text-emerald-400" : "text-red-600 dark:text-red-400"),
26
- children: [Math.abs(c.value), "%"]
28
+ className: e("text-xs font-medium tabular-nums", l.value >= 0 ? "text-status-success-text" : "text-status-error-text"),
29
+ children: [Math.abs(l.value), "%"]
27
30
  }),
28
31
  /* @__PURE__ */ r("span", {
29
32
  className: "text-xs text-text-secondary",
30
- children: c.label
33
+ children: l.label
31
34
  })
32
35
  ]
33
36
  }),
34
- l && /* @__PURE__ */ r("p", {
37
+ u && /* @__PURE__ */ r("p", {
35
38
  className: "mt-1 text-xs text-text-secondary",
36
- children: l
39
+ children: u
37
40
  })
38
41
  ]
39
- }), s && /* @__PURE__ */ r("div", {
40
- className: e("flex h-10 w-10 shrink-0 items-center justify-center rounded-lg", d || "bg-action-primary-bg/10 text-primary"),
41
- children: s
42
+ }), c && /* @__PURE__ */ r("div", {
43
+ className: e("flex h-10 w-10 shrink-0 items-center justify-center rounded-lg", f || "bg-action-primary-bg/10 text-primary"),
44
+ children: c
42
45
  })]
43
46
  })
44
47
  });
45
48
  //#endregion
46
- export { a as StatCard };
49
+ export { o as StatCard };
47
50
 
48
51
  //# sourceMappingURL=StatCard.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StatCard.js","names":[],"sources":["../../../src/timecampus/components/StatCard.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { cn } from \"../utils/helpers\";\nimport { ArrowUp, ArrowDown } from \"lucide-react\";\n\ninterface StatCardProps {\n title: string;\n value: string | number;\n icon?: ReactNode;\n trend?: { value: number; label: string };\n description?: string;\n className?: string;\n iconBgColor?: string;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n title,\n value,\n icon,\n trend,\n description,\n className,\n iconBgColor,\n}) => {\n return (\n <div\n className={cn(\n \"rounded-xl border border-border-subtle bg-bg-surface p-4 sm:p-6\",\n className,\n )}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-secondary truncate\">\n {title}\n </p>\n <p className=\"mt-2 text-2xl font-bold text-text-primary\">\n {value}\n </p>\n {trend && (\n <div className=\"mt-2 flex items-center gap-1\">\n {trend.value >= 0 ? (\n <ArrowUp className=\"h-3 w-3 text-emerald-500\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-red-500\" />\n )}\n <span\n className={cn(\n \"text-xs font-medium\",\n trend.value >= 0\n ? \"text-emerald-600 dark:text-emerald-400\"\n : \"text-red-600 dark:text-red-400\",\n )}\n >\n {Math.abs(trend.value)}%\n </span>\n <span className=\"text-xs text-text-secondary\">\n {trend.label}\n </span>\n </div>\n )}\n {description && (\n <p className=\"mt-1 text-xs text-text-secondary\">{description}</p>\n )}\n </div>\n {icon && (\n <div\n className={cn(\n \"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg\",\n iconBgColor || \"bg-action-primary-bg/10 text-primary\",\n )}\n >\n {icon}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"mappings":";;;;AAcA,IAAa,KAA+B,EAC1C,UACA,UACA,SACA,UACA,gBACA,cACA,qBAGE,kBAAC,OAAD;CACE,WAAW,EACT,mEACA,EACD;WAED,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eACV;KACC,CAAA;IACJ,kBAAC,KAAD;KAAG,WAAU;eACV;KACC,CAAA;IACH,KACC,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAM,SAAS,IACd,kBAAC,GAAD,EAAS,WAAU,4BAA6B,CAAA,GAEhD,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA;MAEhD,kBAAC,QAAD;OACE,WAAW,EACT,uBACA,EAAM,SAAS,IACX,2CACA,iCACL;iBANH,CAQG,KAAK,IAAI,EAAM,MAAM,EAAC,IAClB;;MACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAM;OACF,CAAA;MACH;;IAEP,KACC,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA;IAE/D;MACL,KACC,kBAAC,OAAD;GACE,WAAW,EACT,kEACA,KAAe,uCAChB;aAEA;GACG,CAAA,CAEJ;;CACF,CAAA"}
1
+ {"version":3,"file":"StatCard.js","names":[],"sources":["../../../src/timecampus/components/StatCard.tsx"],"sourcesContent":["import type { FC, ReactNode } from \"react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { cn } from \"../utils/helpers\";\nimport { ArrowUp, ArrowDown } from \"lucide-react\";\n\ninterface StatCardProps {\n title: string;\n value: string | number;\n icon?: ReactNode;\n trend?: { value: number; label: string };\n description?: string;\n className?: string;\n iconBgColor?: string;\n /** Render the featured/hero metric with a richer glass + glow treatment. */\n featured?: boolean;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n title,\n value,\n icon,\n trend,\n description,\n className,\n iconBgColor,\n featured = false,\n}) => {\n return (\n <GlassCard\n treatment={featured ? \"glass\" : \"metric\"}\n glow={featured}\n className={cn(\"p-4 sm:p-6\", className)}\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-secondary truncate\">\n {title}\n </p>\n <p className=\"mt-2 text-2xl font-bold tabular-nums text-text-primary\">\n {value}\n </p>\n {trend && (\n <div className=\"mt-2 flex items-center gap-1\">\n {trend.value >= 0 ? (\n <ArrowUp className=\"h-3 w-3 text-status-success-text\" />\n ) : (\n <ArrowDown className=\"h-3 w-3 text-status-error-text\" />\n )}\n <span\n className={cn(\n \"text-xs font-medium tabular-nums\",\n trend.value >= 0\n ? \"text-status-success-text\"\n : \"text-status-error-text\",\n )}\n >\n {Math.abs(trend.value)}%\n </span>\n <span className=\"text-xs text-text-secondary\">{trend.label}</span>\n </div>\n )}\n {description && (\n <p className=\"mt-1 text-xs text-text-secondary\">{description}</p>\n )}\n </div>\n {icon && (\n <div\n className={cn(\n \"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg\",\n iconBgColor || \"bg-action-primary-bg/10 text-primary\",\n )}\n >\n {icon}\n </div>\n )}\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;AAiBA,IAAa,KAA+B,EAC1C,UACA,UACA,SACA,UACA,gBACA,cACA,gBACA,cAAW,SAGT,kBAAC,GAAD;CACE,WAAW,IAAW,UAAU;CAChC,MAAM;CACN,WAAW,EAAG,cAAc,EAAU;WAEtC,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,KAAD;KAAG,WAAU;eACV;KACC,CAAA;IACJ,kBAAC,KAAD;KAAG,WAAU;eACV;KACC,CAAA;IACH,KACC,kBAAC,OAAD;KAAK,WAAU;eAAf;MACG,EAAM,SAAS,IACd,kBAAC,GAAD,EAAS,WAAU,oCAAqC,CAAA,GAExD,kBAAC,GAAD,EAAW,WAAU,kCAAmC,CAAA;MAE1D,kBAAC,QAAD;OACE,WAAW,EACT,oCACA,EAAM,SAAS,IACX,6BACA,yBACL;iBANH,CAQG,KAAK,IAAI,EAAM,MAAM,EAAC,IAClB;;MACP,kBAAC,QAAD;OAAM,WAAU;iBAA+B,EAAM;OAAa,CAAA;MAC9D;;IAEP,KACC,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAgB,CAAA;IAE/D;MACL,KACC,kBAAC,OAAD;GACE,WAAW,EACT,kEACA,KAAe,uCAChB;aAEA;GACG,CAAA,CAEJ;;CACI,CAAA"}