@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
@@ -5,21 +5,22 @@ import { PageLayout as i } from "../../components/PageLayout.js";
5
5
  import { useEffect as a, useState as o } from "react";
6
6
  import { Shield as s } from "lucide-react";
7
7
  import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
+ import { GlassCard as u } from "@burdenoff/fe-libs/ui";
8
9
  //#region src/timecampus/pages/location-tracking/LocationPrivacySettingsPage.tsx
9
- var u = "location.privacy";
10
- function d() {
11
- let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = n({ variables: { key: u } }), [h, { loading: g }] = r(), _ = f?.configurationByKey?.value ?? {}, [v, y] = o(!0), [b, x] = o(!1), [S, C] = o(!1);
10
+ var d = "location.privacy";
11
+ function f() {
12
+ let { workspaceId: f = "" } = e(), { data: p, loading: m, error: h } = n({ variables: { key: d } }), [g, { loading: _ }] = r(), v = p?.configurationByKey?.value ?? {}, [y, b] = o(!0), [x, S] = o(!1), [C, w] = o(!1);
12
13
  return a(() => {
13
- _ && (y(_.trackingEnabled ?? !0), x(_.shareWithTeam ?? !1), C(_.preciseLocation ?? !1));
14
+ v && (b(v.trackingEnabled ?? !0), S(v.shareWithTeam ?? !1), w(v.preciseLocation ?? !1));
14
15
  }, [
15
- _.trackingEnabled,
16
- _.shareWithTeam,
17
- _.preciseLocation
18
- ]), p ? /* @__PURE__ */ c(i, {
16
+ v.trackingEnabled,
17
+ v.shareWithTeam,
18
+ v.preciseLocation
19
+ ]), m ? /* @__PURE__ */ c(i, {
19
20
  title: "Location Privacy Settings",
20
21
  description: "Control location tracking and data sharing",
21
22
  children: /* @__PURE__ */ c(t, { variant: "detail" })
22
- }) : m ? /* @__PURE__ */ c(i, {
23
+ }) : h ? /* @__PURE__ */ c(i, {
23
24
  title: "Location Privacy Settings",
24
25
  description: "Control location tracking and data sharing",
25
26
  children: /* @__PURE__ */ c("div", {
@@ -29,10 +30,13 @@ function d() {
29
30
  }) : /* @__PURE__ */ c(i, {
30
31
  title: "Location Privacy Settings",
31
32
  description: "Control location tracking and data sharing",
33
+ purpose: "You're in charge of your location data here — turn tracking on or off, decide whether teammates can see where you are, and choose precise versus approximate positioning before any location is ever recorded.",
32
34
  children: /* @__PURE__ */ l("div", {
33
35
  className: "mx-auto max-w-2xl space-y-6",
34
- children: [/* @__PURE__ */ l("div", {
35
- className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
36
+ children: [/* @__PURE__ */ l(u, {
37
+ treatment: "glass",
38
+ glow: !0,
39
+ className: "p-6",
36
40
  children: [/* @__PURE__ */ l("h3", {
37
41
  className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
38
42
  children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Privacy Controls"]
@@ -49,8 +53,8 @@ function d() {
49
53
  children: "Allow the app to track your work location"
50
54
  })] }), /* @__PURE__ */ c("input", {
51
55
  type: "checkbox",
52
- checked: v,
53
- onChange: (e) => y(e.target.checked),
56
+ checked: y,
57
+ onChange: (e) => b(e.target.checked),
54
58
  className: "h-4 w-4 rounded border-border-subtle"
55
59
  })]
56
60
  }),
@@ -64,8 +68,8 @@ function d() {
64
68
  children: "Let team members see your current location"
65
69
  })] }), /* @__PURE__ */ c("input", {
66
70
  type: "checkbox",
67
- checked: b,
68
- onChange: (e) => x(e.target.checked),
71
+ checked: x,
72
+ onChange: (e) => S(e.target.checked),
69
73
  className: "h-4 w-4 rounded border-border-subtle"
70
74
  })]
71
75
  }),
@@ -79,8 +83,8 @@ function d() {
79
83
  children: "Use precise GPS vs approximate location"
80
84
  })] }), /* @__PURE__ */ c("input", {
81
85
  type: "checkbox",
82
- checked: S,
83
- onChange: (e) => C(e.target.checked),
86
+ checked: C,
87
+ onChange: (e) => w(e.target.checked),
84
88
  className: "h-4 w-4 rounded border-border-subtle"
85
89
  })]
86
90
  })
@@ -90,26 +94,26 @@ function d() {
90
94
  className: "flex justify-end",
91
95
  children: /* @__PURE__ */ c("button", {
92
96
  onClick: async () => {
93
- await h({ variables: { input: {
94
- key: u,
97
+ await g({ variables: { input: {
98
+ key: d,
95
99
  value: {
96
- trackingEnabled: v,
97
- shareWithTeam: b,
98
- preciseLocation: S
100
+ trackingEnabled: y,
101
+ shareWithTeam: x,
102
+ preciseLocation: C
99
103
  },
100
104
  description: "Location privacy settings",
101
105
  scope: "USER"
102
106
  } } });
103
107
  },
104
- disabled: g,
108
+ disabled: _,
105
109
  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",
106
- children: g ? "Saving..." : "Save Settings"
110
+ children: _ ? "Saving..." : "Save Settings"
107
111
  })
108
112
  })]
109
113
  })
110
114
  });
111
115
  }
112
116
  //#endregion
113
- export { d as LocationPrivacySettingsPage };
117
+ export { f as LocationPrivacySettingsPage };
114
118
 
115
119
  //# sourceMappingURL=LocationPrivacySettingsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocationPrivacySettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationPrivacySettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Shield } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"location.privacy\";\n\nexport function LocationPrivacySettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [trackingEnabled, setTrackingEnabled] = useState(true);\n const [shareWithTeam, setShareWithTeam] = useState(false);\n const [preciseLocation, setPreciseLocation] = useState(false);\n\n useEffect(() => {\n if (configValue) {\n setTrackingEnabled(configValue.trackingEnabled ?? true);\n setShareWithTeam(configValue.shareWithTeam ?? false);\n setPreciseLocation(configValue.preciseLocation ?? false);\n }\n }, [\n configValue.trackingEnabled,\n configValue.shareWithTeam,\n configValue.preciseLocation,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { trackingEnabled, shareWithTeam, preciseLocation },\n description: \"Location privacy settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\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 privacy settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\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 <Shield className=\"h-4 w-4\" />\n Privacy Controls\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 Enable location tracking\n </span>\n <p className=\"text-xs text-text-secondary\">\n Allow the app to track your work location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={trackingEnabled}\n onChange={(e) => setTrackingEnabled(e.target.checked)}\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 Share with team\n </span>\n <p className=\"text-xs text-text-secondary\">\n Let team members see your current location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={shareWithTeam}\n onChange={(e) => setShareWithTeam(e.target.checked)}\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 Precise location\n </span>\n <p className=\"text-xs text-text-secondary\">\n Use precise GPS vs approximate location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={preciseLocation}\n onChange={(e) => setPreciseLocation(e.target.checked)}\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":";;;;;;;;AAUA,IAAM,IAAa;AAEnB,SAAgB,IAA8B;CAC5C,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,WAAW,EAAE,KAAK,GAAY,EAC/B,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EAEvE,IAAe,GAAM,oBAAoB,SAAS,EAAE,EAKpD,CAAC,GAAiB,KAAsB,EAAS,GAAK,EACtD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAiB,KAAsB,EAAS,GAAM;AAmD7D,QAjDA,QAAgB;AACd,EAAI,MACF,EAAmB,EAAY,mBAAmB,GAAK,EACvD,EAAiB,EAAY,iBAAiB,GAAM,EACpD,EAAmB,EAAY,mBAAmB,GAAM;IAEzD;EACD,EAAY;EACZ,EAAY;EACZ,EAAY;EACb,CAAC,EAeE,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,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,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,mBAE3B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAiB,EAAE,OAAO,QAAQ;QACnD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACJ;OACF;OACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SArGS,YAAY;AAC7B,YAAM,EAAiB,EACrB,WAAW,EACT,OAAO;OACL,KAAK;OACL,OAAO;QAAE;QAAiB;QAAe;QAAiB;OAC1D,aAAa;OACb,OAAO;OACR,EACF,EACF,CAAC;;KA4FM,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
1
+ {"version":3,"file":"LocationPrivacySettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationPrivacySettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Shield } 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 useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"location.privacy\";\n\nexport function LocationPrivacySettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [trackingEnabled, setTrackingEnabled] = useState(true);\n const [shareWithTeam, setShareWithTeam] = useState(false);\n const [preciseLocation, setPreciseLocation] = useState(false);\n\n useEffect(() => {\n if (configValue) {\n setTrackingEnabled(configValue.trackingEnabled ?? true);\n setShareWithTeam(configValue.shareWithTeam ?? false);\n setPreciseLocation(configValue.preciseLocation ?? false);\n }\n }, [\n configValue.trackingEnabled,\n configValue.shareWithTeam,\n configValue.preciseLocation,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { trackingEnabled, shareWithTeam, preciseLocation },\n description: \"Location privacy settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\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 privacy settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n purpose=\"You're in charge of your location data here — turn tracking on or off, decide whether teammates can see where you are, and choose precise versus approximate positioning before any location is ever recorded.\"\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 <Shield className=\"h-4 w-4\" />\n Privacy Controls\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 Enable location tracking\n </span>\n <p className=\"text-xs text-text-secondary\">\n Allow the app to track your work location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={trackingEnabled}\n onChange={(e) => setTrackingEnabled(e.target.checked)}\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 Share with team\n </span>\n <p className=\"text-xs text-text-secondary\">\n Let team members see your current location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={shareWithTeam}\n onChange={(e) => setShareWithTeam(e.target.checked)}\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 Precise location\n </span>\n <p className=\"text-xs text-text-secondary\">\n Use precise GPS vs approximate location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={preciseLocation}\n onChange={(e) => setPreciseLocation(e.target.checked)}\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":";;;;;;;;;AAWA,IAAM,IAAa;AAEnB,SAAgB,IAA8B;CAC5C,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,WAAW,EAAE,KAAK,GAAY,EAC/B,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EAEvE,IAAe,GAAM,oBAAoB,SAAS,EAAE,EAKpD,CAAC,GAAiB,KAAsB,EAAS,GAAK,EACtD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAiB,KAAsB,EAAS,GAAM;AAmD7D,QAjDA,QAAgB;AACd,EAAI,MACF,EAAmB,EAAY,mBAAmB,GAAK,EACvD,EAAiB,EAAY,iBAAiB,GAAM,EACpD,EAAmB,EAAY,mBAAmB,GAAM;IAEzD;EACD,EAAY;EACZ,EAAY;EACZ,EAAY;EACb,CAAC,EAeE,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,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;YAER,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD;IAAW,WAAU;IAAQ,MAAA;IAAK,WAAU;cAA5C,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,mBAE3B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAiB,EAAE,OAAO,QAAQ;QACnD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACJ;OACI;OACZ,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SAtGS,YAAY;AAC7B,YAAM,EAAiB,EACrB,WAAW,EACT,OAAO;OACL,KAAK;OACL,OAAO;QAAE;QAAiB;QAAe;QAAiB;OAC1D,aAAa;OACb,OAAO;OACR,EACF,EACF,CAAC;;KA6FM,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
@@ -4,67 +4,71 @@ import { StatCard as n } from "../../components/StatCard.js";
4
4
  import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
5
5
  import { useGetLocationStatsQuery as i, useListLocationEntriesQuery as a } from "../../../generated/wspace-operations.js";
6
6
  import { PageLayout as o } from "../../components/PageLayout.js";
7
- import { Clock as s, MapPin as c } from "lucide-react";
8
- import { jsx as l, jsxs as u } from "react/jsx-runtime";
7
+ import { EmptyState as s } from "../../components/EmptyState.js";
8
+ import { Clock as c, MapPin as l } from "lucide-react";
9
+ import { jsx as u, jsxs as d } from "react/jsx-runtime";
9
10
  //#region src/timecampus/pages/location-tracking/LocationTrackingPage.tsx
10
- function d() {
11
- let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = a(), { data: h, loading: g, error: _ } = i(), v = f?.locationEntries?.items ?? [], y = h?.locationStats;
12
- return p && g ? /* @__PURE__ */ l(o, {
11
+ function f() {
12
+ let { workspaceId: f = "" } = e(), { data: p, loading: m, error: h } = a(), { data: g, loading: _, error: v } = i(), y = p?.locationEntries?.items ?? [], b = g?.locationStats;
13
+ return m && _ ? /* @__PURE__ */ u(o, {
13
14
  title: "Location Tracking",
14
15
  description: "Track work locations and productivity",
15
- children: /* @__PURE__ */ l(r, {
16
+ children: /* @__PURE__ */ u(r, {
16
17
  variant: "list",
17
18
  count: 4
18
19
  })
19
- }) : m && _ ? /* @__PURE__ */ l(o, {
20
+ }) : h && v ? /* @__PURE__ */ u(o, {
20
21
  title: "Location Tracking",
21
22
  description: "Track work locations and productivity",
22
- children: /* @__PURE__ */ l("div", {
23
+ children: /* @__PURE__ */ u("div", {
23
24
  className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
24
25
  children: "Failed to load location data. Please try again later."
25
26
  })
26
- }) : /* @__PURE__ */ u(o, {
27
+ }) : /* @__PURE__ */ d(o, {
27
28
  title: "Location Tracking",
28
29
  description: "Track work locations and productivity",
29
- children: [/* @__PURE__ */ u("div", {
30
+ purpose: "See where work actually happens — office, home, client sites — and how long you spend at each, so you can verify on-site time, support field teams, and back up location-based billing.",
31
+ children: [/* @__PURE__ */ d("div", {
30
32
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
31
33
  children: [
32
- /* @__PURE__ */ l(n, {
34
+ /* @__PURE__ */ u(n, {
35
+ featured: !0,
33
36
  title: "Total Locations",
34
- value: String(y?.totalLocations ?? 0),
35
- icon: /* @__PURE__ */ l(c, { className: "h-5 w-5" })
37
+ value: String(b?.totalLocations ?? 0),
38
+ icon: /* @__PURE__ */ u(l, { className: "h-5 w-5" })
36
39
  }),
37
- /* @__PURE__ */ l(n, {
40
+ /* @__PURE__ */ u(n, {
38
41
  title: "Unique Addresses",
39
- value: String(y?.uniqueAddresses ?? 0),
40
- icon: /* @__PURE__ */ l(c, { className: "h-5 w-5" })
42
+ value: String(b?.uniqueAddresses ?? 0),
43
+ icon: /* @__PURE__ */ u(l, { className: "h-5 w-5" })
41
44
  }),
42
- /* @__PURE__ */ l(n, {
45
+ /* @__PURE__ */ u(n, {
43
46
  title: "Most Frequent",
44
- value: y?.mostFrequentLocation ?? "N/A"
47
+ value: b?.mostFrequentLocation ?? "N/A"
45
48
  }),
46
- /* @__PURE__ */ l(n, {
49
+ /* @__PURE__ */ u(n, {
47
50
  title: "Total Duration",
48
- value: t((y?.totalDuration ?? 0) / 3600),
49
- icon: /* @__PURE__ */ l(s, { className: "h-5 w-5" }),
51
+ value: t((b?.totalDuration ?? 0) / 3600),
52
+ icon: /* @__PURE__ */ u(c, { className: "h-5 w-5" }),
50
53
  description: "Tracked time"
51
54
  })
52
55
  ]
53
- }), /* @__PURE__ */ l("div", {
56
+ }), y.length === 0 && !m ? /* @__PURE__ */ u(s, {
57
+ illustration: "empty-data",
58
+ title: "No location entries found",
59
+ description: "With location tracking enabled, the places you work from will show up here with time spent at each."
60
+ }) : /* @__PURE__ */ u("div", {
54
61
  className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop",
55
62
  children: /* @__PURE__ */ u("div", {
56
63
  className: "divide-y divide-border",
57
- children: [v.length === 0 && !p && /* @__PURE__ */ l("div", {
58
- className: "p-4 text-center text-sm text-text-secondary",
59
- children: "No location entries found."
60
- }), v.map((e) => /* @__PURE__ */ u("div", {
64
+ children: y.map((e) => /* @__PURE__ */ d("div", {
61
65
  className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
62
- children: [/* @__PURE__ */ u("div", {
66
+ children: [/* @__PURE__ */ d("div", {
63
67
  className: "flex items-center gap-3",
64
- children: [/* @__PURE__ */ l(c, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
68
+ children: [/* @__PURE__ */ u(l, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ d("div", { children: [/* @__PURE__ */ u("p", {
65
69
  className: "text-sm font-medium text-text-primary",
66
70
  children: e.address ?? "Unknown Location"
67
- }), /* @__PURE__ */ u("p", {
71
+ }), /* @__PURE__ */ d("p", {
68
72
  className: "text-xs text-text-secondary",
69
73
  children: [
70
74
  e.geofenceId ? "Geofenced" : "Manual",
@@ -73,25 +77,25 @@ function d() {
73
77
  new Date(e.startTime).toLocaleDateString()
74
78
  ]
75
79
  })] })]
76
- }), /* @__PURE__ */ l("div", {
80
+ }), /* @__PURE__ */ u("div", {
77
81
  className: "flex items-center gap-4",
78
- children: /* @__PURE__ */ u("div", {
82
+ children: /* @__PURE__ */ d("div", {
79
83
  className: "text-right",
80
- children: [/* @__PURE__ */ l("p", {
84
+ children: [/* @__PURE__ */ u("p", {
81
85
  className: "text-sm font-medium text-text-primary",
82
86
  children: e.duration ? t(e.duration / 3600) : "Active"
83
- }), /* @__PURE__ */ l("p", {
87
+ }), /* @__PURE__ */ u("p", {
84
88
  className: "text-xs text-text-secondary",
85
89
  children: "duration"
86
90
  })]
87
91
  })
88
92
  })]
89
- }, e.id))]
93
+ }, e.id))
90
94
  })
91
95
  })]
92
96
  });
93
97
  }
94
98
  //#endregion
95
- export { d as LocationTrackingPage };
99
+ export { f as LocationTrackingPage };
96
100
 
97
101
  //# sourceMappingURL=LocationTrackingPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocationTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationTrackingPage.tsx"],"sourcesContent":["import { MapPin, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListLocationEntriesQuery,\n useGetLocationStatsQuery,\n type LocationEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function LocationTrackingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: entriesData,\n loading: entriesLoading,\n error: entriesError,\n } = useListLocationEntriesQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetLocationStatsQuery();\n\n const locations = entriesData?.locationEntries?.items ?? [];\n const stats = statsData?.locationStats;\n\n if (entriesLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (entriesError && statsError) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations 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 location data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Locations\"\n value={String(stats?.totalLocations ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Unique Addresses\"\n value={String(stats?.uniqueAddresses ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Most Frequent\"\n value={stats?.mostFrequentLocation ?? \"N/A\"}\n />\n <StatCard\n title=\"Total Duration\"\n value={formatHours((stats?.totalDuration ?? 0) / 3600)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"Tracked time\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n <div className=\"divide-y divide-border\">\n {locations.length === 0 && !entriesLoading && (\n <div className=\"p-4 text-center text-sm text-text-secondary\">\n No location entries found.\n </div>\n )}\n {locations.map((location: LocationEntryFieldsFragment) => (\n <div\n key={location.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 <MapPin className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {location.address ?? \"Unknown Location\"}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {location.geofenceId ? \"Geofenced\" : \"Manual\"} &middot;{\" \"}\n {new Date(location.startTime).toLocaleDateString()}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">\n {location.duration\n ? formatHours(location.duration / 3600)\n : \"Active\"}\n </p>\n <p className=\"text-xs text-text-secondary\">duration</p>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA6B,EAC3B,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA0B,EAExB,IAAY,GAAa,iBAAiB,SAAS,EAAE,EACrD,IAAQ,GAAW;AA0BzB,QAxBI,KAAkB,IAElB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,KAAgB,IAEhB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,kBAAkB,EAAE;KACzC,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,mBAAmB,EAAE;KAC1C,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAO,wBAAwB;KACtC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAa,GAAO,iBAAiB,KAAK,KAAK;KACtD,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,EAAU,WAAW,KAAK,CAAC,KAC1B,kBAAC,OAAD;KAAK,WAAU;eAA8C;KAEvD,CAAA,EAEP,EAAU,KAAK,MACd,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,+BAAgC,CAAA,EAClD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS,WAAW;OACnB,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAS,aAAa,cAAc;QAAS;QAAU;QACvD,IAAI,KAAK,EAAS,UAAU,CAAC,oBAAoB;QAChD;SACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAS,WACN,EAAY,EAAS,WAAW,KAAK,GACrC;QACF,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA,CACnD;;MACF,CAAA,CACF;OAzBC,EAAS,GAyBV,CACN,CACE;;GACF,CAAA,CACK"}
1
+ {"version":3,"file":"LocationTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationTrackingPage.tsx"],"sourcesContent":["import { MapPin, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { EmptyState } from \"../../components/EmptyState\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListLocationEntriesQuery,\n useGetLocationStatsQuery,\n type LocationEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function LocationTrackingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: entriesData,\n loading: entriesLoading,\n error: entriesError,\n } = useListLocationEntriesQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetLocationStatsQuery();\n\n const locations = entriesData?.locationEntries?.items ?? [];\n const stats = statsData?.locationStats;\n\n if (entriesLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (entriesError && statsError) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations 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 location data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n purpose=\"See where work actually happens — office, home, client sites — and how long you spend at each, so you can verify on-site time, support field teams, and back up location-based billing.\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Total Locations\"\n value={String(stats?.totalLocations ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Unique Addresses\"\n value={String(stats?.uniqueAddresses ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Most Frequent\"\n value={stats?.mostFrequentLocation ?? \"N/A\"}\n />\n <StatCard\n title=\"Total Duration\"\n value={formatHours((stats?.totalDuration ?? 0) / 3600)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"Tracked time\"\n />\n </div>\n\n {locations.length === 0 && !entriesLoading ? (\n <EmptyState\n illustration=\"empty-data\"\n title=\"No location entries found\"\n description=\"With location tracking enabled, the places you work from will show up here with time spent at each.\"\n />\n ) : (\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop\">\n <div className=\"divide-y divide-border\">\n {locations.map((location: LocationEntryFieldsFragment) => (\n <div\n key={location.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 <MapPin className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {location.address ?? \"Unknown Location\"}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {location.geofenceId ? \"Geofenced\" : \"Manual\"} &middot;{\" \"}\n {new Date(location.startTime).toLocaleDateString()}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">\n {location.duration\n ? formatHours(location.duration / 3600)\n : \"Active\"}\n </p>\n <p className=\"text-xs text-text-secondary\">duration</p>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;AAaA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA6B,EAC3B,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA0B,EAExB,IAAY,GAAa,iBAAiB,SAAS,EAAE,EACrD,IAAQ,GAAW;AA0BzB,QAxBI,KAAkB,IAElB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,KAAgB,IAEhB,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,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,UAAA;KACA,OAAM;KACN,OAAO,OAAO,GAAO,kBAAkB,EAAE;KACzC,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,mBAAmB,EAAE;KAC1C,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAO,wBAAwB;KACtC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAa,GAAO,iBAAiB,KAAK,KAAK;KACtD,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACE;MAEL,EAAU,WAAW,KAAK,CAAC,IAC1B,kBAAC,GAAD;GACE,cAAa;GACb,OAAM;GACN,aAAY;GACZ,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAU,KAAK,MACd,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,+BAAgC,CAAA,EAClD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS,WAAW;OACnB,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAS,aAAa,cAAc;QAAS;QAAU;QACvD,IAAI,KAAK,EAAS,UAAU,CAAC,oBAAoB;QAChD;SACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAS,WACN,EAAY,EAAS,WAAW,KAAK,GACrC;QACF,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA,CACnD;;MACF,CAAA,CACF;OAzBC,EAAS,GAyBV,CACN;IACE,CAAA;GACF,CAAA,CAEG"}
@@ -32,10 +32,12 @@ function f() {
32
32
  return /* @__PURE__ */ d(a, {
33
33
  title: "Meeting Analytics",
34
34
  description: "Insights into meeting time and cost",
35
+ purpose: "Put a number on your meeting habit — total hours, dollar cost and follow-through on action items — so you can cut the meetings that don't pay for themselves and reclaim time for focused work.",
35
36
  children: [/* @__PURE__ */ d("div", {
36
37
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
37
38
  children: [
38
39
  /* @__PURE__ */ u(n, {
40
+ featured: !0,
39
41
  title: "Total Meetings",
40
42
  value: String(g?.totalMeetings ?? 0),
41
43
  icon: /* @__PURE__ */ u(s, { className: "h-5 w-5" }),
@@ -1 +1 @@
1
- {"version":3,"file":"MeetingAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, CalendarDays, Clock, DollarSign } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetMeetingStatsQuery } from \"@/generated/wspace-operations\";\nimport { formatCurrency } from \"../../utils/helpers\";\n\nexport function MeetingAnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetMeetingStatsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const stats = data?.meetingStats;\n\n if (loading) {\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\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 meeting analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalHours = Math.round((stats?.totalDuration ?? 0) / 60);\n const avgDuration = Math.round(stats?.averageDuration ?? 0);\n\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Meetings\"\n value={String(stats?.totalMeetings ?? 0)}\n icon={<CalendarDays className=\"h-5 w-5\" />}\n trend={{\n value: stats?.actionItemsCompleted ?? 0,\n label: \"actions completed\",\n }}\n />\n <StatCard\n title=\"Meeting Hours\"\n value={`${totalHours}h`}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{ value: stats?.totalDuration ?? 0, label: \"total minutes\" }}\n />\n <StatCard\n title=\"Meeting Cost\"\n value={formatCurrency(stats?.totalCost ?? 0)}\n icon={<DollarSign className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Avg. Duration\"\n value={`${avgDuration} min`}\n icon={<BarChart3 className=\"h-5 w-5\" />}\n trend={{ value: stats?.averageRating ?? 0, label: \"avg rating\" }}\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 Meeting Time Distribution\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\">\n {stats\n ? `${stats.totalMeetings} meetings · ${stats.actionItemsTotal} action items (${stats.actionItemsCompleted} completed)`\n : \"Chart will render here\"}\n </p>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAAwB;EACvD,WAAW,EAAE,gBAAa;EAC1B,MAAM,CAAC;EACR,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;aAAoG;GAE7G,CAAA;EACK,CAAA;CAIjB,IAAM,IAAa,KAAK,OAAO,GAAO,iBAAiB,KAAK,GAAG,EACzD,IAAc,KAAK,MAAM,GAAO,mBAAmB,EAAE;AAE3D,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,iBAAiB,EAAE;KACxC,MAAM,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;KAC1C,OAAO;MACL,OAAO,GAAO,wBAAwB;MACtC,OAAO;MACR;KACD,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAW;KACrB,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,OAAO;MAAE,OAAO,GAAO,iBAAiB;MAAG,OAAO;MAAiB;KACnE,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,EAAe,GAAO,aAAa,EAAE;KAC5C,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;KACxC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAY;KACtB,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,OAAO;MAAE,OAAO,GAAO,iBAAiB;MAAG,OAAO;MAAc;KAChE,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;eACV,IACG,GAAG,EAAM,cAAc,cAAc,EAAM,iBAAiB,iBAAiB,EAAM,qBAAqB,eACxG;KACF,CAAA;IACA,CAAA,CACF;KACK"}
1
+ {"version":3,"file":"MeetingAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, CalendarDays, Clock, DollarSign } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetMeetingStatsQuery } from \"@/generated/wspace-operations\";\nimport { formatCurrency } from \"../../utils/helpers\";\n\nexport function MeetingAnalyticsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetMeetingStatsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const stats = data?.meetingStats;\n\n if (loading) {\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\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 meeting analytics. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalHours = Math.round((stats?.totalDuration ?? 0) / 60);\n const avgDuration = Math.round(stats?.averageDuration ?? 0);\n\n return (\n <PageLayout\n title=\"Meeting Analytics\"\n description=\"Insights into meeting time and cost\"\n purpose=\"Put a number on your meeting habit — total hours, dollar cost and follow-through on action items — so you can cut the meetings that don't pay for themselves and reclaim time for focused work.\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n featured\n title=\"Total Meetings\"\n value={String(stats?.totalMeetings ?? 0)}\n icon={<CalendarDays className=\"h-5 w-5\" />}\n trend={{\n value: stats?.actionItemsCompleted ?? 0,\n label: \"actions completed\",\n }}\n />\n <StatCard\n title=\"Meeting Hours\"\n value={`${totalHours}h`}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{ value: stats?.totalDuration ?? 0, label: \"total minutes\" }}\n />\n <StatCard\n title=\"Meeting Cost\"\n value={formatCurrency(stats?.totalCost ?? 0)}\n icon={<DollarSign className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Avg. Duration\"\n value={`${avgDuration} min`}\n icon={<BarChart3 className=\"h-5 w-5\" />}\n trend={{ value: stats?.averageRating ?? 0, label: \"avg rating\" }}\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 Meeting Time Distribution\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\">\n {stats\n ? `${stats.totalMeetings} meetings · ${stats.actionItemsTotal} action items (${stats.actionItemsCompleted} completed)`\n : \"Chart will render here\"}\n </p>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAQA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAAwB;EACvD,WAAW,EAAE,gBAAa;EAC1B,MAAM,CAAC;EACR,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;aAAoG;GAE7G,CAAA;EACK,CAAA;CAIjB,IAAM,IAAa,KAAK,OAAO,GAAO,iBAAiB,KAAK,GAAG,EACzD,IAAc,KAAK,MAAM,GAAO,mBAAmB,EAAE;AAE3D,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,OAAO,GAAO,iBAAiB,EAAE;KACxC,MAAM,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA;KAC1C,OAAO;MACL,OAAO,GAAO,wBAAwB;MACtC,OAAO;MACR;KACD,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAW;KACrB,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,OAAO;MAAE,OAAO,GAAO,iBAAiB;MAAG,OAAO;MAAiB;KACnE,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,EAAe,GAAO,aAAa,EAAE;KAC5C,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;KACxC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAY;KACtB,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;KACvC,OAAO;MAAE,OAAO,GAAO,iBAAiB;MAAG,OAAO;MAAc;KAChE,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;eACV,IACG,GAAG,EAAM,cAAc,cAAc,EAAM,iBAAiB,iBAAiB,EAAM,qBAAqB,eACxG;KACF,CAAA;IACA,CAAA,CACF;KACK"}
@@ -4,37 +4,41 @@ import { PageLayout as n } from "../../components/PageLayout.js";
4
4
  import { useCallback as r, useState as i } from "react";
5
5
  import { ArrowLeft as a } from "lucide-react";
6
6
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ import { GlassCard as c } from "@burdenoff/fe-libs/ui";
7
8
  //#region src/timecampus/pages/meetings/MeetingCreatePage.tsx
8
- function c() {
9
- let { workspaceId: c = "" } = e(), [l, { loading: u }] = t(), [d, f] = i(""), [p, m] = i(""), [h, g] = i(30), [_, v] = i(""), y = r(async () => {
10
- !c || !d || !p || (await l({
9
+ function l() {
10
+ let { workspaceId: l = "" } = e(), [u, { loading: d }] = t(), [f, p] = i(""), [m, h] = i(""), [g, _] = i(30), [v, y] = i(""), b = r(async () => {
11
+ !l || !f || !m || (await u({
11
12
  variables: { input: {
12
- workspaceId: c,
13
- title: d,
13
+ workspaceId: l,
14
+ title: f,
14
15
  meetingType: "TEAM",
15
- startTime: new Date(p).toISOString(),
16
- duration: h,
17
- notes: _ || void 0
16
+ startTime: new Date(m).toISOString(),
17
+ duration: g,
18
+ notes: v || void 0
18
19
  } },
19
20
  refetchQueries: ["ListMeetings"]
20
- }), f(""), m(""), g(30), v(""));
21
+ }), p(""), h(""), _(30), y(""));
21
22
  }, [
22
- c,
23
- d,
24
- p,
25
- h,
26
- _,
27
- l
23
+ l,
24
+ f,
25
+ m,
26
+ g,
27
+ v,
28
+ u
28
29
  ]);
29
30
  return /* @__PURE__ */ o(n, {
30
31
  title: "Schedule Meeting",
31
32
  description: "Create a new meeting",
33
+ purpose: "Book a meeting with its time and agenda so it's tracked alongside your work — letting TimeCampus account for the hours it consumes and surface its cost and action items afterwards.",
32
34
  actions: /* @__PURE__ */ s("button", {
33
35
  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",
34
36
  children: [/* @__PURE__ */ o(a, { className: "h-4 w-4" }), "Back"]
35
37
  }),
36
- children: /* @__PURE__ */ o("div", {
37
- className: "mx-auto max-w-2xl rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
38
+ children: /* @__PURE__ */ o(c, {
39
+ treatment: "glass",
40
+ glow: !0,
41
+ className: "mx-auto max-w-2xl p-6",
38
42
  children: /* @__PURE__ */ s("div", {
39
43
  className: "space-y-4",
40
44
  children: [
@@ -44,8 +48,8 @@ function c() {
44
48
  }), /* @__PURE__ */ o("input", {
45
49
  type: "text",
46
50
  placeholder: "Enter meeting title",
47
- value: d,
48
- onChange: (e) => f(e.target.value),
51
+ value: f,
52
+ onChange: (e) => p(e.target.value),
49
53
  className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary"
50
54
  })] }),
51
55
  /* @__PURE__ */ s("div", {
@@ -55,16 +59,16 @@ function c() {
55
59
  children: "Date"
56
60
  }), /* @__PURE__ */ o("input", {
57
61
  type: "date",
58
- value: p,
59
- onChange: (e) => m(e.target.value),
62
+ value: m,
63
+ onChange: (e) => h(e.target.value),
60
64
  className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
61
65
  })] }), /* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("label", {
62
66
  className: "block text-sm font-medium text-text-primary",
63
67
  children: "Duration (minutes)"
64
68
  }), /* @__PURE__ */ o("input", {
65
69
  type: "number",
66
- value: h,
67
- onChange: (e) => g(Number(e.target.value)),
70
+ value: g,
71
+ onChange: (e) => _(Number(e.target.value)),
68
72
  className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
69
73
  })] })]
70
74
  }),
@@ -74,8 +78,8 @@ function c() {
74
78
  }), /* @__PURE__ */ o("textarea", {
75
79
  placeholder: "Meeting agenda...",
76
80
  rows: 3,
77
- value: _,
78
- onChange: (e) => v(e.target.value),
81
+ value: v,
82
+ onChange: (e) => y(e.target.value),
79
83
  className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary"
80
84
  })] }),
81
85
  /* @__PURE__ */ s("div", {
@@ -84,10 +88,10 @@ function c() {
84
88
  className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
85
89
  children: "Cancel"
86
90
  }), /* @__PURE__ */ o("button", {
87
- onClick: y,
88
- disabled: u || !d || !p,
91
+ onClick: b,
92
+ disabled: d || !f || !m,
89
93
  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",
90
- children: u ? "Scheduling..." : "Schedule"
94
+ children: d ? "Scheduling..." : "Schedule"
91
95
  })]
92
96
  })
93
97
  ]
@@ -96,6 +100,6 @@ function c() {
96
100
  });
97
101
  }
98
102
  //#endregion
99
- export { c as MeetingCreatePage };
103
+ export { l as MeetingCreatePage };
100
104
 
101
105
  //# sourceMappingURL=MeetingCreatePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MeetingCreatePage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingCreatePage.tsx"],"sourcesContent":["import { useState, useCallback } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useCreateMeetingMutation } from \"@/generated/wspace-operations\";\n\nexport function MeetingCreatePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const [createMeeting, { loading: creating }] = useCreateMeetingMutation();\n\n const [title, setTitle] = useState(\"\");\n const [date, setDate] = useState(\"\");\n const [duration, setDuration] = useState(30);\n const [description, setDescription] = useState(\"\");\n\n const handleSubmit = useCallback(async () => {\n if (!workspaceId || !title || !date) return;\n const startTime = new Date(date).toISOString();\n await createMeeting({\n variables: {\n input: {\n workspaceId,\n title,\n meetingType: \"TEAM\" as never,\n startTime,\n duration,\n notes: description || undefined,\n },\n },\n refetchQueries: [\"ListMeetings\"],\n });\n setTitle(\"\");\n setDate(\"\");\n setDuration(30);\n setDescription(\"\");\n }, [workspaceId, title, date, duration, description, createMeeting]);\n\n return (\n <PageLayout\n title=\"Schedule Meeting\"\n description=\"Create a new meeting\"\n actions={\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 <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n }\n >\n <div className=\"mx-auto max-w-2xl rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Meeting Title\n </label>\n <input\n type=\"text\"\n placeholder=\"Enter meeting title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Date\n </label>\n <input\n type=\"date\"\n value={date}\n onChange={(e) => setDate(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Duration (minutes)\n </label>\n <input\n type=\"number\"\n value={duration}\n onChange={(e) => setDuration(Number(e.target.value))}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Description\n </label>\n <textarea\n placeholder=\"Meeting agenda...\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div className=\"flex justify-end gap-2 pt-4\">\n <button className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n Cancel\n </button>\n <button\n onClick={handleSubmit}\n disabled={creating || !title || !date}\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 {creating ? \"Scheduling...\" : \"Schedule\"}\n </button>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,IAAoB;CAClC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,CAAC,GAAe,EAAE,SAAS,OAAc,GAA0B,EAEnE,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAE5C,IAAe,EAAY,YAAY;AACvC,GAAC,KAAe,CAAC,KAAS,CAAC,MAE/B,MAAM,EAAc;GAClB,WAAW,EACT,OAAO;IACL;IACA;IACA,aAAa;IACb,WAPY,IAAI,KAAK,EAAK,CAAC,aAAa;IAQxC;IACA,OAAO,KAAe,KAAA;IACvB,EACF;GACD,gBAAgB,CAAC,eAAe;GACjC,CAAC,EACF,EAAS,GAAG,EACZ,EAAQ,GAAG,EACX,EAAY,GAAG,EACf,EAAe,GAAG;IACjB;EAAC;EAAa;EAAO;EAAM;EAAU;EAAa;EAAc,CAAC;AAEpE,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,OAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,SAAD;MACE,MAAK;MACL,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;MACzC,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;OACxC,WAAU;OACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAY,OAAO,EAAE,OAAO,MAAM,CAAC;OACpD,WAAU;OACV,CAAA,CACE,EAAA,CAAA,CACF;;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,YAAD;MACE,aAAY;MACZ,MAAM;MACN,OAAO;MACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;MAC/C,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OAAQ,WAAU;iBAA+G;OAExH,CAAA,EACT,kBAAC,UAAD;OACE,SAAS;OACT,UAAU,KAAY,CAAC,KAAS,CAAC;OACjC,WAAU;iBAET,IAAW,kBAAkB;OACvB,CAAA,CACL;;KACF;;GACF,CAAA;EACK,CAAA"}
1
+ {"version":3,"file":"MeetingCreatePage.js","names":[],"sources":["../../../../src/timecampus/pages/meetings/MeetingCreatePage.tsx"],"sourcesContent":["import { useState, useCallback } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useCreateMeetingMutation } from \"@/generated/wspace-operations\";\n\nexport function MeetingCreatePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const [createMeeting, { loading: creating }] = useCreateMeetingMutation();\n\n const [title, setTitle] = useState(\"\");\n const [date, setDate] = useState(\"\");\n const [duration, setDuration] = useState(30);\n const [description, setDescription] = useState(\"\");\n\n const handleSubmit = useCallback(async () => {\n if (!workspaceId || !title || !date) return;\n const startTime = new Date(date).toISOString();\n await createMeeting({\n variables: {\n input: {\n workspaceId,\n title,\n meetingType: \"TEAM\" as never,\n startTime,\n duration,\n notes: description || undefined,\n },\n },\n refetchQueries: [\"ListMeetings\"],\n });\n setTitle(\"\");\n setDate(\"\");\n setDuration(30);\n setDescription(\"\");\n }, [workspaceId, title, date, duration, description, createMeeting]);\n\n return (\n <PageLayout\n title=\"Schedule Meeting\"\n description=\"Create a new meeting\"\n purpose=\"Book a meeting with its time and agenda so it's tracked alongside your work — letting TimeCampus account for the hours it consumes and surface its cost and action items afterwards.\"\n actions={\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 <ArrowLeft className=\"h-4 w-4\" />\n Back\n </button>\n }\n >\n <GlassCard treatment=\"glass\" glow className=\"mx-auto max-w-2xl p-6\">\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Meeting Title\n </label>\n <input\n type=\"text\"\n placeholder=\"Enter meeting title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Date\n </label>\n <input\n type=\"date\"\n value={date}\n onChange={(e) => setDate(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Duration (minutes)\n </label>\n <input\n type=\"number\"\n value={duration}\n onChange={(e) => setDuration(Number(e.target.value))}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Description\n </label>\n <textarea\n placeholder=\"Meeting agenda...\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div className=\"flex justify-end gap-2 pt-4\">\n <button className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n Cancel\n </button>\n <button\n onClick={handleSubmit}\n disabled={creating || !title || !date}\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 {creating ? \"Scheduling...\" : \"Schedule\"}\n </button>\n </div>\n </div>\n </GlassCard>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,IAAoB;CAClC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,CAAC,GAAe,EAAE,SAAS,OAAc,GAA0B,EAEnE,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAE5C,IAAe,EAAY,YAAY;AACvC,GAAC,KAAe,CAAC,KAAS,CAAC,MAE/B,MAAM,EAAc;GAClB,WAAW,EACT,OAAO;IACL;IACA;IACA,aAAa;IACb,WAPY,IAAI,KAAK,EAAK,CAAC,aAAa;IAQxC;IACA,OAAO,KAAe,KAAA;IACvB,EACF;GACD,gBAAgB,CAAC,eAAe;GACjC,CAAC,EACF,EAAS,GAAG,EACZ,EAAQ,GAAG,EACX,EAAY,GAAG,EACf,EAAe,GAAG;IACjB;EAAC;EAAa;EAAO;EAAM;EAAU;EAAa;EAAc,CAAC;AAEpE,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SAAQ;EACR,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,OAE1B;;YAGX,kBAAC,GAAD;GAAW,WAAU;GAAQ,MAAA;GAAK,WAAU;aAC1C,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,SAAD;MACE,MAAK;MACL,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;MACzC,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;OACxC,WAAU;OACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,OAAO;OACP,WAAW,MAAM,EAAY,OAAO,EAAE,OAAO,MAAM,CAAC;OACpD,WAAU;OACV,CAAA,CACE,EAAA,CAAA,CACF;;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,YAAD;MACE,aAAY;MACZ,MAAM;MACN,OAAO;MACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;MAC/C,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OAAQ,WAAU;iBAA+G;OAExH,CAAA,EACT,kBAAC,UAAD;OACE,SAAS;OACT,UAAU,KAAY,CAAC,KAAS,CAAC;OACjC,WAAU;iBAET,IAAW,kBAAkB;OACvB,CAAA,CACL;;KACF;;GACI,CAAA;EACD,CAAA"}