@burdenoff/microfe-timecampus 2026.625.1 → 2026.626.2

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 (101) 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/PageLayout.js +23 -15
  4. package/dist/timecampus/components/PageLayout.js.map +1 -1
  5. package/dist/timecampus/pages/applets/AppletStorePage.js +33 -30
  6. package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
  7. package/dist/timecampus/pages/applets/InstalledAppletsPage.js +37 -31
  8. package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
  9. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +48 -44
  10. package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
  11. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +35 -31
  12. package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
  13. package/dist/timecampus/pages/channels/ChannelsPage.js +27 -24
  14. package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
  15. package/dist/timecampus/pages/client-portal/ClientPortalPage.js +46 -38
  16. package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
  17. package/dist/timecampus/pages/dashboard/AnalyticsPage.js +66 -39
  18. package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
  19. package/dist/timecampus/pages/dashboard/ReportsPage.js +42 -36
  20. package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
  21. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +2 -0
  22. package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
  23. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +35 -31
  24. package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
  25. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +31 -25
  26. package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
  27. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +43 -35
  28. package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
  29. package/dist/timecampus/pages/focus-score/FocusScorePage.js +55 -51
  30. package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
  31. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +32 -28
  32. package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
  33. package/dist/timecampus/pages/geofencing/GeofencingPage.js +32 -25
  34. package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
  35. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +29 -25
  36. package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
  37. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +32 -29
  38. package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
  39. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +29 -25
  40. package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
  41. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +39 -35
  42. package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
  43. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +2 -0
  44. package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
  45. package/dist/timecampus/pages/meetings/MeetingCreatePage.js +33 -29
  46. package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
  47. package/dist/timecampus/pages/meetings/MeetingDetailPage.js +122 -104
  48. package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
  49. package/dist/timecampus/pages/meetings/MeetingsPage.js +42 -32
  50. package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
  51. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +2 -0
  52. package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
  53. package/dist/timecampus/pages/pomodoro/PomodoroPage.js +145 -114
  54. package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
  55. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +49 -45
  56. package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
  57. package/dist/timecampus/pages/projects/ProjectCreatePage.js +28 -24
  58. package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
  59. package/dist/timecampus/pages/projects/ProjectDetailPage.js +109 -78
  60. package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
  61. package/dist/timecampus/pages/projects/ProjectsPage.js +11 -7
  62. package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
  63. package/dist/timecampus/pages/projects/TasksPage.js +40 -30
  64. package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
  65. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +50 -46
  66. package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
  67. package/dist/timecampus/pages/team/TeamAnalyticsPage.js +18 -14
  68. package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
  69. package/dist/timecampus/pages/team/TeamMembersPage.js +41 -35
  70. package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
  71. package/dist/timecampus/pages/team/TeamPage.js +91 -61
  72. package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
  73. package/dist/timecampus/pages/team-activity/TeamActivityPage.js +40 -36
  74. package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
  75. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +33 -29
  76. package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
  77. package/dist/timecampus/pages/templates/TemplateApplicationPage.js +17 -13
  78. package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
  79. package/dist/timecampus/pages/templates/TemplateDetailPage.js +67 -49
  80. package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
  81. package/dist/timecampus/pages/templates/TemplatesPage.js +34 -31
  82. package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
  83. package/dist/timecampus/pages/time/TimeEntriesPage.js +48 -39
  84. package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
  85. package/dist/timecampus/pages/time/TimeTrackingPage.js +65 -64
  86. package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
  87. package/dist/timecampus/pages/time/TimerPage.js +103 -69
  88. package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
  89. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +53 -49
  90. package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
  91. package/dist/timecampus/pages/widgets/WidgetDetailPage.js +65 -47
  92. package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
  93. package/dist/timecampus/pages/widgets/WidgetsPage.js +38 -31
  94. package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
  95. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +2 -0
  96. package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
  97. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +35 -31
  98. package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
  99. package/dist/timecampus/pages/workflows/WorkflowsPage.js +43 -33
  100. package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
  101. package/package.json +2 -2
@@ -1,91 +1,118 @@
1
- import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
2
- import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
3
- import { useGetFocusScoreSummaryQuery as n, useGetTimeEntryStatsQuery as r, useGetWorkPatternSummaryQuery as i } from "../../../generated/wspace-operations.js";
4
- import { PageLayout as a } from "../../components/PageLayout.js";
5
- import { BarChart3 as o } from "lucide-react";
6
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
1
+ import { useTimeCampus as e, useTimeCampusNavigate as t } from "../../providers/TimeCampusProvider.js";
2
+ import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
3
+ import { useGetFocusScoreSummaryQuery as r, useGetTimeEntryStatsQuery as i, useGetWorkPatternSummaryQuery as a } from "../../../generated/wspace-operations.js";
4
+ import { PageLayout as o } from "../../components/PageLayout.js";
5
+ import { BarChart3 as s } from "lucide-react";
6
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
+ import { GlassCard as u, NextSteps as d } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/timecampus/pages/dashboard/AnalyticsPage.tsx
8
- function l() {
9
- let { workspaceId: l = "" } = e(), { data: u, loading: d, error: f } = r({ skip: !l }), { data: p, loading: m } = n({ skip: !l }), { data: h, loading: g } = i({ skip: !l }), _ = u?.timeEntryStats, v = p?.focusScoreSummary, y = h?.workPatternSummary;
10
- return d || m || g ? /* @__PURE__ */ s(a, {
9
+ function f() {
10
+ let { workspaceId: f = "" } = e(), p = t(), { data: m, loading: h, error: g } = i({ skip: !f }), { data: _, loading: v } = r({ skip: !f }), { data: y, loading: b } = a({ skip: !f }), x = m?.timeEntryStats, S = _?.focusScoreSummary, C = y?.workPatternSummary;
11
+ return h || v || b ? /* @__PURE__ */ c(o, {
11
12
  title: "Analytics",
12
13
  description: "Insights into your time tracking and productivity",
13
- children: /* @__PURE__ */ s(t, {
14
+ children: /* @__PURE__ */ c(n, {
14
15
  variant: "card",
15
16
  count: 4
16
17
  })
17
- }) : f ? /* @__PURE__ */ s(a, {
18
+ }) : g ? /* @__PURE__ */ c(o, {
18
19
  title: "Analytics",
19
20
  description: "Insights into your time tracking and productivity",
20
- children: /* @__PURE__ */ s("div", {
21
+ children: /* @__PURE__ */ c("div", {
21
22
  className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
22
23
  children: "Failed to load analytics. Please try again later."
23
24
  })
24
- }) : /* @__PURE__ */ s(a, {
25
+ }) : /* @__PURE__ */ l(o, {
25
26
  title: "Analytics",
26
27
  description: "Insights into your time tracking and productivity",
27
- children: /* @__PURE__ */ c("div", {
28
+ purpose: "Turn the raw hours you track into answers — spot whether your focus is improving, where billable time is going, and which habits to change to get more done with less burnout.",
29
+ children: [/* @__PURE__ */ c(d, {
30
+ storageKey: "timecampus-analytics",
31
+ className: "mb-6",
32
+ steps: [
33
+ {
34
+ id: "reports",
35
+ label: "Build a detailed report",
36
+ description: "Slice time by project, client or person.",
37
+ onClick: () => p("/reports")
38
+ },
39
+ {
40
+ id: "focus",
41
+ label: "Dig into your focus score",
42
+ description: "Understand what's helping or hurting deep work.",
43
+ onClick: () => p("/focus-score")
44
+ },
45
+ {
46
+ id: "patterns",
47
+ label: "Review your work patterns",
48
+ description: "See how your week actually breaks down.",
49
+ onClick: () => p("/work-patterns")
50
+ }
51
+ ]
52
+ }), /* @__PURE__ */ l("div", {
28
53
  className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
29
- children: [/* @__PURE__ */ c("div", {
30
- className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
31
- children: [/* @__PURE__ */ c("div", {
54
+ children: [/* @__PURE__ */ l(u, {
55
+ treatment: "glass",
56
+ glow: !0,
57
+ className: "p-6",
58
+ children: [/* @__PURE__ */ l("div", {
32
59
  className: "mb-4 flex items-center gap-2",
33
- children: [/* @__PURE__ */ s(o, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ s("h3", {
60
+ children: [/* @__PURE__ */ c(s, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ c("h3", {
34
61
  className: "text-sm font-semibold text-text-primary",
35
62
  children: "Productivity Trends"
36
63
  })]
37
- }), /* @__PURE__ */ s("div", {
64
+ }), /* @__PURE__ */ c("div", {
38
65
  className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
39
- children: /* @__PURE__ */ c("div", {
66
+ children: /* @__PURE__ */ l("div", {
40
67
  className: "text-center",
41
68
  children: [
42
- /* @__PURE__ */ s("p", {
69
+ /* @__PURE__ */ c("p", {
43
70
  className: "text-sm text-text-secondary",
44
- children: v ? `Focus Score: ${Math.round(v.averageScore)}/100 (${v.trend ?? "stable"})` : "No focus score data"
71
+ children: S ? `Focus Score: ${Math.round(S.averageScore)}/100 (${S.trend ?? "stable"})` : "No focus score data"
45
72
  }),
46
- y && /* @__PURE__ */ c("p", {
73
+ C && /* @__PURE__ */ l("p", {
47
74
  className: "mt-1 text-xs text-text-secondary",
48
75
  children: [
49
- y.averageFocusHours.toFixed(1),
76
+ C.averageFocusHours.toFixed(1),
50
77
  "h avg focus ·",
51
78
  " ",
52
- y.averageMeetingHours.toFixed(1),
79
+ C.averageMeetingHours.toFixed(1),
53
80
  "h avg meetings"
54
81
  ]
55
82
  }),
56
- v?.improvementArea && /* @__PURE__ */ c("p", {
83
+ S?.improvementArea && /* @__PURE__ */ l("p", {
57
84
  className: "mt-1 text-xs text-text-secondary",
58
- children: ["Improve: ", v.improvementArea]
85
+ children: ["Improve: ", S.improvementArea]
59
86
  })
60
87
  ]
61
88
  })
62
89
  })]
63
- }), /* @__PURE__ */ c("div", {
64
- className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
65
- children: [/* @__PURE__ */ c("div", {
90
+ }), /* @__PURE__ */ l("div", {
91
+ className: "rounded-xl border border-border-seam bg-bg-surface shadow-elevation-1 p-6",
92
+ children: [/* @__PURE__ */ l("div", {
66
93
  className: "mb-4 flex items-center gap-2",
67
- children: [/* @__PURE__ */ s(o, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ s("h3", {
94
+ children: [/* @__PURE__ */ c(s, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ c("h3", {
68
95
  className: "text-sm font-semibold text-text-primary",
69
96
  children: "Time Distribution"
70
97
  })]
71
- }), /* @__PURE__ */ s("div", {
98
+ }), /* @__PURE__ */ c("div", {
72
99
  className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
73
- children: /* @__PURE__ */ c("div", {
100
+ children: /* @__PURE__ */ l("div", {
74
101
  className: "text-center",
75
- children: [/* @__PURE__ */ s("p", {
102
+ children: [/* @__PURE__ */ c("p", {
76
103
  className: "text-sm text-text-secondary",
77
- children: _ ? `${Math.round(_.totalHours)}h total · ${Math.round(_.billableHours)}h billable · ${_.totalEntries} entries` : "No time entry data"
78
- }), _ && _.activeTimers > 0 && /* @__PURE__ */ c("p", {
104
+ children: x ? `${Math.round(x.totalHours)}h total · ${Math.round(x.billableHours)}h billable · ${x.totalEntries} entries` : "No time entry data"
105
+ }), x && x.activeTimers > 0 && /* @__PURE__ */ l("p", {
79
106
  className: "mt-1 text-xs text-text-secondary",
80
- children: [_.activeTimers, " timer(s) running"]
107
+ children: [x.activeTimers, " timer(s) running"]
81
108
  })]
82
109
  })
83
110
  })]
84
111
  })]
85
- })
112
+ })]
86
113
  });
87
114
  }
88
115
  //#endregion
89
- export { l as AnalyticsPage };
116
+ export { f as AnalyticsPage };
90
117
 
91
118
  //# sourceMappingURL=AnalyticsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/dashboard/AnalyticsPage.tsx"],"sourcesContent":["import { BarChart3 } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useGetFocusScoreSummaryQuery,\n useGetWorkPatternSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function AnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetTimeEntryStatsQuery({\n skip: !workspaceId,\n });\n\n const { data: focusData, loading: focusLoading } =\n useGetFocusScoreSummaryQuery({\n skip: !workspaceId,\n });\n\n const { data: patternData, loading: patternLoading } =\n useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const stats = statsData?.timeEntryStats;\n const focus = focusData?.focusScoreSummary;\n const pattern = patternData?.workPatternSummary;\n\n if (statsLoading || focusLoading || patternLoading) {\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Productivity Trends\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <div className=\"text-center\">\n <p className=\"text-sm text-text-secondary\">\n {focus\n ? `Focus Score: ${Math.round(focus.averageScore)}/100 (${focus.trend ?? \"stable\"})`\n : \"No focus score data\"}\n </p>\n {pattern && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n {pattern.averageFocusHours.toFixed(1)}h avg focus ·{\" \"}\n {pattern.averageMeetingHours.toFixed(1)}h avg meetings\n </p>\n )}\n {focus?.improvementArea && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Improve: {focus.improvementArea}\n </p>\n )}\n </div>\n </div>\n </div>\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Time Distribution\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <div className=\"text-center\">\n <p className=\"text-sm text-text-secondary\">\n {stats\n ? `${Math.round(stats.totalHours)}h total · ${Math.round(stats.billableHours)}h billable · ${stats.totalEntries} entries`\n : \"No time entry data\"}\n </p>\n {stats && stats.activeTimers > 0 && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n {stats.activeTimers} timer(s) running\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA0B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEI,EAAE,MAAM,GAAW,SAAS,MAChC,EAA6B,EAC3B,MAAM,CAAC,GACR,CAAC,EAEE,EAAE,MAAM,GAAa,SAAS,MAClC,EAA8B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEE,IAAQ,GAAW,gBACnB,IAAQ,GAAW,mBACnB,IAAU,GAAa;AA0B7B,QAxBI,KAAgB,KAAgB,IAEhC,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,KAAD;QAAG,WAAU;kBACV,IACG,gBAAgB,KAAK,MAAM,EAAM,aAAa,CAAC,QAAQ,EAAM,SAAS,SAAS,KAC/E;QACF,CAAA;OACH,KACC,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAQ,kBAAkB,QAAQ,EAAE;SAAC;SAAc;SACnD,EAAQ,oBAAoB,QAAQ,EAAE;SAAC;SACtC;;OAEL,GAAO,mBACN,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAAgD,aACpC,EAAM,gBACd;;OAEF;;KACF,CAAA,CACF;OACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,IACG,GAAG,KAAK,MAAM,EAAM,WAAW,CAAC,YAAY,KAAK,MAAM,EAAM,cAAc,CAAC,eAAe,EAAM,aAAa,YAC9G;OACF,CAAA,EACH,KAAS,EAAM,eAAe,KAC7B,kBAAC,KAAD;OAAG,WAAU;iBAAb,CACG,EAAM,cAAa,oBAClB;SAEF;;KACF,CAAA,CACF;MACF;;EACK,CAAA"}
1
+ {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/dashboard/AnalyticsPage.tsx"],"sourcesContent":["import { BarChart3 } from \"lucide-react\";\nimport { GlassCard, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n useTimeCampus,\n useTimeCampusNavigate,\n} from \"../../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useGetFocusScoreSummaryQuery,\n useGetWorkPatternSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function AnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const navigate = useTimeCampusNavigate();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetTimeEntryStatsQuery({\n skip: !workspaceId,\n });\n\n const { data: focusData, loading: focusLoading } =\n useGetFocusScoreSummaryQuery({\n skip: !workspaceId,\n });\n\n const { data: patternData, loading: patternLoading } =\n useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const stats = statsData?.timeEntryStats;\n const focus = focusData?.focusScoreSummary;\n const pattern = patternData?.workPatternSummary;\n\n if (statsLoading || focusLoading || patternLoading) {\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Analytics\"\n description=\"Insights into your time tracking and productivity\"\n purpose=\"Turn the raw hours you track into answers — spot whether your focus is improving, where billable time is going, and which habits to change to get more done with less burnout.\"\n >\n <NextSteps\n storageKey=\"timecampus-analytics\"\n className=\"mb-6\"\n steps={[\n {\n id: \"reports\",\n label: \"Build a detailed report\",\n description: \"Slice time by project, client or person.\",\n onClick: () => navigate(\"/reports\"),\n },\n {\n id: \"focus\",\n label: \"Dig into your focus score\",\n description: \"Understand what's helping or hurting deep work.\",\n onClick: () => navigate(\"/focus-score\"),\n },\n {\n id: \"patterns\",\n label: \"Review your work patterns\",\n description: \"See how your week actually breaks down.\",\n onClick: () => navigate(\"/work-patterns\"),\n },\n ]}\n />\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Productivity Trends\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <div className=\"text-center\">\n <p className=\"text-sm text-text-secondary\">\n {focus\n ? `Focus Score: ${Math.round(focus.averageScore)}/100 (${focus.trend ?? \"stable\"})`\n : \"No focus score data\"}\n </p>\n {pattern && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n {pattern.averageFocusHours.toFixed(1)}h avg focus ·{\" \"}\n {pattern.averageMeetingHours.toFixed(1)}h avg meetings\n </p>\n )}\n {focus?.improvementArea && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n Improve: {focus.improvementArea}\n </p>\n )}\n </div>\n </div>\n </GlassCard>\n <div className=\"rounded-xl border border-border-seam bg-bg-surface shadow-elevation-1 p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Time Distribution\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <div className=\"text-center\">\n <p className=\"text-sm text-text-secondary\">\n {stats\n ? `${Math.round(stats.totalHours)}h total · ${Math.round(stats.billableHours)}h billable · ${stats.totalEntries} entries`\n : \"No time entry data\"}\n </p>\n {stats && stats.activeTimers > 0 && (\n <p className=\"mt-1 text-xs text-text-secondary\">\n {stats.activeTimers} timer(s) running\n </p>\n )}\n </div>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,IAAW,GAAuB,EAElC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA0B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEI,EAAE,MAAM,GAAW,SAAS,MAChC,EAA6B,EAC3B,MAAM,CAAC,GACR,CAAC,EAEE,EAAE,MAAM,GAAa,SAAS,MAClC,EAA8B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEE,IAAQ,GAAW,gBACnB,IAAQ,GAAW,mBACnB,IAAU,GAAa;AA0B7B,QAxBI,KAAgB,KAAgB,IAEhC,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,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,SAAQ;YAHV,CAKE,kBAAC,GAAD;GACE,YAAW;GACX,WAAU;GACV,OAAO;IACL;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,WAAW;KACpC;IACD;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,eAAe;KACxC;IACD;KACE,IAAI;KACJ,OAAO;KACP,aAAa;KACb,eAAe,EAAS,iBAAiB;KAC1C;IACF;GACD,CAAA,EACF,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAA5C,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,KAAD;QAAG,WAAU;kBACV,IACG,gBAAgB,KAAK,MAAM,EAAM,aAAa,CAAC,QAAQ,EAAM,SAAS,SAAS,KAC/E;QACF,CAAA;OACH,KACC,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG,EAAQ,kBAAkB,QAAQ,EAAE;SAAC;SAAc;SACnD,EAAQ,oBAAoB,QAAQ,EAAE;SAAC;SACtC;;OAEL,GAAO,mBACN,kBAAC,KAAD;QAAG,WAAU;kBAAb,CAAgD,aACpC,EAAM,gBACd;;OAEF;;KACF,CAAA,CACI;OACZ,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,IACG,GAAG,KAAK,MAAM,EAAM,WAAW,CAAC,YAAY,KAAK,MAAM,EAAM,cAAc,CAAC,eAAe,EAAM,aAAa,YAC9G;OACF,CAAA,EACH,KAAS,EAAM,eAAe,KAC7B,kBAAC,KAAD;OAAG,WAAU;iBAAb,CACG,EAAM,cAAa,oBAClB;SAEF;;KACF,CAAA,CACF;MACF;KACK"}
@@ -2,93 +2,99 @@ import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
2
2
  import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
3
3
  import { useGetFocusScoreSummaryQuery as n, useGetTimeEntryStatsQuery as r, useGetWorkPatternSummaryQuery as i } from "../../../generated/wspace-operations.js";
4
4
  import { PageLayout as a } from "../../components/PageLayout.js";
5
- import { Download as o, FileText as s, Plus as c } from "lucide-react";
6
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import { EmptyState as o } from "../../components/EmptyState.js";
6
+ import { Download as s, FileText as c, Plus as l } from "lucide-react";
7
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
8
+ import { GlassCard as f } from "@burdenoff/fe-libs/ui";
7
9
  //#region src/timecampus/pages/dashboard/ReportsPage.tsx
8
- function d() {
9
- let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = r({ skip: !d }), { data: h, loading: g } = i({ skip: !d }), { data: _, loading: v } = n({ skip: !d }), y = f?.timeEntryStats, b = h?.workPatternSummary, x = _?.focusScoreSummary;
10
- if (p || g || v) return /* @__PURE__ */ l(a, {
10
+ function p() {
11
+ let { workspaceId: p = "" } = e(), { data: m, loading: h, error: g } = r({ skip: !p }), { data: _, loading: v } = i({ skip: !p }), { data: y, loading: b } = n({ skip: !p }), x = m?.timeEntryStats, S = _?.workPatternSummary, C = y?.focusScoreSummary;
12
+ if (h || v || b) return /* @__PURE__ */ u(a, {
11
13
  title: "Reports",
12
14
  description: "Generate and view time tracking reports",
13
- actions: /* @__PURE__ */ u("button", {
15
+ actions: /* @__PURE__ */ d("button", {
14
16
  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",
15
- children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Generate Report"]
17
+ children: [/* @__PURE__ */ u(l, { className: "h-4 w-4" }), "Generate Report"]
16
18
  }),
17
- children: /* @__PURE__ */ l(t, {
19
+ children: /* @__PURE__ */ u(t, {
18
20
  variant: "list",
19
21
  count: 4
20
22
  })
21
23
  });
22
- if (m) return /* @__PURE__ */ l(a, {
24
+ if (g) return /* @__PURE__ */ u(a, {
23
25
  title: "Reports",
24
26
  description: "Generate and view time tracking reports",
25
- children: /* @__PURE__ */ l("div", {
27
+ children: /* @__PURE__ */ u("div", {
26
28
  className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
27
29
  children: "Failed to load reports data. Please try again later."
28
30
  })
29
31
  });
30
- let S = [
31
- ...y ? [{
32
+ let w = [
33
+ ...x ? [{
32
34
  id: "time-summary",
33
35
  name: "Time Tracking Summary",
34
36
  type: "time",
35
- period: `${Math.round(y.totalHours)}h total · ${y.totalEntries} entries`,
37
+ period: `${Math.round(x.totalHours)}h total · ${x.totalEntries} entries`,
36
38
  status: "ready"
37
39
  }, {
38
40
  id: "billable-summary",
39
41
  name: "Billable Hours Report",
40
42
  type: "billing",
41
- period: `${Math.round(y.billableHours)}h billable · ${y.activeTimers} active`,
43
+ period: `${Math.round(x.billableHours)}h billable · ${x.activeTimers} active`,
42
44
  status: "ready"
43
45
  }] : [],
44
- ...b ? [{
46
+ ...S ? [{
45
47
  id: "work-pattern",
46
48
  name: "Work Pattern Analysis",
47
49
  type: "team",
48
- period: `${b.averageFocusHours.toFixed(1)}h avg focus · ${Math.round(b.averageProductivity)}% productivity`,
50
+ period: `${S.averageFocusHours.toFixed(1)}h avg focus · ${Math.round(S.averageProductivity)}% productivity`,
49
51
  status: "ready"
50
52
  }] : [],
51
- ...x ? [{
53
+ ...C ? [{
52
54
  id: "focus-score",
53
55
  name: "Focus Score Report",
54
56
  type: "productivity",
55
- period: `Avg: ${Math.round(x.averageScore)} · High: ${Math.round(x.highestScore)} · Low: ${Math.round(x.lowestScore)}`,
57
+ period: `Avg: ${Math.round(C.averageScore)} · High: ${Math.round(C.highestScore)} · Low: ${Math.round(C.lowestScore)}`,
56
58
  status: "ready"
57
59
  }] : []
58
60
  ];
59
- return /* @__PURE__ */ l(a, {
61
+ return /* @__PURE__ */ u(a, {
60
62
  title: "Reports",
61
63
  description: "Generate and view time tracking reports",
62
- actions: /* @__PURE__ */ u("button", {
64
+ purpose: "Package your tracked time into shareable, exportable reports — the deliverables you hand to clients for billing or to leadership for capacity and utilisation decisions.",
65
+ actions: /* @__PURE__ */ d("button", {
63
66
  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",
64
- children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Generate Report"]
67
+ children: [/* @__PURE__ */ u(l, { className: "h-4 w-4" }), "Generate Report"]
65
68
  }),
66
- children: /* @__PURE__ */ l("div", {
67
- className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop",
68
- children: /* @__PURE__ */ l("div", {
69
+ children: w.length === 0 ? /* @__PURE__ */ u(o, {
70
+ illustration: "empty-data",
71
+ title: "No report data available yet",
72
+ description: "Track some time first — once you have entries, focus scores or work patterns, ready-to-export reports appear here."
73
+ }) : /* @__PURE__ */ u(f, {
74
+ treatment: "glass",
75
+ glow: !0,
76
+ className: "overflow-hidden",
77
+ children: /* @__PURE__ */ u("div", {
69
78
  className: "divide-y divide-border",
70
- children: S.length === 0 ? /* @__PURE__ */ l("div", {
71
- className: "p-8 text-center text-sm text-text-secondary",
72
- children: "No report data available yet."
73
- }) : S.map((e) => /* @__PURE__ */ u("div", {
79
+ children: w.map((e) => /* @__PURE__ */ d("div", {
74
80
  className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
75
- children: [/* @__PURE__ */ u("div", {
81
+ children: [/* @__PURE__ */ d("div", {
76
82
  className: "flex items-center gap-3",
77
- children: [/* @__PURE__ */ l(s, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
83
+ children: [/* @__PURE__ */ u(c, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
78
84
  className: "text-sm font-medium text-text-primary",
79
85
  children: e.name
80
- }), /* @__PURE__ */ l("p", {
86
+ }), /* @__PURE__ */ u("p", {
81
87
  className: "text-xs text-text-secondary",
82
88
  children: e.period
83
89
  })] })]
84
- }), /* @__PURE__ */ u("div", {
90
+ }), /* @__PURE__ */ d("div", {
85
91
  className: "flex items-center gap-3",
86
- children: [/* @__PURE__ */ l("span", {
92
+ children: [/* @__PURE__ */ u("span", {
87
93
  className: "inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-status-success-bg text-status-success-text",
88
94
  children: e.status
89
- }), /* @__PURE__ */ l("button", {
95
+ }), /* @__PURE__ */ u("button", {
90
96
  className: "rounded-md p-1.5 hover:bg-bg-sunken",
91
- children: /* @__PURE__ */ l(o, { className: "h-4 w-4 text-text-secondary" })
97
+ children: /* @__PURE__ */ u(s, { className: "h-4 w-4 text-text-secondary" })
92
98
  })]
93
99
  })]
94
100
  }, e.id))
@@ -97,6 +103,6 @@ function d() {
97
103
  });
98
104
  }
99
105
  //#endregion
100
- export { d as ReportsPage };
106
+ export { p as ReportsPage };
101
107
 
102
108
  //# sourceMappingURL=ReportsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsPage.js","names":[],"sources":["../../../../src/timecampus/pages/dashboard/ReportsPage.tsx"],"sourcesContent":["import { FileText, Plus, Download } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useGetWorkPatternSummaryQuery,\n useGetFocusScoreSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function ReportsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetTimeEntryStatsQuery({\n skip: !workspaceId,\n });\n\n const { data: patternData, loading: patternLoading } =\n useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const { data: focusData, loading: focusLoading } =\n useGetFocusScoreSummaryQuery({\n skip: !workspaceId,\n });\n\n const stats = statsData?.timeEntryStats;\n const pattern = patternData?.workPatternSummary;\n const focus = focusData?.focusScoreSummary;\n\n const isLoading = statsLoading || patternLoading || focusLoading;\n\n if (isLoading) {\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n actions={\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 Generate Report\n </button>\n }\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load reports data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n // Build dynamic reports from available analytics data\n const reports = [\n ...(stats\n ? [\n {\n id: \"time-summary\",\n name: \"Time Tracking Summary\",\n type: \"time\",\n period: `${Math.round(stats.totalHours)}h total · ${stats.totalEntries} entries`,\n status: \"ready\" as const,\n },\n {\n id: \"billable-summary\",\n name: \"Billable Hours Report\",\n type: \"billing\",\n period: `${Math.round(stats.billableHours)}h billable · ${stats.activeTimers} active`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ...(pattern\n ? [\n {\n id: \"work-pattern\",\n name: \"Work Pattern Analysis\",\n type: \"team\",\n period: `${pattern.averageFocusHours.toFixed(1)}h avg focus · ${Math.round(pattern.averageProductivity)}% productivity`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ...(focus\n ? [\n {\n id: \"focus-score\",\n name: \"Focus Score Report\",\n type: \"productivity\",\n period: `Avg: ${Math.round(focus.averageScore)} · High: ${Math.round(focus.highestScore)} · Low: ${Math.round(focus.lowestScore)}`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ];\n\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n actions={\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 Generate Report\n </button>\n }\n >\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n <div className=\"divide-y divide-border\">\n {reports.length === 0 ? (\n <div className=\"p-8 text-center text-sm text-text-secondary\">\n No report data available yet.\n </div>\n ) : (\n reports.map((report) => (\n <div\n key={report.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <FileText className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {report.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {report.period}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-status-success-bg text-status-success-text\">\n {report.status}\n </span>\n <button className=\"rounded-md p-1.5 hover:bg-bg-sunken\">\n <Download className=\"h-4 w-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n ))\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AAUA,SAAgB,IAAc;CAC5B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA0B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEI,EAAE,MAAM,GAAa,SAAS,MAClC,EAA8B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEE,EAAE,MAAM,GAAW,SAAS,MAChC,EAA6B,EAC3B,MAAM,CAAC,GACR,CAAC,EAEE,IAAQ,GAAW,gBACnB,IAAU,GAAa,oBACvB,IAAQ,GAAW;AAIzB,KAFkB,KAAgB,KAAkB,EAGlD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGX,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA;AAIjB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA;CAKjB,IAAM,IAAU;EACd,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,KAAK,MAAM,EAAM,WAAW,CAAC,YAAY,EAAM,aAAa;GACvE,QAAQ;GACT,EACD;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,KAAK,MAAM,EAAM,cAAc,CAAC,eAAe,EAAM,aAAa;GAC7E,QAAQ;GACT,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,EAAQ,kBAAkB,QAAQ,EAAE,CAAC,gBAAgB,KAAK,MAAM,EAAQ,oBAAoB,CAAC;GACxG,QAAQ;GACT,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,QAAQ,KAAK,MAAM,EAAM,aAAa,CAAC,WAAW,KAAK,MAAM,EAAM,aAAa,CAAC,UAAU,KAAK,MAAM,EAAM,YAAY;GAChI,QAAQ;GACT,CACF,GACD,EAAE;EACP;AAED,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,WAAW,IAClB,kBAAC,OAAD;KAAK,WAAU;eAA8C;KAEvD,CAAA,GAEN,EAAQ,KAAK,MACX,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,EACpD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAO;OACN,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAO;OACN,CAAA,CACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAO;OACH,CAAA,EACP,kBAAC,UAAD;OAAQ,WAAU;iBAChB,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA;OAC7C,CAAA,CACL;QACF;OAtBC,EAAO,GAsBR,CACN;IAEA,CAAA;GACF,CAAA;EACK,CAAA"}
1
+ {"version":3,"file":"ReportsPage.js","names":[],"sources":["../../../../src/timecampus/pages/dashboard/ReportsPage.tsx"],"sourcesContent":["import { FileText, Plus, Download } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useGetWorkPatternSummaryQuery,\n useGetFocusScoreSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function ReportsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetTimeEntryStatsQuery({\n skip: !workspaceId,\n });\n\n const { data: patternData, loading: patternLoading } =\n useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const { data: focusData, loading: focusLoading } =\n useGetFocusScoreSummaryQuery({\n skip: !workspaceId,\n });\n\n const stats = statsData?.timeEntryStats;\n const pattern = patternData?.workPatternSummary;\n const focus = focusData?.focusScoreSummary;\n\n const isLoading = statsLoading || patternLoading || focusLoading;\n\n if (isLoading) {\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n actions={\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 Generate Report\n </button>\n }\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load reports data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n // Build dynamic reports from available analytics data\n const reports = [\n ...(stats\n ? [\n {\n id: \"time-summary\",\n name: \"Time Tracking Summary\",\n type: \"time\",\n period: `${Math.round(stats.totalHours)}h total · ${stats.totalEntries} entries`,\n status: \"ready\" as const,\n },\n {\n id: \"billable-summary\",\n name: \"Billable Hours Report\",\n type: \"billing\",\n period: `${Math.round(stats.billableHours)}h billable · ${stats.activeTimers} active`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ...(pattern\n ? [\n {\n id: \"work-pattern\",\n name: \"Work Pattern Analysis\",\n type: \"team\",\n period: `${pattern.averageFocusHours.toFixed(1)}h avg focus · ${Math.round(pattern.averageProductivity)}% productivity`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ...(focus\n ? [\n {\n id: \"focus-score\",\n name: \"Focus Score Report\",\n type: \"productivity\",\n period: `Avg: ${Math.round(focus.averageScore)} · High: ${Math.round(focus.highestScore)} · Low: ${Math.round(focus.lowestScore)}`,\n status: \"ready\" as const,\n },\n ]\n : []),\n ];\n\n return (\n <PageLayout\n title=\"Reports\"\n description=\"Generate and view time tracking reports\"\n purpose=\"Package your tracked time into shareable, exportable reports — the deliverables you hand to clients for billing or to leadership for capacity and utilisation decisions.\"\n actions={\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 Generate Report\n </button>\n }\n >\n {reports.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No report data available yet\"\n description=\"Track some time first — once you have entries, focus scores or work patterns, ready-to-export reports appear here.\"\n />\n ) : (\n <GlassCard treatment=\"glass\" glow className=\"overflow-hidden\">\n <div className=\"divide-y divide-border\">\n {reports.map((report) => (\n <div\n key={report.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <FileText className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {report.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {report.period}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium bg-status-success-bg text-status-success-text\">\n {report.status}\n </span>\n <button className=\"rounded-md p-1.5 hover:bg-bg-sunken\">\n <Download className=\"h-4 w-4 text-text-secondary\" />\n </button>\n </div>\n </div>\n ))}\n </div>\n </GlassCard>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,IAAc;CAC5B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA0B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEI,EAAE,MAAM,GAAa,SAAS,MAClC,EAA8B,EAC5B,MAAM,CAAC,GACR,CAAC,EAEE,EAAE,MAAM,GAAW,SAAS,MAChC,EAA6B,EAC3B,MAAM,CAAC,GACR,CAAC,EAEE,IAAQ,GAAW,gBACnB,IAAU,GAAa,oBACvB,IAAQ,GAAW;AAIzB,KAFkB,KAAgB,KAAkB,EAGlD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGX,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA;AAIjB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA;CAKjB,IAAM,IAAU;EACd,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,KAAK,MAAM,EAAM,WAAW,CAAC,YAAY,EAAM,aAAa;GACvE,QAAQ;GACT,EACD;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,KAAK,MAAM,EAAM,cAAc,CAAC,eAAe,EAAM,aAAa;GAC7E,QAAQ;GACT,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,GAAG,EAAQ,kBAAkB,QAAQ,EAAE,CAAC,gBAAgB,KAAK,MAAM,EAAQ,oBAAoB,CAAC;GACxG,QAAQ;GACT,CACF,GACD,EAAE;EACN,GAAI,IACA,CACE;GACE,IAAI;GACJ,MAAM;GACN,MAAM;GACN,QAAQ,QAAQ,KAAK,MAAM,EAAM,aAAa,CAAC,WAAW,KAAK,MAAM,EAAM,aAAa,CAAC,UAAU,KAAK,MAAM,EAAM,YAAY;GAChI,QAAQ;GACT,CACF,GACD,EAAE;EACP;AAED,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;EACR,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGV,EAAQ,WAAW,IAClB,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAC1C,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,KAAK,MACZ,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA,EACpD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAO;OACN,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAO;OACN,CAAA,CACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAO;OACH,CAAA,EACP,kBAAC,UAAD;OAAQ,WAAU;iBAChB,kBAAC,GAAD,EAAU,WAAU,+BAAgC,CAAA;OAC7C,CAAA,CACL;QACF;OAtBC,EAAO,GAsBR,CACN;IACE,CAAA;GACI,CAAA;EAEH,CAAA"}
@@ -28,10 +28,12 @@ function u() {
28
28
  return /* @__PURE__ */ l(i, {
29
29
  title: "Email Analytics",
30
30
  description: "Insights into email time management",
31
+ purpose: "Know exactly how much of your day email consumes and how fast you respond — so you can set realistic response targets, batch your inbox, and stop email from quietly running your schedule.",
31
32
  children: [/* @__PURE__ */ l("div", {
32
33
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
33
34
  children: [
34
35
  /* @__PURE__ */ c(t, {
36
+ featured: !0,
35
37
  title: "Emails Today",
36
38
  value: b,
37
39
  icon: /* @__PURE__ */ c(s, { className: "h-5 w-5" })
@@ -1 +1 @@
1
- {"version":3,"file":"EmailAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/email-tracking/EmailAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, Mail, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetEmailTrackingStatsQuery } from \"@/generated/wspace-operations\";\n\nexport function EmailAnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useGetEmailTrackingStatsQuery({\n skip: !workspaceId,\n });\n\n const stats = data?.emailTrackingStats;\n\n if (loading) {\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load email analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalMinutes = Math.round((stats?.totalDuration ?? 0) / 60);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n const timeOnEmail = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;\n const avgResponse =\n stats?.averageResponseTime != null\n ? `${Math.round(stats.averageResponseTime)} min`\n : \"--\";\n const totalEmails = String(stats?.totalEmails ?? 0);\n const importantRatio = stats?.totalEmails\n ? Math.round((stats.importantCount / stats.totalEmails) * 100)\n : 0;\n\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Emails Today\"\n value={totalEmails}\n icon={<Mail className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Time on Email\"\n value={timeOnEmail}\n icon={<Clock className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Avg. Response\"\n value={avgResponse}\n description=\"Target: 15 min\"\n />\n <StatCard\n title=\"Email Score\"\n value={`${importantRatio}%`}\n icon={<BarChart3 className=\"h-5 w-5\" />}\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 Email Volume & Response Time\n </h3>\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\">Chart will render here</p>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,IAAqB;CACnC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,MAAM,CAAC,GACR,CAAC,EAEI,IAAQ,GAAM;AAEpB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA;AAIjB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA;CAIjB,IAAM,IAAe,KAAK,OAAO,GAAO,iBAAiB,KAAK,GAAG,EAC3D,IAAQ,KAAK,MAAM,IAAe,GAAG,EACrC,IAAU,IAAe,IACzB,IAAc,IAAQ,IAAI,GAAG,EAAM,IAAI,EAAQ,KAAK,GAAG,EAAQ,IAC/D,IACJ,GAAO,uBAAuB,OAE1B,OADA,GAAG,KAAK,MAAM,EAAM,oBAAoB,CAAC,OAEzC,IAAc,OAAO,GAAO,eAAe,EAAE,EAC7C,IAAiB,GAAO,cAC1B,KAAK,MAAO,EAAM,iBAAiB,EAAM,cAAe,IAAI,GAC5D;AAEJ,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;KAClC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAe;KACzB,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cAA+C;IAExD,CAAA,EACL,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAA0B,CAAA;IACjE,CAAA,CACF;KACK"}
1
+ {"version":3,"file":"EmailAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/email-tracking/EmailAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, Mail, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetEmailTrackingStatsQuery } from \"@/generated/wspace-operations\";\n\nexport function EmailAnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useGetEmailTrackingStatsQuery({\n skip: !workspaceId,\n });\n\n const stats = data?.emailTrackingStats;\n\n if (loading) {\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load email analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalMinutes = Math.round((stats?.totalDuration ?? 0) / 60);\n const hours = Math.floor(totalMinutes / 60);\n const minutes = totalMinutes % 60;\n const timeOnEmail = hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;\n const avgResponse =\n stats?.averageResponseTime != null\n ? `${Math.round(stats.averageResponseTime)} min`\n : \"--\";\n const totalEmails = String(stats?.totalEmails ?? 0);\n const importantRatio = stats?.totalEmails\n ? Math.round((stats.importantCount / stats.totalEmails) * 100)\n : 0;\n\n return (\n <PageLayout\n title=\"Email Analytics\"\n description=\"Insights into email time management\"\n purpose=\"Know exactly how much of your day email consumes and how fast you respond — so you can set realistic response targets, batch your inbox, and stop email from quietly running your schedule.\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Emails Today\"\n value={totalEmails}\n icon={<Mail className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Time on Email\"\n value={timeOnEmail}\n icon={<Clock className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Avg. Response\"\n value={avgResponse}\n description=\"Target: 15 min\"\n />\n <StatCard\n title=\"Email Score\"\n value={`${importantRatio}%`}\n icon={<BarChart3 className=\"h-5 w-5\" />}\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 Email Volume & Response Time\n </h3>\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\">Chart will render here</p>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,IAAqB;CACnC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,MAAM,CAAC,GACR,CAAC,EAEI,IAAQ,GAAM;AAEpB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA;AAIjB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA;CAIjB,IAAM,IAAe,KAAK,OAAO,GAAO,iBAAiB,KAAK,GAAG,EAC3D,IAAQ,KAAK,MAAM,IAAe,GAAG,EACrC,IAAU,IAAe,IACzB,IAAc,IAAQ,IAAI,GAAG,EAAM,IAAI,EAAQ,KAAK,GAAG,EAAQ,IAC/D,IACJ,GAAO,uBAAuB,OAE1B,OADA,GAAG,KAAK,MAAM,EAAM,oBAAoB,CAAC,OAEzC,IAAc,OAAO,GAAO,eAAe,EAAE,EAC7C,IAAiB,GAAO,cAC1B,KAAK,MAAO,EAAM,iBAAiB,EAAM,cAAe,IAAI,GAC5D;AAEJ,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;YAHV,CAKE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,UAAA;KACA,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;KAClC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAe;KACzB,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,MAAD;IAAI,WAAU;cAA+C;IAExD,CAAA,EACL,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,KAAD;KAAG,WAAU;eAA8B;KAA0B,CAAA;IACjE,CAAA,CACF;KACK"}
@@ -5,46 +5,47 @@ import { PageLayout as i } from "../../components/PageLayout.js";
5
5
  import { useCallback as a, useEffect as o, useState as s } from "react";
6
6
  import { Settings as c } from "lucide-react";
7
7
  import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
+ import { GlassCard as d } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/timecampus/pages/email-tracking/EmailSettingsPage.tsx
9
- var d = "timecampus.email.settings", f = {
10
+ var f = "timecampus.email.settings", p = {
10
11
  autoTrack: !0,
11
12
  categorizeByProject: !0,
12
13
  responseTimeAlerts: !1
13
14
  };
14
- function p() {
15
- let { workspaceId: p = "" } = e(), { data: m, loading: h, error: g } = n({
15
+ function m() {
16
+ let { workspaceId: m = "" } = e(), { data: h, loading: g, error: _ } = n({
16
17
  variables: {
17
18
  scope: "WORKSPACE",
18
19
  limit: 100
19
20
  },
20
- skip: !p
21
- }), [_, { loading: v }] = r(), [y, b] = s(f);
21
+ skip: !m
22
+ }), [v, { loading: y }] = r(), [b, x] = s(p);
22
23
  o(() => {
23
- if (m?.configurations) {
24
- let e = m.configurations.find((e) => e.key === d);
24
+ if (h?.configurations) {
25
+ let e = h.configurations.find((e) => e.key === f);
25
26
  if (e?.value) {
26
27
  let t = e.value;
27
- b({
28
- autoTrack: t.autoTrack ?? f.autoTrack,
29
- categorizeByProject: t.categorizeByProject ?? f.categorizeByProject,
30
- responseTimeAlerts: t.responseTimeAlerts ?? f.responseTimeAlerts
28
+ x({
29
+ autoTrack: t.autoTrack ?? p.autoTrack,
30
+ categorizeByProject: t.categorizeByProject ?? p.categorizeByProject,
31
+ responseTimeAlerts: t.responseTimeAlerts ?? p.responseTimeAlerts
31
32
  });
32
33
  }
33
34
  }
34
- }, [m]);
35
- let x = a(async () => {
36
- await _({ variables: { input: {
37
- key: d,
38
- value: y,
35
+ }, [h]);
36
+ let S = a(async () => {
37
+ await v({ variables: { input: {
38
+ key: f,
39
+ value: b,
39
40
  description: "Email tracking settings",
40
41
  scope: "WORKSPACE"
41
42
  } } });
42
- }, [_, y]);
43
- return h ? /* @__PURE__ */ l(i, {
43
+ }, [v, b]);
44
+ return g ? /* @__PURE__ */ l(i, {
44
45
  title: "Email Settings",
45
46
  description: "Configure email tracking preferences",
46
47
  children: /* @__PURE__ */ l(t, { variant: "detail" })
47
- }) : g ? /* @__PURE__ */ l(i, {
48
+ }) : _ ? /* @__PURE__ */ l(i, {
48
49
  title: "Email Settings",
49
50
  description: "Configure email tracking preferences",
50
51
  children: /* @__PURE__ */ l("div", {
@@ -54,10 +55,13 @@ function p() {
54
55
  }) : /* @__PURE__ */ l(i, {
55
56
  title: "Email Settings",
56
57
  description: "Configure email tracking preferences",
58
+ purpose: "Control how email time is captured and attributed — auto-track reading and replies, tie messages to the right project, and get nudged about slow responses — so email effort shows up in your reports.",
57
59
  children: /* @__PURE__ */ u("div", {
58
60
  className: "mx-auto max-w-2xl space-y-6",
59
- children: [/* @__PURE__ */ u("div", {
60
- className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
61
+ children: [/* @__PURE__ */ u(d, {
62
+ treatment: "glass",
63
+ glow: !0,
64
+ className: "p-6",
61
65
  children: [/* @__PURE__ */ u("h3", {
62
66
  className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
63
67
  children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Tracking Configuration"]
@@ -74,8 +78,8 @@ function p() {
74
78
  children: "Automatically track time spent reading and responding"
75
79
  })] }), /* @__PURE__ */ l("input", {
76
80
  type: "checkbox",
77
- checked: y.autoTrack,
78
- onChange: (e) => b((t) => ({
81
+ checked: b.autoTrack,
82
+ onChange: (e) => x((t) => ({
79
83
  ...t,
80
84
  autoTrack: e.target.checked
81
85
  })),
@@ -92,8 +96,8 @@ function p() {
92
96
  children: "Link emails to projects automatically"
93
97
  })] }), /* @__PURE__ */ l("input", {
94
98
  type: "checkbox",
95
- checked: y.categorizeByProject,
96
- onChange: (e) => b((t) => ({
99
+ checked: b.categorizeByProject,
100
+ onChange: (e) => x((t) => ({
97
101
  ...t,
98
102
  categorizeByProject: e.target.checked
99
103
  })),
@@ -110,8 +114,8 @@ function p() {
110
114
  children: "Notify when response time exceeds threshold"
111
115
  })] }), /* @__PURE__ */ l("input", {
112
116
  type: "checkbox",
113
- checked: y.responseTimeAlerts,
114
- onChange: (e) => b((t) => ({
117
+ checked: b.responseTimeAlerts,
118
+ onChange: (e) => x((t) => ({
115
119
  ...t,
116
120
  responseTimeAlerts: e.target.checked
117
121
  })),
@@ -123,16 +127,16 @@ function p() {
123
127
  }), /* @__PURE__ */ l("div", {
124
128
  className: "flex justify-end",
125
129
  children: /* @__PURE__ */ l("button", {
126
- onClick: x,
127
- disabled: v,
130
+ onClick: S,
131
+ disabled: y,
128
132
  className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50",
129
- children: v ? "Saving..." : "Save Settings"
133
+ children: y ? "Saving..." : "Save Settings"
130
134
  })
131
135
  })]
132
136
  })
133
137
  });
134
138
  }
135
139
  //#endregion
136
- export { p as EmailSettingsPage };
140
+ export { m as EmailSettingsPage };
137
141
 
138
142
  //# sourceMappingURL=EmailSettingsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmailSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/email-tracking/EmailSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst EMAIL_SETTINGS_KEY = \"timecampus.email.settings\";\n\ninterface EmailSettings {\n autoTrack: boolean;\n categorizeByProject: boolean;\n responseTimeAlerts: boolean;\n}\n\nconst DEFAULT_SETTINGS: EmailSettings = {\n autoTrack: true,\n categorizeByProject: true,\n responseTimeAlerts: false,\n};\n\nexport function EmailSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] = useState<EmailSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const emailConfig = data.configurations.find(\n (c: ConfigurationFieldsFragment) => c.key === EMAIL_SETTINGS_KEY,\n );\n if (emailConfig?.value) {\n const val = emailConfig.value as Partial<EmailSettings>;\n setSettings({\n autoTrack: val.autoTrack ?? DEFAULT_SETTINGS.autoTrack,\n categorizeByProject:\n val.categorizeByProject ?? DEFAULT_SETTINGS.categorizeByProject,\n responseTimeAlerts:\n val.responseTimeAlerts ?? DEFAULT_SETTINGS.responseTimeAlerts,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: EMAIL_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Email tracking settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Tracking Configuration\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Auto-track emails\n </span>\n <p className=\"text-xs text-text-secondary\">\n Automatically track time spent reading and responding\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.autoTrack}\n onChange={(e) =>\n setSettings((s) => ({ ...s, autoTrack: e.target.checked }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Categorize by project\n </span>\n <p className=\"text-xs text-text-secondary\">\n Link emails to projects automatically\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.categorizeByProject}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n categorizeByProject: e.target.checked,\n }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Response time alerts\n </span>\n <p className=\"text-xs text-text-secondary\">\n Notify when response time exceeds threshold\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.responseTimeAlerts}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n responseTimeAlerts: e.target.checked,\n }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EmailSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/email-tracking/EmailSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst EMAIL_SETTINGS_KEY = \"timecampus.email.settings\";\n\ninterface EmailSettings {\n autoTrack: boolean;\n categorizeByProject: boolean;\n responseTimeAlerts: boolean;\n}\n\nconst DEFAULT_SETTINGS: EmailSettings = {\n autoTrack: true,\n categorizeByProject: true,\n responseTimeAlerts: false,\n};\n\nexport function EmailSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] = useState<EmailSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const emailConfig = data.configurations.find(\n (c: ConfigurationFieldsFragment) => c.key === EMAIL_SETTINGS_KEY,\n );\n if (emailConfig?.value) {\n const val = emailConfig.value as Partial<EmailSettings>;\n setSettings({\n autoTrack: val.autoTrack ?? DEFAULT_SETTINGS.autoTrack,\n categorizeByProject:\n val.categorizeByProject ?? DEFAULT_SETTINGS.categorizeByProject,\n responseTimeAlerts:\n val.responseTimeAlerts ?? DEFAULT_SETTINGS.responseTimeAlerts,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: EMAIL_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Email tracking settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Email Settings\"\n description=\"Configure email tracking preferences\"\n purpose=\"Control how email time is captured and attributed — auto-track reading and replies, tie messages to the right project, and get nudged about slow responses — so email effort shows up in your reports.\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Tracking Configuration\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Auto-track emails\n </span>\n <p className=\"text-xs text-text-secondary\">\n Automatically track time spent reading and responding\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.autoTrack}\n onChange={(e) =>\n setSettings((s) => ({ ...s, autoTrack: e.target.checked }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Categorize by project\n </span>\n <p className=\"text-xs text-text-secondary\">\n Link emails to projects automatically\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.categorizeByProject}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n categorizeByProject: e.target.checked,\n }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Response time alerts\n </span>\n <p className=\"text-xs text-text-secondary\">\n Notify when response time exceeds threshold\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={settings.responseTimeAlerts}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n responseTimeAlerts: e.target.checked,\n }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </GlassCard>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}