@burdenoff/microfe-timecampus 2026.608.1 → 2026.625.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 (107) hide show
  1. package/dist/timecampus/components/ErrorBoundary.js +4 -4
  2. package/dist/timecampus/components/ErrorBoundary.js.map +1 -1
  3. package/dist/timecampus/components/LoadingSkeleton.js +8 -8
  4. package/dist/timecampus/components/LoadingSkeleton.js.map +1 -1
  5. package/dist/timecampus/components/PageLayout.js +17 -13
  6. package/dist/timecampus/components/PageLayout.js.map +1 -1
  7. package/dist/timecampus/components/StatCard.js +22 -19
  8. package/dist/timecampus/components/StatCard.js.map +1 -1
  9. package/dist/timecampus/pages/HomePage.js +183 -163
  10. package/dist/timecampus/pages/HomePage.js.map +1 -1
  11. package/dist/timecampus/pages/applets/AppletStorePage.js +17 -17
  12. package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
  13. package/dist/timecampus/pages/applets/InstalledAppletsPage.js +18 -18
  14. package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
  15. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +28 -28
  16. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
  17. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +19 -19
  18. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
  19. package/dist/timecampus/pages/channels/ChannelsPage.js +15 -15
  20. package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
  21. package/dist/timecampus/pages/client-portal/ClientPortalPage.js +22 -22
  22. package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
  23. package/dist/timecampus/pages/dashboard/AnalyticsPage.js +20 -20
  24. package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
  25. package/dist/timecampus/pages/dashboard/ReportsPage.js +20 -20
  26. package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
  27. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +18 -18
  28. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
  29. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +22 -22
  30. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
  31. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +14 -14
  32. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
  33. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +22 -22
  34. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
  35. package/dist/timecampus/pages/focus-score/FocusScorePage.js +27 -27
  36. package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
  37. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +19 -19
  38. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
  39. package/dist/timecampus/pages/geofencing/GeofencingPage.js +16 -16
  40. package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
  41. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +18 -18
  42. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
  43. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +16 -16
  44. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
  45. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +21 -21
  46. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
  47. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +22 -22
  48. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
  49. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +18 -18
  50. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
  51. package/dist/timecampus/pages/meetings/MeetingCreatePage.js +16 -16
  52. package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
  53. package/dist/timecampus/pages/meetings/MeetingDetailPage.js +29 -29
  54. package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
  55. package/dist/timecampus/pages/meetings/MeetingsPage.js +20 -20
  56. package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
  57. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +23 -23
  58. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
  59. package/dist/timecampus/pages/pomodoro/PomodoroPage.js +23 -23
  60. package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
  61. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +30 -30
  62. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
  63. package/dist/timecampus/pages/projects/ProjectCreatePage.js +19 -19
  64. package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
  65. package/dist/timecampus/pages/projects/ProjectDetailPage.js +23 -23
  66. package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
  67. package/dist/timecampus/pages/projects/ProjectsPage.js +20 -20
  68. package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
  69. package/dist/timecampus/pages/projects/TasksPage.js +15 -15
  70. package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
  71. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +25 -25
  72. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
  73. package/dist/timecampus/pages/team/TeamAnalyticsPage.js +19 -19
  74. package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
  75. package/dist/timecampus/pages/team/TeamMembersPage.js +21 -21
  76. package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
  77. package/dist/timecampus/pages/team/TeamPage.js +19 -19
  78. package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
  79. package/dist/timecampus/pages/team-activity/TeamActivityPage.js +21 -21
  80. package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
  81. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +20 -20
  82. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
  83. package/dist/timecampus/pages/templates/TemplateApplicationPage.js +16 -16
  84. package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
  85. package/dist/timecampus/pages/templates/TemplateDetailPage.js +21 -21
  86. package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
  87. package/dist/timecampus/pages/templates/TemplatesPage.js +16 -16
  88. package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
  89. package/dist/timecampus/pages/time/TimeEntriesPage.js +25 -25
  90. package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
  91. package/dist/timecampus/pages/time/TimeTrackingPage.js +24 -24
  92. package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
  93. package/dist/timecampus/pages/time/TimerPage.js +20 -20
  94. package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
  95. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +27 -27
  96. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
  97. package/dist/timecampus/pages/widgets/WidgetDetailPage.js +20 -20
  98. package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
  99. package/dist/timecampus/pages/widgets/WidgetsPage.js +18 -18
  100. package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
  101. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +23 -23
  102. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
  103. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +19 -19
  104. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
  105. package/dist/timecampus/pages/workflows/WorkflowsPage.js +17 -17
  106. package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
  107. package/package.json +2 -2
@@ -1,94 +1,94 @@
1
1
  import { formatDate as e, formatHours as t, getStatusColor as n } from "../../utils/helpers.js";
2
- import { PageLayout as r } from "../../components/PageLayout.js";
3
- import { LoadingSkeleton as i } from "../../components/LoadingSkeleton.js";
4
- import { useListTimeEntriesQuery as a } from "../../../generated/wspace-operations.js";
2
+ import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
3
+ import { useListTimeEntriesQuery as i } from "../../../generated/wspace-operations.js";
4
+ import { PageLayout as a } from "../../components/PageLayout.js";
5
5
  import { Filter as o, Plus as s } from "lucide-react";
6
6
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
7
  //#region src/timecampus/pages/time/TimeEntriesPage.tsx
8
8
  function u() {
9
- let { data: u, loading: d, error: f } = a({ variables: { limit: 50 } }), p = u?.timeEntries?.items ?? [];
10
- return f ? /* @__PURE__ */ c(r, {
9
+ let { data: u, loading: d, error: f } = i({ variables: { limit: 50 } }), p = u?.timeEntries?.items ?? [];
10
+ return f ? /* @__PURE__ */ c(a, {
11
11
  title: "Time Entries",
12
12
  description: "View and manage all time entries",
13
13
  children: /* @__PURE__ */ c("div", {
14
- className: "rounded-xl border border-red-200 bg-red-50 p-6 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/50 dark:text-red-400",
14
+ className: "rounded-xl border border-status-error-bg/40 bg-status-error-bg p-6 text-sm text-status-error-text",
15
15
  children: "Failed to load time entries. Please try again later."
16
16
  })
17
- }) : /* @__PURE__ */ c(r, {
17
+ }) : /* @__PURE__ */ c(a, {
18
18
  title: "Time Entries",
19
19
  description: "View and manage all time entries",
20
20
  actions: /* @__PURE__ */ l("div", {
21
21
  className: "flex items-center gap-2",
22
22
  children: [/* @__PURE__ */ l("button", {
23
- className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground hover:bg-muted/50",
23
+ className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
24
24
  children: [/* @__PURE__ */ c(o, { className: "h-4 w-4" }), "Filter"]
25
25
  }), /* @__PURE__ */ l("button", {
26
- className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
26
+ className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
27
27
  children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Add Entry"]
28
28
  })]
29
29
  }),
30
- children: d ? /* @__PURE__ */ c(i, {
30
+ children: d ? /* @__PURE__ */ c(r, {
31
31
  variant: "table",
32
32
  count: 5
33
33
  }) : /* @__PURE__ */ c("div", {
34
- className: "rounded-xl border border-border bg-card",
34
+ className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop",
35
35
  children: /* @__PURE__ */ c("div", {
36
36
  className: "overflow-x-auto",
37
37
  children: /* @__PURE__ */ l("table", {
38
38
  className: "w-full",
39
39
  children: [/* @__PURE__ */ c("thead", { children: /* @__PURE__ */ l("tr", {
40
- className: "border-b border-border",
40
+ className: "border-b border-border-subtle",
41
41
  children: [
42
42
  /* @__PURE__ */ c("th", {
43
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
43
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
44
44
  children: "Date"
45
45
  }),
46
46
  /* @__PURE__ */ c("th", {
47
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
47
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
48
48
  children: "Project"
49
49
  }),
50
50
  /* @__PURE__ */ c("th", {
51
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
51
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
52
52
  children: "Task"
53
53
  }),
54
54
  /* @__PURE__ */ c("th", {
55
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
55
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
56
56
  children: "Duration"
57
57
  }),
58
58
  /* @__PURE__ */ c("th", {
59
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
59
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
60
60
  children: "Billable"
61
61
  }),
62
62
  /* @__PURE__ */ c("th", {
63
- className: "px-4 py-3 text-left text-xs font-medium text-muted-foreground",
63
+ className: "px-4 py-3 text-left text-xs font-medium text-text-secondary",
64
64
  children: "Status"
65
65
  })
66
66
  ]
67
67
  }) }), /* @__PURE__ */ l("tbody", {
68
68
  className: "divide-y divide-border",
69
69
  children: [p.map((r) => /* @__PURE__ */ l("tr", {
70
- className: "hover:bg-muted/50 transition-colors",
70
+ className: "hover:bg-bg-sunken/50 transition-colors",
71
71
  children: [
72
72
  /* @__PURE__ */ c("td", {
73
- className: "px-4 py-3 text-sm text-muted-foreground",
73
+ className: "px-4 py-3 text-sm text-text-secondary",
74
74
  children: e(r.startTime)
75
75
  }),
76
76
  /* @__PURE__ */ c("td", {
77
- className: "px-4 py-3 text-sm font-medium text-foreground",
77
+ className: "px-4 py-3 text-sm font-medium text-text-primary",
78
78
  children: r.project?.name ?? "No Project"
79
79
  }),
80
80
  /* @__PURE__ */ c("td", {
81
- className: "px-4 py-3 text-sm text-muted-foreground",
81
+ className: "px-4 py-3 text-sm text-text-secondary",
82
82
  children: r.task?.title ?? r.description ?? "No description"
83
83
  }),
84
84
  /* @__PURE__ */ c("td", {
85
- className: "px-4 py-3 text-sm font-mono text-foreground",
85
+ className: "px-4 py-3 text-sm font-mono text-text-primary",
86
86
  children: t((r.duration ?? 0) / 3600)
87
87
  }),
88
88
  /* @__PURE__ */ c("td", {
89
89
  className: "px-4 py-3",
90
90
  children: /* @__PURE__ */ c("span", {
91
- className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${r.billable ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400" : "bg-gray-100 text-gray-600 dark:bg-gray-900/30 dark:text-gray-400"}`,
91
+ className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${r.billable ? "bg-status-success-bg text-status-success-text" : "bg-bg-sunken text-text-secondary"}`,
92
92
  children: r.billable ? "Yes" : "No"
93
93
  })
94
94
  }),
@@ -102,7 +102,7 @@ function u() {
102
102
  ]
103
103
  }, r.id)), p.length === 0 && /* @__PURE__ */ c("tr", { children: /* @__PURE__ */ c("td", {
104
104
  colSpan: 6,
105
- className: "px-4 py-8 text-center text-sm text-muted-foreground",
105
+ className: "px-4 py-8 text-center text-sm text-text-secondary",
106
106
  children: "No time entries found"
107
107
  }) })]
108
108
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"TimeEntriesPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeEntriesPage.tsx"],"sourcesContent":["import { Clock, Plus, Filter } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, formatDate, getStatusColor } from \"../../utils/helpers\";\nimport {\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function TimeEntriesPage() {\n const { data, loading, error } = useListTimeEntriesQuery({\n variables: { limit: 50 },\n });\n\n const entries = data?.timeEntries?.items ?? [];\n\n if (error) {\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n >\n <div className=\"rounded-xl border border-red-200 bg-red-50 p-6 text-sm text-red-700 dark:border-red-900 dark:bg-red-950/50 dark:text-red-400\">\n Failed to load time entries. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n actions={\n <div className=\"flex items-center gap-2\">\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-foreground hover:bg-muted/50\">\n <Filter className=\"h-4 w-4\" />\n Filter\n </button>\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90\">\n <Plus className=\"h-4 w-4\" />\n Add Entry\n </button>\n </div>\n }\n >\n {loading ? (\n <LoadingSkeleton variant=\"table\" count={5} />\n ) : (\n <div className=\"rounded-xl border border-border bg-card\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Date\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Project\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Task\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Duration\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Billable\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-muted-foreground\">\n Status\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {entries.map((entry: TimeEntryFieldsFragment) => (\n <tr\n key={entry.id}\n className=\"hover:bg-muted/50 transition-colors\"\n >\n <td className=\"px-4 py-3 text-sm text-muted-foreground\">\n {formatDate(entry.startTime)}\n </td>\n <td className=\"px-4 py-3 text-sm font-medium text-foreground\">\n {entry.project?.name ?? \"No Project\"}\n </td>\n <td className=\"px-4 py-3 text-sm text-muted-foreground\">\n {entry.task?.title ??\n entry.description ??\n \"No description\"}\n </td>\n <td className=\"px-4 py-3 text-sm font-mono text-foreground\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${entry.billable ? \"bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400\" : \"bg-gray-100 text-gray-600 dark:bg-gray-900/30 dark:text-gray-400\"}`}\n >\n {entry.billable ? \"Yes\" : \"No\"}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(entry.isRunning ? \"running\" : \"completed\")}`}\n >\n {entry.isRunning ? \"running\" : \"completed\"}\n </span>\n </td>\n </tr>\n ))}\n {entries.length === 0 && (\n <tr>\n <td\n colSpan={6}\n className=\"px-4 py-8 text-center text-sm text-muted-foreground\"\n >\n No time entries found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AASA,SAAgB,IAAkB;CAChC,IAAM,EAAE,SAAM,YAAS,aAAU,EAAwB,EACvD,WAAW,EAAE,OAAO,IAAI,EACzB,CAAC,EAEI,IAAU,GAAM,aAAa,SAAS,EAAE;AAe9C,QAbI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,SAEvB;OACT,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YAErB;MACL;;YAGP,IACC,kBAAC,GAAD;GAAiB,SAAQ;GAAQ,OAAO;GAAK,CAAA,GAE7C,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAAgE;QAEzE,CAAA;OACF;SACC,CAAA,EACR,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACG,EAAQ,KAAK,MACZ,kBAAC,MAAD;OAEE,WAAU;iBAFZ;QAIE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAW,EAAM,UAAU;SACzB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,SAAS,QAAQ;SACrB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,MAAM,SACX,EAAM,eACN;SACC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,GAAa,EAAM,YAAY,KAAK,KAAK;SACvC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAM,WAAW,iFAAiF;oBAExK,EAAM,WAAW,QAAQ;UACrB,CAAA;SACJ,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAe,EAAM,YAAY,YAAY,YAAY;oBAE/H,EAAM,YAAY,YAAY;UAC1B,CAAA;SACJ,CAAA;QACF;SA/BE,EAAM,GA+BR,CACL,EACD,EAAQ,WAAW,KAClB,kBAAC,MAAD,EAAA,UACE,kBAAC,MAAD;OACE,SAAS;OACT,WAAU;iBACX;OAEI,CAAA,EACF,CAAA,CAED;QACF;;IACJ,CAAA;GACF,CAAA;EAEG,CAAA"}
1
+ {"version":3,"file":"TimeEntriesPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeEntriesPage.tsx"],"sourcesContent":["import { Clock, Plus, Filter } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, formatDate, getStatusColor } from \"../../utils/helpers\";\nimport {\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function TimeEntriesPage() {\n const { data, loading, error } = useListTimeEntriesQuery({\n variables: { limit: 50 },\n });\n\n const entries = data?.timeEntries?.items ?? [];\n\n if (error) {\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n >\n <div className=\"rounded-xl border border-status-error-bg/40 bg-status-error-bg p-6 text-sm text-status-error-text\">\n Failed to load time entries. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Time Entries\"\n description=\"View and manage all time entries\"\n actions={\n <div className=\"flex items-center gap-2\">\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <Filter className=\"h-4 w-4\" />\n Filter\n </button>\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Add Entry\n </button>\n </div>\n }\n >\n {loading ? (\n <LoadingSkeleton variant=\"table\" count={5} />\n ) : (\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n <div className=\"overflow-x-auto\">\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b border-border-subtle\">\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Date\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Project\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Task\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Duration\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Billable\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium text-text-secondary\">\n Status\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {entries.map((entry: TimeEntryFieldsFragment) => (\n <tr\n key={entry.id}\n className=\"hover:bg-bg-sunken/50 transition-colors\"\n >\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {formatDate(entry.startTime)}\n </td>\n <td className=\"px-4 py-3 text-sm font-medium text-text-primary\">\n {entry.project?.name ?? \"No Project\"}\n </td>\n <td className=\"px-4 py-3 text-sm text-text-secondary\">\n {entry.task?.title ??\n entry.description ??\n \"No description\"}\n </td>\n <td className=\"px-4 py-3 text-sm font-mono text-text-primary\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${entry.billable ? \"bg-status-success-bg text-status-success-text\" : \"bg-bg-sunken text-text-secondary\"}`}\n >\n {entry.billable ? \"Yes\" : \"No\"}\n </span>\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(entry.isRunning ? \"running\" : \"completed\")}`}\n >\n {entry.isRunning ? \"running\" : \"completed\"}\n </span>\n </td>\n </tr>\n ))}\n {entries.length === 0 && (\n <tr>\n <td\n colSpan={6}\n className=\"px-4 py-8 text-center text-sm text-text-secondary\"\n >\n No time entries found\n </td>\n </tr>\n )}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AASA,SAAgB,IAAkB;CAChC,IAAM,EAAE,SAAM,YAAS,aAAU,EAAwB,EACvD,WAAW,EAAE,OAAO,IAAI,EACzB,CAAC,EAEI,IAAU,GAAM,aAAa,SAAS,EAAE;AAe9C,QAbI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,SAEvB;OACT,kBAAC,UAAD;IAAQ,WAAU;cAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YAErB;MACL;;YAGP,IACC,kBAAC,GAAD;GAAiB,SAAQ;GAAQ,OAAO;GAAK,CAAA,GAE7C,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OACE,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACL,kBAAC,MAAD;QAAI,WAAU;kBAA8D;QAEvE,CAAA;OACF;SACC,CAAA,EACR,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACG,EAAQ,KAAK,MACZ,kBAAC,MAAD;OAEE,WAAU;iBAFZ;QAIE,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAW,EAAM,UAAU;SACzB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,SAAS,QAAQ;SACrB,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,EAAM,MAAM,SACX,EAAM,eACN;SACC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACX,GAAa,EAAM,YAAY,KAAK,KAAK;SACvC,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAM,WAAW,kDAAkD;oBAEzI,EAAM,WAAW,QAAQ;UACrB,CAAA;SACJ,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBACZ,kBAAC,QAAD;UACE,WAAW,4DAA4D,EAAe,EAAM,YAAY,YAAY,YAAY;oBAE/H,EAAM,YAAY,YAAY;UAC1B,CAAA;SACJ,CAAA;QACF;SA/BE,EAAM,GA+BR,CACL,EACD,EAAQ,WAAW,KAClB,kBAAC,MAAD,EAAA,UACE,kBAAC,MAAD;OACE,SAAS;OACT,WAAU;iBACX;OAEI,CAAA,EACF,CAAA,CAED;QACF;;IACJ,CAAA;GACF,CAAA;EAEG,CAAA"}
@@ -1,9 +1,9 @@
1
1
  import { formatHours as e, formatTimerDuration as t } from "../../utils/helpers.js";
2
- import { PageLayout as n } from "../../components/PageLayout.js";
3
- import { StatCard as r } from "../../components/StatCard.js";
4
- import { LoadingSkeleton as i } from "../../components/LoadingSkeleton.js";
5
- import { useTimeCampusStore as a } from "../../store/timecampusStore.js";
6
- import { useGetTimeEntryStatsQuery as o, useListTimeEntriesQuery as s } from "../../../generated/wspace-operations.js";
2
+ import { StatCard as n } from "../../components/StatCard.js";
3
+ import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
4
+ import { useTimeCampusStore as i } from "../../store/timecampusStore.js";
5
+ import { useGetTimeEntryStatsQuery as a, useListTimeEntriesQuery as o } from "../../../generated/wspace-operations.js";
6
+ import { PageLayout as s } from "../../components/PageLayout.js";
7
7
  import { Clock as c, Pause as l, Play as u, Square as d } from "lucide-react";
8
8
  import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
9
9
  import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
@@ -12,20 +12,20 @@ function g() {
12
12
  let { t: g } = h(), _ = (e, t) => {
13
13
  let n = g(e);
14
14
  return n === e ? t : n;
15
- }, { activeTimer: v, startTimer: y, stopTimer: b } = a(), { data: x, loading: S } = o(), { data: C, loading: w } = s({ variables: { limit: 10 } }), T = x?.timeEntryStats, E = C?.timeEntries?.items ?? [];
16
- return S ? /* @__PURE__ */ p(n, {
15
+ }, { activeTimer: v, startTimer: y, stopTimer: b } = i(), { data: x, loading: S } = a(), { data: C, loading: w } = o({ variables: { limit: 10 } }), T = x?.timeEntryStats, E = C?.timeEntries?.items ?? [];
16
+ return S ? /* @__PURE__ */ p(s, {
17
17
  title: _("timecampus.timeTracking.title", "Time Tracking"),
18
18
  description: _("timecampus.timeTracking.description", "Track and manage your work hours"),
19
- children: /* @__PURE__ */ p(i, {
19
+ children: /* @__PURE__ */ p(r, {
20
20
  variant: "card",
21
21
  count: 4
22
22
  })
23
- }) : /* @__PURE__ */ m(n, {
23
+ }) : /* @__PURE__ */ m(s, {
24
24
  title: _("timecampus.timeTracking.title", "Time Tracking"),
25
25
  description: _("timecampus.timeTracking.description", "Track and manage your work hours"),
26
26
  actions: /* @__PURE__ */ p("button", {
27
27
  onClick: () => v ? b() : y(),
28
- className: `inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium ${v ? "bg-red-500 text-white hover:bg-red-600" : "bg-primary text-primary-foreground hover:bg-primary/90"}`,
28
+ className: `inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium ${v ? "bg-action-danger-bg text-action-primary-text hover:bg-action-danger-bg/90" : "bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90"}`,
29
29
  children: v ? /* @__PURE__ */ m(f, { children: [
30
30
  /* @__PURE__ */ p(d, { className: "h-4 w-4" }),
31
31
  _("timecampus.timeTracking.actions.stop", "Stop"),
@@ -37,7 +37,7 @@ function g() {
37
37
  children: [/* @__PURE__ */ m("div", {
38
38
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
39
39
  children: [
40
- /* @__PURE__ */ p(r, {
40
+ /* @__PURE__ */ p(n, {
41
41
  title: _("timecampus.timeTracking.stats.today", "Today"),
42
42
  value: e(T?.totalHours ?? 0),
43
43
  icon: /* @__PURE__ */ p(c, { className: "h-5 w-5" }),
@@ -46,58 +46,58 @@ function g() {
46
46
  label: _("timecampus.timeTracking.stats.vsYesterday", "vs yesterday")
47
47
  }
48
48
  }),
49
- /* @__PURE__ */ p(r, {
49
+ /* @__PURE__ */ p(n, {
50
50
  title: _("timecampus.timeTracking.stats.billable", "Billable"),
51
51
  value: e(T?.billableHours ?? 0),
52
52
  icon: /* @__PURE__ */ p(c, { className: "h-5 w-5" }),
53
53
  description: `${T?.totalEntries ?? 0} ${_("timecampus.timeTracking.stats.entries", "entries")}`
54
54
  }),
55
- /* @__PURE__ */ p(r, {
55
+ /* @__PURE__ */ p(n, {
56
56
  title: _("timecampus.timeTracking.stats.activeTimers", "Active Timers"),
57
57
  value: T?.activeTimers ?? 0,
58
58
  icon: /* @__PURE__ */ p(c, { className: "h-5 w-5" }),
59
59
  description: _("timecampus.timeTracking.stats.currentlyRunning", "Currently running")
60
60
  }),
61
- /* @__PURE__ */ p(r, {
61
+ /* @__PURE__ */ p(n, {
62
62
  title: _("timecampus.timeTracking.stats.activeTimer", "Active Timer"),
63
63
  value: v ? t(v.seconds) : _("timecampus.timeTracking.stats.stopped", "Stopped"),
64
64
  icon: p(v ? l : u, { className: "h-5 w-5" })
65
65
  })
66
66
  ]
67
67
  }), /* @__PURE__ */ m("div", {
68
- className: "rounded-xl border border-border bg-card p-6",
68
+ className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
69
69
  children: [/* @__PURE__ */ p("h3", {
70
- className: "mb-4 text-sm font-semibold text-foreground",
70
+ className: "mb-4 text-sm font-semibold text-text-primary",
71
71
  children: _("timecampus.timeTracking.entries.title", "Today's Entries")
72
- }), w ? /* @__PURE__ */ p(i, {
72
+ }), w ? /* @__PURE__ */ p(r, {
73
73
  variant: "list",
74
74
  count: 4
75
75
  }) : E.length === 0 ? /* @__PURE__ */ p("div", {
76
- className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
76
+ className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
77
77
  children: /* @__PURE__ */ p("p", {
78
- className: "text-sm text-muted-foreground",
78
+ className: "text-sm text-text-secondary",
79
79
  children: _("timecampus.timeTracking.entries.empty", "No time entries yet. Start a timer to begin tracking.")
80
80
  })
81
81
  }) : /* @__PURE__ */ p("div", {
82
82
  className: "flex flex-col gap-2",
83
83
  children: E.map((t) => /* @__PURE__ */ m("div", {
84
- className: "flex items-center justify-between rounded-lg border border-border p-3 transition-colors hover:bg-muted/50",
84
+ className: "flex items-center justify-between rounded-lg border border-border-subtle p-3 transition-colors hover:bg-bg-sunken/50",
85
85
  children: [/* @__PURE__ */ m("div", {
86
86
  className: "min-w-0 flex-1",
87
87
  children: [/* @__PURE__ */ p("p", {
88
- className: "text-sm font-medium text-foreground",
88
+ className: "text-sm font-medium text-text-primary",
89
89
  children: t.project?.name ?? _("timecampus.timeTracking.entries.noProject", "No Project")
90
90
  }), /* @__PURE__ */ p("p", {
91
- className: "text-xs text-muted-foreground",
91
+ className: "text-xs text-text-secondary",
92
92
  children: t.description ?? _("timecampus.timeTracking.entries.noDescription", "No description")
93
93
  })]
94
94
  }), /* @__PURE__ */ m("div", {
95
95
  className: "ml-4 text-right",
96
96
  children: [/* @__PURE__ */ p("p", {
97
- className: "text-sm font-mono font-medium text-foreground",
97
+ className: "text-sm font-mono font-medium text-text-primary",
98
98
  children: e((t.duration ?? 0) / 3600)
99
99
  }), /* @__PURE__ */ p("span", {
100
- className: "inline-flex items-center rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400",
100
+ className: "inline-flex items-center rounded-full bg-status-success-bg px-2 py-0.5 text-xs font-medium text-status-success-text",
101
101
  children: t.isRunning ? _("timecampus.timeTracking.entries.status.running", "running") : _("timecampus.timeTracking.entries.status.completed", "completed")
102
102
  })]
103
103
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"TimeTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeTrackingPage.tsx"],"sourcesContent":["import { Clock, Play, Pause, Square } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useGetTimeEntryStatsQuery,\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\n\nexport function TimeTrackingPage() {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: statsData, loading: statsLoading } =\n useGetTimeEntryStatsQuery();\n const { data: entriesData, loading: entriesLoading } =\n useListTimeEntriesQuery({\n variables: { limit: 10 },\n });\n\n const stats = statsData?.timeEntryStats;\n const todayEntries = entriesData?.timeEntries?.items ?? [];\n\n if (statsLoading) {\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n actions={\n <button\n onClick={() => (activeTimer ? stopTimer() : startTimer())}\n className={`inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium ${activeTimer ? \"bg-red-500 text-white hover:bg-red-600\" : \"bg-primary text-primary-foreground hover:bg-primary/90\"}`}\n >\n {activeTimer ? (\n <>\n <Square className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.stop\", \"Stop\")} (\n {formatTimerDuration(activeTimer.seconds)})\n </>\n ) : (\n <>\n <Play className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.startTimer\", \"Start Timer\")}\n </>\n )}\n </button>\n }\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title={t(\"timecampus.timeTracking.stats.today\", \"Today\")}\n value={formatHours(stats?.totalHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{\n value: 15,\n label: t(\n \"timecampus.timeTracking.stats.vsYesterday\",\n \"vs yesterday\",\n ),\n }}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.billable\", \"Billable\")}\n value={formatHours(stats?.billableHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n description={`${stats?.totalEntries ?? 0} ${t(\"timecampus.timeTracking.stats.entries\", \"entries\")}`}\n />\n <StatCard\n title={t(\n \"timecampus.timeTracking.stats.activeTimers\",\n \"Active Timers\",\n )}\n value={stats?.activeTimers ?? 0}\n icon={<Clock className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.timeTracking.stats.currentlyRunning\",\n \"Currently running\",\n )}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.activeTimer\", \"Active Timer\")}\n value={\n activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : t(\"timecampus.timeTracking.stats.stopped\", \"Stopped\")\n }\n icon={\n activeTimer ? (\n <Pause className=\"h-5 w-5\" />\n ) : (\n <Play className=\"h-5 w-5\" />\n )\n }\n />\n </div>\n\n <div className=\"rounded-xl border border-border bg-card p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-foreground\">\n {t(\"timecampus.timeTracking.entries.title\", \"Today's Entries\")}\n </h3>\n {entriesLoading ? (\n <LoadingSkeleton variant=\"list\" count={4} />\n ) : todayEntries.length === 0 ? (\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border\">\n <p className=\"text-sm text-muted-foreground\">\n {t(\n \"timecampus.timeTracking.entries.empty\",\n \"No time entries yet. Start a timer to begin tracking.\",\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {todayEntries.map((entry: TimeEntryFieldsFragment) => (\n <div\n key={entry.id}\n className=\"flex items-center justify-between rounded-lg border border-border p-3 transition-colors hover:bg-muted/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-foreground\">\n {entry.project?.name ??\n t(\n \"timecampus.timeTracking.entries.noProject\",\n \"No Project\",\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {entry.description ??\n t(\n \"timecampus.timeTracking.entries.noDescription\",\n \"No description\",\n )}\n </p>\n </div>\n <div className=\"ml-4 text-right\">\n <p className=\"text-sm font-mono font-medium text-foreground\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </p>\n <span className=\"inline-flex items-center rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400\">\n {entry.isRunning\n ? t(\n \"timecampus.timeTracking.entries.status.running\",\n \"running\",\n )\n : t(\n \"timecampus.timeTracking.entries.status.completed\",\n \"completed\",\n )}\n </span>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TimeTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeTrackingPage.tsx"],"sourcesContent":["import { Clock, Play, Pause, Square } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useGetTimeEntryStatsQuery,\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\n\nexport function TimeTrackingPage() {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: statsData, loading: statsLoading } =\n useGetTimeEntryStatsQuery();\n const { data: entriesData, loading: entriesLoading } =\n useListTimeEntriesQuery({\n variables: { limit: 10 },\n });\n\n const stats = statsData?.timeEntryStats;\n const todayEntries = entriesData?.timeEntries?.items ?? [];\n\n if (statsLoading) {\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n actions={\n <button\n onClick={() => (activeTimer ? stopTimer() : startTimer())}\n className={`inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium ${activeTimer ? \"bg-action-danger-bg text-action-primary-text hover:bg-action-danger-bg/90\" : \"bg-action-primary-bg text-action-primary-text hover:bg-action-primary-bg/90\"}`}\n >\n {activeTimer ? (\n <>\n <Square className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.stop\", \"Stop\")} (\n {formatTimerDuration(activeTimer.seconds)})\n </>\n ) : (\n <>\n <Play className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.startTimer\", \"Start Timer\")}\n </>\n )}\n </button>\n }\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title={t(\"timecampus.timeTracking.stats.today\", \"Today\")}\n value={formatHours(stats?.totalHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{\n value: 15,\n label: t(\n \"timecampus.timeTracking.stats.vsYesterday\",\n \"vs yesterday\",\n ),\n }}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.billable\", \"Billable\")}\n value={formatHours(stats?.billableHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n description={`${stats?.totalEntries ?? 0} ${t(\"timecampus.timeTracking.stats.entries\", \"entries\")}`}\n />\n <StatCard\n title={t(\n \"timecampus.timeTracking.stats.activeTimers\",\n \"Active Timers\",\n )}\n value={stats?.activeTimers ?? 0}\n icon={<Clock className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.timeTracking.stats.currentlyRunning\",\n \"Currently running\",\n )}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.activeTimer\", \"Active Timer\")}\n value={\n activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : t(\"timecampus.timeTracking.stats.stopped\", \"Stopped\")\n }\n icon={\n activeTimer ? (\n <Pause className=\"h-5 w-5\" />\n ) : (\n <Play className=\"h-5 w-5\" />\n )\n }\n />\n </div>\n\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n {t(\"timecampus.timeTracking.entries.title\", \"Today's Entries\")}\n </h3>\n {entriesLoading ? (\n <LoadingSkeleton variant=\"list\" count={4} />\n ) : todayEntries.length === 0 ? (\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <p className=\"text-sm text-text-secondary\">\n {t(\n \"timecampus.timeTracking.entries.empty\",\n \"No time entries yet. Start a timer to begin tracking.\",\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {todayEntries.map((entry: TimeEntryFieldsFragment) => (\n <div\n key={entry.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3 transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {entry.project?.name ??\n t(\n \"timecampus.timeTracking.entries.noProject\",\n \"No Project\",\n )}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {entry.description ??\n t(\n \"timecampus.timeTracking.entries.noDescription\",\n \"No description\",\n )}\n </p>\n </div>\n <div className=\"ml-4 text-right\">\n <p className=\"text-sm font-mono font-medium text-text-primary\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </p>\n <span className=\"inline-flex items-center rounded-full bg-status-success-bg px-2 py-0.5 text-xs font-medium text-status-success-text\">\n {entry.isRunning\n ? t(\n \"timecampus.timeTracking.entries.status.running\",\n \"running\",\n )\n : t(\n \"timecampus.timeTracking.entries.status.completed\",\n \"completed\",\n )}\n </span>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1,71 +1,71 @@
1
1
  import { formatTimerDuration as e } from "../../utils/helpers.js";
2
- import { PageLayout as t } from "../../components/PageLayout.js";
3
- import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
4
- import { useTimeCampusStore as r } from "../../store/timecampusStore.js";
5
- import { useListRunningTimersQuery as i } from "../../../generated/wspace-operations.js";
2
+ import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
3
+ import { useTimeCampusStore as n } from "../../store/timecampusStore.js";
4
+ import { useListRunningTimersQuery as r } from "../../../generated/wspace-operations.js";
5
+ import { PageLayout as i } from "../../components/PageLayout.js";
6
6
  import { Play as a, RotateCcw as o, Square as s } from "lucide-react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
8
  //#region src/timecampus/pages/time/TimerPage.tsx
9
9
  function u() {
10
- let { activeTimer: u, startTimer: d, stopTimer: f } = r(), { data: p, loading: m } = i(), h = p?.runningTimers ?? [];
11
- return /* @__PURE__ */ c(t, {
10
+ let { activeTimer: u, startTimer: d, stopTimer: f } = n(), { data: p, loading: m } = r(), h = p?.runningTimers ?? [];
11
+ return /* @__PURE__ */ c(i, {
12
12
  title: "Timer",
13
13
  description: "Focus timer for deep work sessions",
14
14
  children: /* @__PURE__ */ l("div", {
15
15
  className: "mx-auto max-w-lg",
16
16
  children: [/* @__PURE__ */ l("div", {
17
- className: "rounded-xl border border-border bg-card p-8 text-center",
17
+ className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-8 text-center",
18
18
  children: [
19
19
  /* @__PURE__ */ c("p", {
20
- className: "text-6xl font-mono font-bold text-foreground",
20
+ className: "text-6xl font-mono font-bold text-text-primary",
21
21
  children: u ? e(u.seconds) : "00:00:00"
22
22
  }),
23
23
  u?.description && /* @__PURE__ */ c("p", {
24
- className: "mt-2 text-sm text-muted-foreground",
24
+ className: "mt-2 text-sm text-text-secondary",
25
25
  children: u.description
26
26
  }),
27
27
  /* @__PURE__ */ l("div", {
28
28
  className: "mt-6 flex items-center justify-center gap-3",
29
29
  children: [u ? /* @__PURE__ */ l("button", {
30
30
  onClick: f,
31
- className: "inline-flex items-center gap-2 rounded-md bg-red-500 px-6 py-3 text-sm font-medium text-white hover:bg-red-600",
31
+ className: "inline-flex items-center gap-2 rounded-md bg-action-danger-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-danger-bg/90",
32
32
  children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Stop"]
33
33
  }) : /* @__PURE__ */ l("button", {
34
34
  onClick: () => d(),
35
- className: "inline-flex items-center gap-2 rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90",
35
+ className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
36
36
  children: [/* @__PURE__ */ c(a, { className: "h-4 w-4" }), "Start"]
37
37
  }), /* @__PURE__ */ l("button", {
38
- className: "inline-flex items-center gap-2 rounded-md border border-border px-4 py-3 text-sm font-medium text-foreground hover:bg-muted/50",
38
+ className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
39
39
  children: [/* @__PURE__ */ c(o, { className: "h-4 w-4" }), "Reset"]
40
40
  })]
41
41
  })
42
42
  ]
43
43
  }), /* @__PURE__ */ l("div", {
44
- className: "mt-6 rounded-xl border border-border bg-card p-6",
44
+ className: "mt-6 rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
45
45
  children: [/* @__PURE__ */ c("h3", {
46
- className: "mb-4 text-sm font-semibold text-foreground",
46
+ className: "mb-4 text-sm font-semibold text-text-primary",
47
47
  children: "Running Timers"
48
- }), m ? /* @__PURE__ */ c(n, {
48
+ }), m ? /* @__PURE__ */ c(t, {
49
49
  variant: "list",
50
50
  count: 2
51
51
  }) : h.length === 0 ? /* @__PURE__ */ c("p", {
52
- className: "text-center text-sm text-muted-foreground py-4",
52
+ className: "text-center text-sm text-text-secondary py-4",
53
53
  children: "No active timers on the server"
54
54
  }) : /* @__PURE__ */ c("div", {
55
55
  className: "flex flex-col gap-2",
56
56
  children: h.map((t) => /* @__PURE__ */ l("div", {
57
- className: "flex items-center justify-between rounded-lg border border-border p-3",
57
+ className: "flex items-center justify-between rounded-lg border border-border-subtle p-3",
58
58
  children: [/* @__PURE__ */ l("div", {
59
59
  className: "min-w-0 flex-1",
60
60
  children: [/* @__PURE__ */ c("p", {
61
- className: "text-sm font-medium text-foreground",
61
+ className: "text-sm font-medium text-text-primary",
62
62
  children: t.timeEntry.project?.name ?? "No Project"
63
63
  }), /* @__PURE__ */ c("p", {
64
- className: "text-xs text-muted-foreground",
64
+ className: "text-xs text-text-secondary",
65
65
  children: t.timeEntry.description ?? "No description"
66
66
  })]
67
67
  }), /* @__PURE__ */ c("p", {
68
- className: "ml-4 text-sm font-mono font-medium text-foreground",
68
+ className: "ml-4 text-sm font-mono font-medium text-text-primary",
69
69
  children: e(t.elapsedSeconds)
70
70
  })]
71
71
  }, t.timeEntry.id))
@@ -1 +1 @@
1
- {"version":3,"file":"TimerPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimerPage.tsx"],"sourcesContent":["import { Play, Square, RotateCcw } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useListRunningTimersQuery,\n type ListRunningTimersQuery,\n} from \"@/generated/wspace-operations\";\n\ntype RunningTimerItem = ListRunningTimersQuery[\"runningTimers\"][number];\n\nexport function TimerPage() {\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: runningData, loading: runningLoading } =\n useListRunningTimersQuery();\n\n const runningTimers = runningData?.runningTimers ?? [];\n\n return (\n <PageLayout title=\"Timer\" description=\"Focus timer for deep work sessions\">\n <div className=\"mx-auto max-w-lg\">\n <div className=\"rounded-xl border border-border bg-card p-8 text-center\">\n <p className=\"text-6xl font-mono font-bold text-foreground\">\n {activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : \"00:00:00\"}\n </p>\n {activeTimer?.description && (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {activeTimer.description}\n </p>\n )}\n <div className=\"mt-6 flex items-center justify-center gap-3\">\n {activeTimer ? (\n <button\n onClick={stopTimer}\n className=\"inline-flex items-center gap-2 rounded-md bg-red-500 px-6 py-3 text-sm font-medium text-white hover:bg-red-600\"\n >\n <Square className=\"h-4 w-4\" />\n Stop\n </button>\n ) : (\n <button\n onClick={() => startTimer()}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90\"\n >\n <Play className=\"h-4 w-4\" />\n Start\n </button>\n )}\n <button className=\"inline-flex items-center gap-2 rounded-md border border-border px-4 py-3 text-sm font-medium text-foreground hover:bg-muted/50\">\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </button>\n </div>\n </div>\n\n {/* Server-side running timers */}\n <div className=\"mt-6 rounded-xl border border-border bg-card p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-foreground\">\n Running Timers\n </h3>\n {runningLoading ? (\n <LoadingSkeleton variant=\"list\" count={2} />\n ) : runningTimers.length === 0 ? (\n <p className=\"text-center text-sm text-muted-foreground py-4\">\n No active timers on the server\n </p>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {runningTimers.map((timer: RunningTimerItem) => (\n <div\n key={timer.timeEntry.id}\n className=\"flex items-center justify-between rounded-lg border border-border p-3\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-foreground\">\n {timer.timeEntry.project?.name ?? \"No Project\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {timer.timeEntry.description ?? \"No description\"}\n </p>\n </div>\n <p className=\"ml-4 text-sm font-mono font-medium text-foreground\">\n {formatTimerDuration(timer.elapsedSeconds)}\n </p>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,IAAY;CAC1B,IAAM,EAAE,gBAAa,eAAY,iBAAc,GAAoB,EAE7D,EAAE,MAAM,GAAa,SAAS,MAClC,GAA2B,EAEvB,IAAgB,GAAa,iBAAiB,EAAE;AAEtD,QACE,kBAAC,GAAD;EAAY,OAAM;EAAQ,aAAY;YACpC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV,IACG,EAAoB,EAAY,QAAQ,GACxC;MACF,CAAA;KACH,GAAa,eACZ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY;MACX,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,IACC,kBAAC,UAAD;OACE,SAAS;OACT,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,OAEvB;WAET,kBAAC,UAAD;OACE,eAAe,GAAY;OAC3B,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,QAErB;UAEX,kBAAC,UAAD;OAAQ,WAAU;iBAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,QAE1B;SACL;;KACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA6C;KAEtD,CAAA,EACJ,IACC,kBAAC,GAAD;KAAiB,SAAQ;KAAO,OAAO;KAAK,CAAA,GAC1C,EAAc,WAAW,IAC3B,kBAAC,KAAD;KAAG,WAAU;eAAiD;KAE1D,CAAA,GAEJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAc,KAAK,MAClB,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,SAAS,QAAQ;QAChC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,eAAe;QAC9B,CAAA,CACA;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAoB,EAAM,eAAe;OACxC,CAAA,CACA;QAdC,EAAM,UAAU,GAcjB,CACN;KACE,CAAA,CAEJ;MACF;;EACK,CAAA"}
1
+ {"version":3,"file":"TimerPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimerPage.tsx"],"sourcesContent":["import { Play, Square, RotateCcw } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useListRunningTimersQuery,\n type ListRunningTimersQuery,\n} from \"@/generated/wspace-operations\";\n\ntype RunningTimerItem = ListRunningTimersQuery[\"runningTimers\"][number];\n\nexport function TimerPage() {\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: runningData, loading: runningLoading } =\n useListRunningTimersQuery();\n\n const runningTimers = runningData?.runningTimers ?? [];\n\n return (\n <PageLayout title=\"Timer\" description=\"Focus timer for deep work sessions\">\n <div className=\"mx-auto max-w-lg\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-8 text-center\">\n <p className=\"text-6xl font-mono font-bold text-text-primary\">\n {activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : \"00:00:00\"}\n </p>\n {activeTimer?.description && (\n <p className=\"mt-2 text-sm text-text-secondary\">\n {activeTimer.description}\n </p>\n )}\n <div className=\"mt-6 flex items-center justify-center gap-3\">\n {activeTimer ? (\n <button\n onClick={stopTimer}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-danger-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-danger-bg/90\"\n >\n <Square className=\"h-4 w-4\" />\n Stop\n </button>\n ) : (\n <button\n onClick={() => startTimer()}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Play className=\"h-4 w-4\" />\n Start\n </button>\n )}\n <button className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </button>\n </div>\n </div>\n\n {/* Server-side running timers */}\n <div className=\"mt-6 rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Running Timers\n </h3>\n {runningLoading ? (\n <LoadingSkeleton variant=\"list\" count={2} />\n ) : runningTimers.length === 0 ? (\n <p className=\"text-center text-sm text-text-secondary py-4\">\n No active timers on the server\n </p>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {runningTimers.map((timer: RunningTimerItem) => (\n <div\n key={timer.timeEntry.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle p-3\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {timer.timeEntry.project?.name ?? \"No Project\"}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {timer.timeEntry.description ?? \"No description\"}\n </p>\n </div>\n <p className=\"ml-4 text-sm font-mono font-medium text-text-primary\">\n {formatTimerDuration(timer.elapsedSeconds)}\n </p>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,IAAY;CAC1B,IAAM,EAAE,gBAAa,eAAY,iBAAc,GAAoB,EAE7D,EAAE,MAAM,GAAa,SAAS,MAClC,GAA2B,EAEvB,IAAgB,GAAa,iBAAiB,EAAE;AAEtD,QACE,kBAAC,GAAD;EAAY,OAAM;EAAQ,aAAY;YACpC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV,IACG,EAAoB,EAAY,QAAQ,GACxC;MACF,CAAA;KACH,GAAa,eACZ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY;MACX,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,IACC,kBAAC,UAAD;OACE,SAAS;OACT,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,OAEvB;WAET,kBAAC,UAAD;OACE,eAAe,GAAY;OAC3B,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,QAErB;UAEX,kBAAC,UAAD;OAAQ,WAAU;iBAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,QAE1B;SACL;;KACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA+C;KAExD,CAAA,EACJ,IACC,kBAAC,GAAD;KAAiB,SAAQ;KAAO,OAAO;KAAK,CAAA,GAC1C,EAAc,WAAW,IAC3B,kBAAC,KAAD;KAAG,WAAU;eAA+C;KAExD,CAAA,GAEJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAc,KAAK,MAClB,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,SAAS,QAAQ;QAChC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,eAAe;QAC9B,CAAA,CACA;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAoB,EAAM,eAAe;OACxC,CAAA,CACA;QAdC,EAAM,UAAU,GAcjB,CACN;KACE,CAAA,CAEJ;MACF;;EACK,CAAA"}
@@ -1,14 +1,14 @@
1
1
  import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
2
2
  import { formatDate as t, formatHours as n, getInitials as r, getStatusColor as i } from "../../utils/helpers.js";
3
- import { PageLayout as a } from "../../components/PageLayout.js";
4
- import { StatCard as o } from "../../components/StatCard.js";
5
- import { LoadingSkeleton as s } from "../../components/LoadingSkeleton.js";
6
- import { useApproveRequestMutation as c, useGetApprovalStatsQuery as l, useListApprovalRequestsQuery as u, useRejectRequestMutation as d } from "../../../generated/wspace-operations.js";
3
+ import { StatCard as a } from "../../components/StatCard.js";
4
+ import { LoadingSkeleton as o } from "../../components/LoadingSkeleton.js";
5
+ import { useApproveRequestMutation as s, useGetApprovalStatsQuery as c, useListApprovalRequestsQuery as l, useRejectRequestMutation as u } from "../../../generated/wspace-operations.js";
6
+ import { PageLayout as d } from "../../components/PageLayout.js";
7
7
  import { CheckCircle as f, Clock as p, XCircle as m } from "lucide-react";
8
8
  import { jsx as h, jsxs as g } from "react/jsx-runtime";
9
9
  //#region src/timecampus/pages/time-approval/TimeApprovalPage.tsx
10
10
  function _() {
11
- let { workspaceId: _ = "" } = e(), { data: v, loading: y, error: b } = u(), { data: x, loading: S, error: C } = l(), [w, { loading: T }] = c(), [E, { loading: D }] = d(), O = v?.approvalRequests?.items ?? [], k = x?.approvalStats, A = T || D, j = async (e) => {
11
+ let { workspaceId: _ = "" } = e(), { data: v, loading: y, error: b } = l(), { data: x, loading: S, error: C } = c(), [w, { loading: T }] = s(), [E, { loading: D }] = u(), O = v?.approvalRequests?.items ?? [], k = x?.approvalStats, A = T || D, j = async (e) => {
12
12
  await w({ variables: { id: e } });
13
13
  }, M = async (e) => {
14
14
  await E({ variables: {
@@ -16,69 +16,69 @@ function _() {
16
16
  reason: "Rejected by reviewer"
17
17
  } });
18
18
  };
19
- return y && S ? /* @__PURE__ */ h(a, {
19
+ return y && S ? /* @__PURE__ */ h(d, {
20
20
  title: "Time Approval",
21
21
  description: "Review and approve team timesheets",
22
- children: /* @__PURE__ */ h(s, {
22
+ children: /* @__PURE__ */ h(o, {
23
23
  variant: "list",
24
24
  count: 4
25
25
  })
26
- }) : b && C ? /* @__PURE__ */ h(a, {
26
+ }) : b && C ? /* @__PURE__ */ h(d, {
27
27
  title: "Time Approval",
28
28
  description: "Review and approve team timesheets",
29
29
  children: /* @__PURE__ */ h("div", {
30
- className: "rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400",
30
+ className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
31
31
  children: "Failed to load approval data. Please try again later."
32
32
  })
33
- }) : /* @__PURE__ */ g(a, {
33
+ }) : /* @__PURE__ */ g(d, {
34
34
  title: "Time Approval",
35
35
  description: "Review and approve team timesheets",
36
36
  children: [/* @__PURE__ */ g("div", {
37
37
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
38
38
  children: [
39
- /* @__PURE__ */ h(o, {
39
+ /* @__PURE__ */ h(a, {
40
40
  title: "Pending Approvals",
41
41
  value: String(k?.pendingCount ?? 0),
42
42
  icon: /* @__PURE__ */ h(p, { className: "h-5 w-5" }),
43
- iconBgColor: "bg-amber-100 text-amber-600 dark:bg-amber-900/30 dark:text-amber-400"
43
+ iconBgColor: "bg-status-warning-bg text-status-warning-text"
44
44
  }),
45
- /* @__PURE__ */ h(o, {
45
+ /* @__PURE__ */ h(a, {
46
46
  title: "Approved This Week",
47
47
  value: String(k?.approvedCount ?? 0),
48
48
  icon: /* @__PURE__ */ h(f, { className: "h-5 w-5" }),
49
- iconBgColor: "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400"
49
+ iconBgColor: "bg-status-success-bg text-status-success-text"
50
50
  }),
51
- /* @__PURE__ */ h(o, {
51
+ /* @__PURE__ */ h(a, {
52
52
  title: "Rejected",
53
53
  value: String(k?.rejectedCount ?? 0),
54
54
  icon: /* @__PURE__ */ h(m, { className: "h-5 w-5" }),
55
- iconBgColor: "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400"
55
+ iconBgColor: "bg-status-error-bg text-status-error-text"
56
56
  }),
57
- /* @__PURE__ */ h(o, {
57
+ /* @__PURE__ */ h(a, {
58
58
  title: "Avg. Review Time",
59
59
  value: k?.averageReviewTime ? `${Math.round(k.averageReviewTime)}h` : "N/A",
60
60
  description: "Target: 24h"
61
61
  })
62
62
  ]
63
63
  }), /* @__PURE__ */ h("div", {
64
- className: "rounded-xl border border-border bg-card",
64
+ className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop",
65
65
  children: /* @__PURE__ */ g("div", {
66
66
  className: "divide-y divide-border",
67
67
  children: [O.length === 0 && !y && /* @__PURE__ */ h("div", {
68
- className: "p-4 text-center text-sm text-muted-foreground",
68
+ className: "p-4 text-center text-sm text-text-secondary",
69
69
  children: "No approval requests found."
70
70
  }), O.map((e) => /* @__PURE__ */ g("div", {
71
- className: "flex items-center justify-between p-4 hover:bg-muted/50 transition-colors",
71
+ className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
72
72
  children: [/* @__PURE__ */ g("div", {
73
73
  className: "flex items-center gap-3",
74
74
  children: [/* @__PURE__ */ h("div", {
75
- className: "flex h-9 w-9 items-center justify-center rounded-full bg-primary/10 text-sm font-medium text-primary",
75
+ className: "flex h-9 w-9 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium text-primary",
76
76
  children: r(e.userId)
77
77
  }), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
78
- className: "text-sm font-medium text-foreground",
78
+ className: "text-sm font-medium text-text-primary",
79
79
  children: e.userId
80
80
  }), /* @__PURE__ */ g("p", {
81
- className: "text-xs text-muted-foreground",
81
+ className: "text-xs text-text-secondary",
82
82
  children: [
83
83
  e.period,
84
84
  " · Submitted",
@@ -92,10 +92,10 @@ function _() {
92
92
  /* @__PURE__ */ g("div", {
93
93
  className: "text-right",
94
94
  children: [/* @__PURE__ */ h("p", {
95
- className: "text-sm font-medium text-foreground",
95
+ className: "text-sm font-medium text-text-primary",
96
96
  children: n(e.totalHours)
97
97
  }), /* @__PURE__ */ g("p", {
98
- className: "text-xs text-muted-foreground",
98
+ className: "text-xs text-text-secondary",
99
99
  children: [n(e.billableHours), " billable"]
100
100
  })]
101
101
  }),
@@ -108,12 +108,12 @@ function _() {
108
108
  children: [/* @__PURE__ */ h("button", {
109
109
  onClick: () => j(e.id),
110
110
  disabled: A,
111
- className: "rounded-md p-1.5 text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-900/20 disabled:opacity-50",
111
+ className: "rounded-md p-1.5 text-status-success-text hover:bg-status-success-bg dark:hover:bg-status-success-text/20 disabled:opacity-50",
112
112
  children: /* @__PURE__ */ h(f, { className: "h-4 w-4" })
113
113
  }), /* @__PURE__ */ h("button", {
114
114
  onClick: () => M(e.id),
115
115
  disabled: A,
116
- className: "rounded-md p-1.5 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 disabled:opacity-50",
116
+ className: "rounded-md p-1.5 text-status-error-text hover:bg-status-error-bg dark:hover:bg-status-error-text/20 disabled:opacity-50",
117
117
  children: /* @__PURE__ */ h(m, { className: "h-4 w-4" })
118
118
  })]
119
119
  })