@burdenoff/microfe-timecampus 2026.801.1 → 2026.820.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.
- package/dist/generated/wspace-operations.d.ts +484 -861
- package/dist/generated/wspace-operations.d.ts.map +1 -1
- package/dist/generated/wspace-operations.js +1377 -1377
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.js.map +1 -1
- package/dist/index.js +5 -3
- package/dist/services/createSandboxAssistantTransport.js.map +1 -1
- package/dist/stories/EmptyState.stories.d.ts +0 -1
- package/dist/stories/LoadingSkeleton.stories.d.ts +0 -1
- package/dist/stories/StatCard.stories.d.ts +0 -1
- package/dist/stories/StatusBadge.stories.d.ts +0 -1
- package/dist/timecampus/AdminRoot.d.ts +8 -0
- package/dist/timecampus/AdminRoot.d.ts.map +1 -0
- package/dist/timecampus/AdminRoot.js +12 -0
- package/dist/timecampus/AdminRoot.js.map +1 -0
- package/dist/timecampus/AdminRoutes.d.ts +3 -0
- package/dist/timecampus/AdminRoutes.d.ts.map +1 -0
- package/dist/timecampus/AdminRoutes.js +8 -0
- package/dist/timecampus/AdminRoutes.js.map +1 -0
- package/dist/timecampus/TimeCampusRoot.d.ts +0 -1
- package/dist/timecampus/TimeCampusRoot.js +4 -2
- package/dist/timecampus/TimeCampusRoot.js.map +1 -1
- package/dist/timecampus/TimeCampusRoutes.js.map +1 -1
- package/dist/timecampus/components/ChartCard.d.ts +0 -1
- package/dist/timecampus/components/ChartCard.js.map +1 -1
- package/dist/timecampus/components/DataTable.d.ts +0 -1
- package/dist/timecampus/components/EmptyState.d.ts +0 -1
- package/dist/timecampus/components/EmptyState.js.map +1 -1
- package/dist/timecampus/components/ErrorBoundary.d.ts +0 -1
- package/dist/timecampus/components/ErrorBoundary.js.map +1 -1
- package/dist/timecampus/components/FilterBar.d.ts +0 -1
- package/dist/timecampus/components/LoadingSkeleton.d.ts +0 -1
- package/dist/timecampus/components/LoadingSkeleton.js.map +1 -1
- package/dist/timecampus/components/Modal.d.ts +0 -1
- package/dist/timecampus/components/Modal.js +5 -3
- package/dist/timecampus/components/Modal.js.map +1 -1
- package/dist/timecampus/components/PageLayout.d.ts +0 -1
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/components/StatCard.d.ts +0 -1
- package/dist/timecampus/components/StatCard.js.map +1 -1
- package/dist/timecampus/components/StatusBadge.d.ts +0 -1
- package/dist/timecampus/components/StatusBadge.js.map +1 -1
- package/dist/timecampus/components/Toast.d.ts +0 -1
- package/dist/timecampus/components/Toast.js.map +1 -1
- package/dist/timecampus/components/charts/BalanceWheel.js.map +1 -1
- package/dist/timecampus/components/charts/BarsChart.d.ts +0 -1
- package/dist/timecampus/components/charts/BarsChart.js.map +1 -1
- package/dist/timecampus/components/charts/ChartParts.d.ts +0 -1
- package/dist/timecampus/components/charts/ChartParts.js.map +1 -1
- package/dist/timecampus/components/charts/DonutChart.d.ts +0 -1
- package/dist/timecampus/components/charts/DonutChart.js.map +1 -1
- package/dist/timecampus/components/charts/Heatmap.d.ts +0 -1
- package/dist/timecampus/components/charts/Heatmap.js +29 -29
- package/dist/timecampus/components/charts/Heatmap.js.map +1 -1
- package/dist/timecampus/components/charts/ProgressMeter.d.ts +0 -1
- package/dist/timecampus/components/charts/ProgressMeter.js +2 -2
- package/dist/timecampus/components/charts/ProgressMeter.js.map +1 -1
- package/dist/timecampus/components/charts/RadialGauge.d.ts +0 -1
- package/dist/timecampus/components/charts/RadialGauge.js +2 -2
- package/dist/timecampus/components/charts/RadialGauge.js.map +1 -1
- package/dist/timecampus/components/charts/TrendChart.d.ts +0 -1
- package/dist/timecampus/components/charts/TrendChart.js.map +1 -1
- package/dist/timecampus/components/charts/WeeksGrid.js +2 -2
- package/dist/timecampus/components/charts/WeeksGrid.js.map +1 -1
- package/dist/timecampus/components/charts/chartTheme.js.map +1 -1
- package/dist/timecampus/components/charts/index.js +10 -9
- package/dist/timecampus/components/index.js +18 -17
- package/dist/timecampus/index.d.ts +3 -1
- package/dist/timecampus/index.d.ts.map +1 -1
- package/dist/timecampus/index.js +8 -5
- package/dist/timecampus/pages/HomePage.d.ts +0 -1
- package/dist/timecampus/pages/HomePage.js.map +1 -1
- package/dist/timecampus/pages/admin/AdminPage.d.ts +3 -0
- package/dist/timecampus/pages/admin/AdminPage.d.ts.map +1 -0
- package/dist/timecampus/pages/admin/AdminPage.js +235 -0
- package/dist/timecampus/pages/admin/AdminPage.js.map +1 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.d.ts.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.d.ts.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.d.ts.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.d.ts.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.d.ts.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/invoicing/InvoicingPage.d.ts.map +1 -1
- package/dist/timecampus/pages/invoicing/InvoicingPage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/DeadTimeRadarPage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/FiniteLifePage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/LifeBalancePage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/LifeTimelinePage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/PersonalCorporatePage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/RecommendationsPage.js +1 -1
- package/dist/timecampus/pages/lifetime/RecommendationsPage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/TimeWellSpentPage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/ValuesGoalsPage.js +9 -6
- package/dist/timecampus/pages/lifetime/ValuesGoalsPage.js.map +1 -1
- package/dist/timecampus/pages/lifetime/domains.d.ts +0 -1
- package/dist/timecampus/pages/lifetime/domains.js +1 -1
- package/dist/timecampus/pages/lifetime/domains.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.d.ts.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/ActionItemFormModal.d.ts +0 -1
- package/dist/timecampus/pages/meetings/ActionItemFormModal.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingFormModal.d.ts +0 -1
- package/dist/timecampus/pages/meetings/MeetingFormModal.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/ParticipantFormModal.d.ts +0 -1
- package/dist/timecampus/pages/meetings/ParticipantFormModal.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.d.ts.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.d.ts.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +4 -4
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.d.ts.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/timeline/TimelinePage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/providers/TimeCampusProvider.d.ts +0 -1
- package/dist/timecampus/providers/TimeCampusProvider.d.ts.map +1 -1
- package/dist/timecampus/providers/TimeCampusProvider.js +38 -35
- package/dist/timecampus/providers/TimeCampusProvider.js.map +1 -1
- package/dist/timecampus/store/timecampusStore.js.map +1 -1
- package/dist/timecampus/types/index.d.ts +4 -1
- package/dist/timecampus/types/index.d.ts.map +1 -1
- package/dist/timecampus/utils/helpers.d.ts +0 -1
- package/dist/timecampus/utils/helpers.js.map +1 -1
- package/dist/types/assistant.d.ts +0 -1
- package/dist/utils/pageContext.js +1 -1
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +60 -57
|
@@ -11,7 +11,7 @@ function o({ value: o, max: s = 100, label: c, thresholds: l = {
|
|
|
11
11
|
warning: .75,
|
|
12
12
|
danger: .9
|
|
13
13
|
}, higherIsWorse: u = !0, tone: d, showValue: f = !0, format: p = a, size: m = "md", className: h }) {
|
|
14
|
-
let g = Math.min(1, Math.max(0, o / (s > 0 ? s : 1))), _ = Math.round(g * 100), v =
|
|
14
|
+
let g = Math.min(1, Math.max(0, o / (s > 0 ? s : 1))), _ = Math.round(g * 100), v = d ?? (u ? g >= l.danger ? "danger" : g >= l.warning ? "warning" : "success" : g >= l.warning ? "success" : g >= l.danger ? "warning" : "danger"), y = t(v);
|
|
15
15
|
return /* @__PURE__ */ r("div", {
|
|
16
16
|
className: e("w-full", h),
|
|
17
17
|
children: [c !== void 0 || f ? /* @__PURE__ */ r("div", {
|
|
@@ -37,7 +37,7 @@ function o({ value: o, max: s = 100, label: c, thresholds: l = {
|
|
|
37
37
|
className: "h-full rounded-full motion-safe:transition-[width] motion-safe:duration-500",
|
|
38
38
|
style: {
|
|
39
39
|
width: `${_}%`,
|
|
40
|
-
backgroundColor:
|
|
40
|
+
backgroundColor: y
|
|
41
41
|
}
|
|
42
42
|
})
|
|
43
43
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressMeter.js","names":[],"sources":["../../../../src/timecampus/components/charts/ProgressMeter.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/helpers\";\nimport { toneColor, type MeterTone, type ValueFormatter } from \"./chartTheme\";\n\nexport interface ProgressMeterProps {\n /** Current value. */\n value: number;\n /** Full-scale value. Default 100. */\n max?: number;\n /** Leading caption (e.g. \"Seats used\", \"Budget spent\"). */\n label?: ReactNode;\n /**\n * Severity thresholds as fractions of `max` (0–1). With the default\n * `higherIsWorse` a fraction ≥ `danger` turns the fill red, ≥ `warning` amber.\n * Default `{ warning: 0.75, danger: 0.9 }`.\n */\n thresholds?: { warning: number; danger: number };\n /** Whether a fuller meter is worse (usage/budget, default) or better (progress). */\n higherIsWorse?: boolean;\n /** Force a tone, bypassing thresholds. */\n tone?: MeterTone;\n /** Show the `value / max` readout on the right of the label row. Default true. */\n showValue?: boolean;\n /** Formats the value + max readout. Default grouped integer. */\n format?: ValueFormatter;\n /** Bar thickness. Default `md`. */\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst TRACK_HEIGHT: Record<NonNullable<ProgressMeterProps[\"size\"]>, string> = {\n sm: \"h-1.5\",\n md: \"h-2.5\",\n lg: \"h-3.5\",\n};\n\nconst defaultFormat: ValueFormatter = (value) => value.toLocaleString();\n\n/**\n * ProgressMeter — a linear meter for a single ratio (seat usage, budget spent,\n * progress to target). The fill carries severity (good → warning → danger) via\n * reserved status tokens over a muted track; the width transition is gated\n * behind `motion-safe` so reduced-motion users get an instant fill. Token-only,\n * no raw colour.\n */\nexport function ProgressMeter({\n value,\n max = 100,\n label,\n thresholds = { warning: 0.75, danger: 0.9 },\n higherIsWorse = true,\n tone,\n showValue = true,\n format = defaultFormat,\n size = \"md\",\n className,\n}: ProgressMeterProps) {\n const safeMax = max > 0 ? max : 1;\n const fraction = Math.min(1, Math.max(0, value / safeMax));\n const pct = Math.round(fraction * 100);\n\n const resolvedTone: MeterTone =\n tone ??\n (higherIsWorse\n ? fraction >= thresholds.danger\n ? \"danger\"\n : fraction >= thresholds.warning\n ? \"warning\"\n : \"success\"\n : fraction >= thresholds.warning\n ? \"success\"\n : fraction >= thresholds.danger\n ? \"warning\"\n : \"danger\");\n\n const fillColor = toneColor(resolvedTone);\n\n return (\n <div className={cn(\"w-full\", className)}>\n {label !== undefined || showValue ? (\n <div className=\"mb-1.5 flex items-center justify-between gap-3 text-sm\">\n {label !== undefined ? (\n <span className=\"min-w-0 truncate font-medium text-text-primary\">\n {label}\n </span>\n ) : (\n <span />\n )}\n {showValue ? (\n <span className=\"shrink-0 tabular-nums text-text-secondary\">\n {format(value)}\n <span className=\"text-text-muted\"> / {format(max)}</span>\n </span>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"w-full overflow-hidden rounded-full bg-bg-sunken\",\n TRACK_HEIGHT[size],\n )}\n role=\"progressbar\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={typeof label === \"string\" ? label : undefined}\n >\n <div\n className=\"h-full rounded-full motion-safe:transition-[width] motion-safe:duration-500\"\n style={{ width: `${pct}%`, backgroundColor: fillColor }}\n />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;AA8BA,IAAM,IAAwE;CAC5E,IAAI;CACJ,IAAI;CACJ,IAAI;
|
|
1
|
+
{"version":3,"file":"ProgressMeter.js","names":[],"sources":["../../../../src/timecampus/components/charts/ProgressMeter.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/helpers\";\nimport { toneColor, type MeterTone, type ValueFormatter } from \"./chartTheme\";\n\nexport interface ProgressMeterProps {\n /** Current value. */\n value: number;\n /** Full-scale value. Default 100. */\n max?: number;\n /** Leading caption (e.g. \"Seats used\", \"Budget spent\"). */\n label?: ReactNode;\n /**\n * Severity thresholds as fractions of `max` (0–1). With the default\n * `higherIsWorse` a fraction ≥ `danger` turns the fill red, ≥ `warning` amber.\n * Default `{ warning: 0.75, danger: 0.9 }`.\n */\n thresholds?: { warning: number; danger: number };\n /** Whether a fuller meter is worse (usage/budget, default) or better (progress). */\n higherIsWorse?: boolean;\n /** Force a tone, bypassing thresholds. */\n tone?: MeterTone;\n /** Show the `value / max` readout on the right of the label row. Default true. */\n showValue?: boolean;\n /** Formats the value + max readout. Default grouped integer. */\n format?: ValueFormatter;\n /** Bar thickness. Default `md`. */\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n}\n\nconst TRACK_HEIGHT: Record<NonNullable<ProgressMeterProps[\"size\"]>, string> = {\n sm: \"h-1.5\",\n md: \"h-2.5\",\n lg: \"h-3.5\",\n};\n\nconst defaultFormat: ValueFormatter = (value) => value.toLocaleString();\n\n/**\n * ProgressMeter — a linear meter for a single ratio (seat usage, budget spent,\n * progress to target). The fill carries severity (good → warning → danger) via\n * reserved status tokens over a muted track; the width transition is gated\n * behind `motion-safe` so reduced-motion users get an instant fill. Token-only,\n * no raw colour.\n */\nexport function ProgressMeter({\n value,\n max = 100,\n label,\n thresholds = { warning: 0.75, danger: 0.9 },\n higherIsWorse = true,\n tone,\n showValue = true,\n format = defaultFormat,\n size = \"md\",\n className,\n}: ProgressMeterProps) {\n const safeMax = max > 0 ? max : 1;\n const fraction = Math.min(1, Math.max(0, value / safeMax));\n const pct = Math.round(fraction * 100);\n\n const resolvedTone: MeterTone =\n tone ??\n (higherIsWorse\n ? fraction >= thresholds.danger\n ? \"danger\"\n : fraction >= thresholds.warning\n ? \"warning\"\n : \"success\"\n : fraction >= thresholds.warning\n ? \"success\"\n : fraction >= thresholds.danger\n ? \"warning\"\n : \"danger\");\n\n const fillColor = toneColor(resolvedTone);\n\n return (\n <div className={cn(\"w-full\", className)}>\n {label !== undefined || showValue ? (\n <div className=\"mb-1.5 flex items-center justify-between gap-3 text-sm\">\n {label !== undefined ? (\n <span className=\"min-w-0 truncate font-medium text-text-primary\">\n {label}\n </span>\n ) : (\n <span />\n )}\n {showValue ? (\n <span className=\"shrink-0 tabular-nums text-text-secondary\">\n {format(value)}\n <span className=\"text-text-muted\"> / {format(max)}</span>\n </span>\n ) : null}\n </div>\n ) : null}\n\n <div\n className={cn(\n \"w-full overflow-hidden rounded-full bg-bg-sunken\",\n TRACK_HEIGHT[size],\n )}\n role=\"progressbar\"\n aria-valuenow={value}\n aria-valuemin={0}\n aria-valuemax={max}\n aria-label={typeof label === \"string\" ? label : undefined}\n >\n <div\n className=\"h-full rounded-full motion-safe:transition-[width] motion-safe:duration-500\"\n style={{ width: `${pct}%`, backgroundColor: fillColor }}\n />\n </div>\n </div>\n );\n}\n"],"mappings":";;;;AA8BA,IAAM,IAAwE;CAC5E,IAAI;CACJ,IAAI;CACJ,IAAI;AACN,GAEM,KAAiC,MAAU,EAAM,eAAe;AAStE,SAAgB,EAAc,EAC5B,UACA,SAAM,KACN,UACA,gBAAa;CAAE,SAAS;CAAM,QAAQ;AAAI,GAC1C,mBAAgB,IAChB,SACA,eAAY,IACZ,YAAS,GACT,UAAO,MACP,gBACqB;CAErB,IAAM,IAAW,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KADzB,IAAM,IAAI,IAAM,EACwB,CAAC,GACnD,IAAM,KAAK,MAAM,IAAW,GAAG,GAE/B,IACJ,MACC,IACG,KAAY,EAAW,SACrB,WACA,KAAY,EAAW,UACrB,YACA,YACJ,KAAY,EAAW,UACrB,YACA,KAAY,EAAW,SACrB,YACA,WAEJ,IAAY,EAAU,CAAY;CAExC,OACE,kBAAC,OAAD;EAAK,WAAW,EAAG,UAAU,CAAS;EAAtC,UAAA,CACG,MAAU,KAAA,KAAa,IACtB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACG,MAAU,KAAA,IAKT,kBAAC,QAAD,CAAO,CAAA,IAJP,kBAAC,QAAD;IAAM,WAAU;IACb,UAAA;GACG,CAAA,GAIP,IACC,kBAAC,QAAD;IAAM,WAAU;IAAhB,UAAA,CACG,EAAO,CAAK,GACb,kBAAC,QAAD;KAAM,WAAU;KAAhB,UAAA,CAAkC,OAAI,EAAO,CAAG,CAAQ;IACpD,CAAA,CAAA;GACJ,CAAA,IAAA,IACD;EACH,CAAA,IAAA,MAEJ,kBAAC,OAAD;GACE,WAAW,EACT,oDACA,EAAa,EACf;GACA,MAAK;GACL,iBAAe;GACf,iBAAe;GACf,iBAAe;GACf,cAAY,OAAO,KAAU,WAAW,IAAQ,KAAA;GAEhD,UAAA,kBAAC,OAAD;IACE,WAAU;IACV,OAAO;KAAE,OAAO,GAAG,EAAI;KAAI,iBAAiB;IAAU;GACvD,CAAA;EACE,CAAA,CACF;;AAET"}
|
|
@@ -8,10 +8,10 @@ function d({ value: d, min: f = 0, max: p = 100, label: m, sublabel: h, threshol
|
|
|
8
8
|
let w = r(), T = p - f || 1, E = u(d, f, p), D = g?.warning ?? (_ ? f + T * .8 : f + T * .5), O = g?.danger ?? (_ ? f + T * .5 : f + T * .8), k = y ?? n(v ?? (_ ? d >= D ? "success" : d >= O ? "warning" : "danger" : d <= D ? "success" : d <= O ? "warning" : "danger")), A = [{
|
|
9
9
|
name: m ?? "value",
|
|
10
10
|
value: E
|
|
11
|
-
}]
|
|
11
|
+
}], j = S ?? `${m ? `${m}: ` : ""}${x(d)}`;
|
|
12
12
|
return /* @__PURE__ */ a("figure", {
|
|
13
13
|
role: "img",
|
|
14
|
-
"aria-label":
|
|
14
|
+
"aria-label": j,
|
|
15
15
|
className: e("relative w-full", C),
|
|
16
16
|
style: { height: b },
|
|
17
17
|
children: [/* @__PURE__ */ i(l, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadialGauge.js","names":[],"sources":["../../../../src/timecampus/components/charts/RadialGauge.tsx"],"sourcesContent":["import {\n PolarAngleAxis,\n RadialBar,\n RadialBarChart,\n ResponsiveContainer,\n} from \"recharts\";\nimport { cn } from \"../../utils/helpers\";\nimport {\n chartTokens,\n toneColor,\n usePrefersReducedMotion,\n type MeterTone,\n type ValueFormatter,\n} from \"./chartTheme\";\n\nexport interface RadialGaugeProps {\n /** The measured value. */\n value: number;\n /** Scale minimum. Default 0. */\n min?: number;\n /** Scale maximum. Default 100. */\n max?: number;\n /** Big centre caption (e.g. \"Compliance\"). */\n label?: string;\n /** Small caption under the value. */\n sublabel?: string;\n /**\n * Severity thresholds in value units. With `higherIsBetter` (default) pass\n * `warning > danger` (e.g. `{ warning: 80, danger: 50 }` → ≥80 good, 50–79\n * warning, <50 danger). Defaults derive from the range.\n */\n thresholds?: { warning: number; danger: number };\n /** Whether a higher value is better (compliance/health) or worse (risk). Default true. */\n higherIsBetter?: boolean;\n /** Force a tone, bypassing threshold logic. */\n tone?: MeterTone;\n /** Force an explicit colour, bypassing tone + thresholds. */\n color?: string;\n /** Pixel height. Default 200. */\n height?: number;\n /** Formats the centre value. Default rounds to an integer. */\n format?: ValueFormatter;\n /** Accessible name. Default derived from label + value. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, value));\n\n/**\n * RadialGauge — a single value on a 270° arc (compliance score, asset health,\n * risk). The arc colour follows severity thresholds (good → warning → danger)\n * using reserved status tokens, over a muted track. Center shows the value and\n * label; respects `prefers-reduced-motion`.\n */\nexport function RadialGauge({\n value,\n min = 0,\n max = 100,\n label,\n sublabel,\n thresholds,\n higherIsBetter = true,\n tone,\n color,\n height = 200,\n format = (v) => Math.round(v).toString(),\n ariaLabel,\n className,\n}: RadialGaugeProps) {\n const reducedMotion = usePrefersReducedMotion();\n const range = max - min || 1;\n const clamped = clamp(value, min, max);\n\n const warning =\n thresholds?.warning ??\n (higherIsBetter ? min + range * 0.8 : min + range * 0.5);\n const danger =\n thresholds?.danger ??\n (higherIsBetter ? min + range * 0.5 : min + range * 0.8);\n\n const resolvedTone: MeterTone =\n tone ??\n (higherIsBetter\n ? value >= warning\n ? \"success\"\n : value >= danger\n ? \"warning\"\n : \"danger\"\n : value <= warning\n ? \"success\"\n : value <= danger\n ? \"warning\"\n : \"danger\");\n\n const arcColor = color ?? toneColor(resolvedTone);\n const data = [{ name: label ?? \"value\", value: clamped }];\n const accessibleName =\n ariaLabel ?? `${label ? `${label}: ` : \"\"}${format(value)}`;\n\n return (\n <figure\n role=\"img\"\n aria-label={accessibleName}\n className={cn(\"relative w-full\", className)}\n style={{ height }}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RadialBarChart\n data={data}\n innerRadius=\"72%\"\n outerRadius=\"100%\"\n barSize={14}\n startAngle={225}\n endAngle={-45}\n >\n <PolarAngleAxis\n type=\"number\"\n domain={[min, max]}\n angleAxisId={0}\n tick={false}\n />\n <RadialBar\n dataKey=\"value\"\n angleAxisId={0}\n background={{ fill: chartTokens.track }}\n cornerRadius={999}\n fill={arcColor}\n isAnimationActive={!reducedMotion}\n />\n </RadialBarChart>\n </ResponsiveContainer>\n\n <div className=\"pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-center\">\n <span className=\"text-3xl font-bold leading-none text-text-primary\">\n {format(value)}\n </span>\n {label ? (\n <span className=\"mt-1 text-sm font-medium text-text-secondary\">\n {label}\n </span>\n ) : null}\n {sublabel ? (\n <span className=\"text-xs text-text-muted\">{sublabel}</span>\n ) : null}\n </div>\n </figure>\n );\n}\n"],"mappings":";;;;;AA+CA,IAAM,KAAS,GAAe,GAAa,MACzC,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,
|
|
1
|
+
{"version":3,"file":"RadialGauge.js","names":[],"sources":["../../../../src/timecampus/components/charts/RadialGauge.tsx"],"sourcesContent":["import {\n PolarAngleAxis,\n RadialBar,\n RadialBarChart,\n ResponsiveContainer,\n} from \"recharts\";\nimport { cn } from \"../../utils/helpers\";\nimport {\n chartTokens,\n toneColor,\n usePrefersReducedMotion,\n type MeterTone,\n type ValueFormatter,\n} from \"./chartTheme\";\n\nexport interface RadialGaugeProps {\n /** The measured value. */\n value: number;\n /** Scale minimum. Default 0. */\n min?: number;\n /** Scale maximum. Default 100. */\n max?: number;\n /** Big centre caption (e.g. \"Compliance\"). */\n label?: string;\n /** Small caption under the value. */\n sublabel?: string;\n /**\n * Severity thresholds in value units. With `higherIsBetter` (default) pass\n * `warning > danger` (e.g. `{ warning: 80, danger: 50 }` → ≥80 good, 50–79\n * warning, <50 danger). Defaults derive from the range.\n */\n thresholds?: { warning: number; danger: number };\n /** Whether a higher value is better (compliance/health) or worse (risk). Default true. */\n higherIsBetter?: boolean;\n /** Force a tone, bypassing threshold logic. */\n tone?: MeterTone;\n /** Force an explicit colour, bypassing tone + thresholds. */\n color?: string;\n /** Pixel height. Default 200. */\n height?: number;\n /** Formats the centre value. Default rounds to an integer. */\n format?: ValueFormatter;\n /** Accessible name. Default derived from label + value. */\n ariaLabel?: string;\n className?: string;\n}\n\nconst clamp = (value: number, min: number, max: number): number =>\n Math.min(max, Math.max(min, value));\n\n/**\n * RadialGauge — a single value on a 270° arc (compliance score, asset health,\n * risk). The arc colour follows severity thresholds (good → warning → danger)\n * using reserved status tokens, over a muted track. Center shows the value and\n * label; respects `prefers-reduced-motion`.\n */\nexport function RadialGauge({\n value,\n min = 0,\n max = 100,\n label,\n sublabel,\n thresholds,\n higherIsBetter = true,\n tone,\n color,\n height = 200,\n format = (v) => Math.round(v).toString(),\n ariaLabel,\n className,\n}: RadialGaugeProps) {\n const reducedMotion = usePrefersReducedMotion();\n const range = max - min || 1;\n const clamped = clamp(value, min, max);\n\n const warning =\n thresholds?.warning ??\n (higherIsBetter ? min + range * 0.8 : min + range * 0.5);\n const danger =\n thresholds?.danger ??\n (higherIsBetter ? min + range * 0.5 : min + range * 0.8);\n\n const resolvedTone: MeterTone =\n tone ??\n (higherIsBetter\n ? value >= warning\n ? \"success\"\n : value >= danger\n ? \"warning\"\n : \"danger\"\n : value <= warning\n ? \"success\"\n : value <= danger\n ? \"warning\"\n : \"danger\");\n\n const arcColor = color ?? toneColor(resolvedTone);\n const data = [{ name: label ?? \"value\", value: clamped }];\n const accessibleName =\n ariaLabel ?? `${label ? `${label}: ` : \"\"}${format(value)}`;\n\n return (\n <figure\n role=\"img\"\n aria-label={accessibleName}\n className={cn(\"relative w-full\", className)}\n style={{ height }}\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <RadialBarChart\n data={data}\n innerRadius=\"72%\"\n outerRadius=\"100%\"\n barSize={14}\n startAngle={225}\n endAngle={-45}\n >\n <PolarAngleAxis\n type=\"number\"\n domain={[min, max]}\n angleAxisId={0}\n tick={false}\n />\n <RadialBar\n dataKey=\"value\"\n angleAxisId={0}\n background={{ fill: chartTokens.track }}\n cornerRadius={999}\n fill={arcColor}\n isAnimationActive={!reducedMotion}\n />\n </RadialBarChart>\n </ResponsiveContainer>\n\n <div className=\"pointer-events-none absolute inset-0 flex flex-col items-center justify-center text-center\">\n <span className=\"text-3xl font-bold leading-none text-text-primary\">\n {format(value)}\n </span>\n {label ? (\n <span className=\"mt-1 text-sm font-medium text-text-secondary\">\n {label}\n </span>\n ) : null}\n {sublabel ? (\n <span className=\"text-xs text-text-muted\">{sublabel}</span>\n ) : null}\n </div>\n </figure>\n );\n}\n"],"mappings":";;;;;AA+CA,IAAM,KAAS,GAAe,GAAa,MACzC,KAAK,IAAI,GAAK,KAAK,IAAI,GAAK,CAAK,CAAC;AAQpC,SAAgB,EAAY,EAC1B,UACA,SAAM,GACN,SAAM,KACN,UACA,aACA,eACA,oBAAiB,IACjB,SACA,UACA,YAAS,KACT,aAAU,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,GACvC,cACA,gBACmB;CACnB,IAAM,IAAgB,EAAwB,GACxC,IAAQ,IAAM,KAAO,GACrB,IAAU,EAAM,GAAO,GAAK,CAAG,GAE/B,IACJ,GAAY,YACX,IAAiB,IAAM,IAAQ,KAAM,IAAM,IAAQ,KAChD,IACJ,GAAY,WACX,IAAiB,IAAM,IAAQ,KAAM,IAAM,IAAQ,KAgBhD,IAAW,KAAS,EAbxB,MACC,IACG,KAAS,IACP,YACA,KAAS,IACP,YACA,WACJ,KAAS,IACP,YACA,KAAS,IACP,YACA,SAEsC,GAC1C,IAAO,CAAC;EAAE,MAAM,KAAS;EAAS,OAAO;CAAQ,CAAC,GAClD,IACJ,KAAa,GAAG,IAAQ,GAAG,EAAM,MAAM,KAAK,EAAO,CAAK;CAE1D,OACE,kBAAC,UAAD;EACE,MAAK;EACL,cAAY;EACZ,WAAW,EAAG,mBAAmB,CAAS;EAC1C,OAAO,EAAE,UAAO;EAJlB,UAAA,CAME,kBAAC,GAAD;GAAqB,OAAM;GAAO,QAAO;GACvC,UAAA,kBAAC,GAAD;IACQ;IACN,aAAY;IACZ,aAAY;IACZ,SAAS;IACT,YAAY;IACZ,UAAU;IANZ,UAAA,CAQE,kBAAC,GAAD;KACE,MAAK;KACL,QAAQ,CAAC,GAAK,CAAG;KACjB,aAAa;KACb,MAAM;IACP,CAAA,GACD,kBAAC,GAAD;KACE,SAAQ;KACR,aAAa;KACb,YAAY,EAAE,MAAM,EAAY,MAAM;KACtC,cAAc;KACd,MAAM;KACN,mBAAmB,CAAC;IACrB,CAAA,CACa;;EACG,CAAA,GAErB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,kBAAC,QAAD;KAAM,WAAU;KACb,UAAA,EAAO,CAAK;IACT,CAAA;IACL,IACC,kBAAC,QAAD;KAAM,WAAU;KACb,UAAA;IACG,CAAA,IACJ;IACH,IACC,kBAAC,QAAD;KAAM,WAAU;KAA2B,UAAA;IAAe,CAAA,IACxD;GACD;EACC,CAAA,CAAA;;AAEZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TrendChart.js","names":[],"sources":["../../../../src/timecampus/components/charts/TrendChart.tsx"],"sourcesContent":["import { useId } from \"react\";\nimport {\n Area,\n AreaChart,\n CartesianGrid,\n Legend,\n Line,\n LineChart,\n ReferenceDot,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport {\n chartTokens,\n defaultSeriesColor,\n formatNumber,\n usePrefersReducedMotion,\n type ChartDatum,\n type ChartSeries,\n type ValueFormatter,\n} from \"./chartTheme\";\nimport {\n ChartDataTable,\n ChartEmpty,\n ChartFigure,\n ChartLegend,\n ChartTooltip,\n} from \"./ChartParts\";\n\nexport interface TrendChartProps {\n /** Rows of `{ [xKey]: label, [series.key]: number }`. */\n data: ChartDatum[];\n /** Field holding the x-axis category/time value. */\n xKey: string;\n /** One or more numeric series. Single series reads on-brand. */\n series: ChartSeries[];\n /** Line, or gradient-filled area. Default `area`. */\n type?: \"line\" | \"area\";\n /** Pixel height of the plot. Default 260. */\n height?: number;\n /** Formats y values in the axis and tooltip. Default grouped integer. */\n valueFormat?: ValueFormatter;\n /** Formats x tick + tooltip header. */\n xTickFormat?: (value: string | number) => string;\n /** Show the horizontal grid. Default true. */\n showGrid?: boolean;\n /** Force the legend on/off. Default: on when there are ≥ 2 series. */\n showLegend?: boolean;\n /** Emphasise each series' final point with a ringed dot. Default true. */\n showEndDots?: boolean;\n /** Message shown when `data` is empty — never fabricate a shape. */\n emptyLabel?: string;\n /** Accessible name for the figure. Default derived from the series labels. */\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * TrendChart — value-over-time as a line or gradient area (asset value,\n * emissions, depreciation). Theme-aware tokens, a hairline grid, a crosshair\n * tooltip, emphasised endpoints, a legend for multi-series, an empty state and\n * a screen-reader data table. Respects `prefers-reduced-motion`.\n */\nexport function TrendChart({\n data,\n xKey,\n series,\n type = \"area\",\n height = 260,\n valueFormat = formatNumber,\n xTickFormat,\n showGrid = true,\n showLegend,\n showEndDots = true,\n emptyLabel,\n ariaLabel,\n className,\n}: TrendChartProps) {\n const gradientBase = useId();\n const reducedMotion = usePrefersReducedMotion();\n\n const resolved = series.map((s, index) => ({\n ...s,\n label: s.label ?? s.key,\n color: s.color ?? defaultSeriesColor(index, series.length),\n }));\n const label =\n ariaLabel ?? `Trend of ${resolved.map((s) => s.label).join(\", \")}`;\n\n if (data.length === 0) {\n return (\n <ChartEmpty height={height} label={emptyLabel} className={className} />\n );\n }\n\n const withLegend = showLegend ?? resolved.length > 1;\n const axisTick = { fill: chartTokens.textMuted, fontSize: 12 };\n\n const lastFiniteIndex = (key: string): number => {\n for (let i = data.length - 1; i >= 0; i -= 1) {\n const value = data[i][key];\n if (typeof value === \"number\" && Number.isFinite(value)) return i;\n }\n return -1;\n };\n\n const Chart = type === \"area\" ? AreaChart : LineChart;\n\n return (\n <ChartFigure\n ariaLabel={label}\n height={height}\n className={className}\n a11y={\n <ChartDataTable\n caption={label}\n xLabel={xKey}\n xKey={xKey}\n data={data}\n series={resolved}\n valueFormat={valueFormat}\n />\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Chart data={data} margin={{ top: 12, right: 16, bottom: 4, left: 4 }}>\n <defs>\n {resolved.map((s, index) => (\n <linearGradient\n key={s.key}\n id={`${gradientBase}-${index}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop offset=\"0%\" stopColor={s.color} stopOpacity={0.24} />\n <stop offset=\"95%\" stopColor={s.color} stopOpacity={0.02} />\n </linearGradient>\n ))}\n </defs>\n\n {showGrid ? (\n <CartesianGrid\n vertical={false}\n stroke={chartTokens.grid}\n strokeWidth={1}\n />\n ) : null}\n\n <XAxis\n dataKey={xKey}\n tickLine={false}\n axisLine={false}\n tick={axisTick}\n tickMargin={8}\n minTickGap={16}\n tickFormatter={\n xTickFormat\n ? (value) => xTickFormat(value as string | number)\n : undefined\n }\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={axisTick}\n width={48}\n tickFormatter={(value) => valueFormat(Number(value))}\n />\n\n <Tooltip\n cursor={{ stroke: chartTokens.axis, strokeWidth: 1 }}\n content={\n <ChartTooltip\n valueFormat={valueFormat}\n labelFormat={xTickFormat}\n hideLabel={false}\n />\n }\n />\n\n {withLegend ? <Legend content={<ChartLegend />} /> : null}\n\n {resolved.map((s, index) =>\n type === \"area\" ? (\n <Area\n key={s.key}\n type=\"monotone\"\n dataKey={s.key}\n name={s.label}\n stroke={s.color}\n strokeWidth={2}\n fill={`url(#${gradientBase}-${index})`}\n isAnimationActive={!reducedMotion}\n dot={false}\n activeDot={{\n r: 4,\n strokeWidth: 2,\n stroke: chartTokens.surface,\n fill: s.color,\n }}\n />\n ) : (\n <Line\n key={s.key}\n type=\"monotone\"\n dataKey={s.key}\n name={s.label}\n stroke={s.color}\n strokeWidth={2}\n isAnimationActive={!reducedMotion}\n dot={false}\n activeDot={{\n r: 4,\n strokeWidth: 2,\n stroke: chartTokens.surface,\n fill: s.color,\n }}\n />\n ),\n )}\n\n {showEndDots\n ? resolved.map((s) => {\n const index = lastFiniteIndex(s.key);\n if (index < 0) return null;\n return (\n <ReferenceDot\n key={`end-${s.key}`}\n x={data[index][xKey] as string | number}\n y={data[index][s.key] as number}\n r={4}\n fill={s.color}\n stroke={chartTokens.surface}\n strokeWidth={2}\n isFront\n />\n );\n })\n : null}\n </Chart>\n </ResponsiveContainer>\n </ChartFigure>\n );\n}\n"],"mappings":";;;;;;AAiEA,SAAgB,EAAW,EACzB,SACA,SACA,WACA,UAAO,QACP,YAAS,KACT,iBAAc,GACd,gBACA,cAAW,IACX,eACA,iBAAc,IACd,eACA,cACA,gBACkB;CAClB,IAAM,IAAe,
|
|
1
|
+
{"version":3,"file":"TrendChart.js","names":[],"sources":["../../../../src/timecampus/components/charts/TrendChart.tsx"],"sourcesContent":["import { useId } from \"react\";\nimport {\n Area,\n AreaChart,\n CartesianGrid,\n Legend,\n Line,\n LineChart,\n ReferenceDot,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport {\n chartTokens,\n defaultSeriesColor,\n formatNumber,\n usePrefersReducedMotion,\n type ChartDatum,\n type ChartSeries,\n type ValueFormatter,\n} from \"./chartTheme\";\nimport {\n ChartDataTable,\n ChartEmpty,\n ChartFigure,\n ChartLegend,\n ChartTooltip,\n} from \"./ChartParts\";\n\nexport interface TrendChartProps {\n /** Rows of `{ [xKey]: label, [series.key]: number }`. */\n data: ChartDatum[];\n /** Field holding the x-axis category/time value. */\n xKey: string;\n /** One or more numeric series. Single series reads on-brand. */\n series: ChartSeries[];\n /** Line, or gradient-filled area. Default `area`. */\n type?: \"line\" | \"area\";\n /** Pixel height of the plot. Default 260. */\n height?: number;\n /** Formats y values in the axis and tooltip. Default grouped integer. */\n valueFormat?: ValueFormatter;\n /** Formats x tick + tooltip header. */\n xTickFormat?: (value: string | number) => string;\n /** Show the horizontal grid. Default true. */\n showGrid?: boolean;\n /** Force the legend on/off. Default: on when there are ≥ 2 series. */\n showLegend?: boolean;\n /** Emphasise each series' final point with a ringed dot. Default true. */\n showEndDots?: boolean;\n /** Message shown when `data` is empty — never fabricate a shape. */\n emptyLabel?: string;\n /** Accessible name for the figure. Default derived from the series labels. */\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * TrendChart — value-over-time as a line or gradient area (asset value,\n * emissions, depreciation). Theme-aware tokens, a hairline grid, a crosshair\n * tooltip, emphasised endpoints, a legend for multi-series, an empty state and\n * a screen-reader data table. Respects `prefers-reduced-motion`.\n */\nexport function TrendChart({\n data,\n xKey,\n series,\n type = \"area\",\n height = 260,\n valueFormat = formatNumber,\n xTickFormat,\n showGrid = true,\n showLegend,\n showEndDots = true,\n emptyLabel,\n ariaLabel,\n className,\n}: TrendChartProps) {\n const gradientBase = useId();\n const reducedMotion = usePrefersReducedMotion();\n\n const resolved = series.map((s, index) => ({\n ...s,\n label: s.label ?? s.key,\n color: s.color ?? defaultSeriesColor(index, series.length),\n }));\n const label =\n ariaLabel ?? `Trend of ${resolved.map((s) => s.label).join(\", \")}`;\n\n if (data.length === 0) {\n return (\n <ChartEmpty height={height} label={emptyLabel} className={className} />\n );\n }\n\n const withLegend = showLegend ?? resolved.length > 1;\n const axisTick = { fill: chartTokens.textMuted, fontSize: 12 };\n\n const lastFiniteIndex = (key: string): number => {\n for (let i = data.length - 1; i >= 0; i -= 1) {\n const value = data[i][key];\n if (typeof value === \"number\" && Number.isFinite(value)) return i;\n }\n return -1;\n };\n\n const Chart = type === \"area\" ? AreaChart : LineChart;\n\n return (\n <ChartFigure\n ariaLabel={label}\n height={height}\n className={className}\n a11y={\n <ChartDataTable\n caption={label}\n xLabel={xKey}\n xKey={xKey}\n data={data}\n series={resolved}\n valueFormat={valueFormat}\n />\n }\n >\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <Chart data={data} margin={{ top: 12, right: 16, bottom: 4, left: 4 }}>\n <defs>\n {resolved.map((s, index) => (\n <linearGradient\n key={s.key}\n id={`${gradientBase}-${index}`}\n x1=\"0\"\n y1=\"0\"\n x2=\"0\"\n y2=\"1\"\n >\n <stop offset=\"0%\" stopColor={s.color} stopOpacity={0.24} />\n <stop offset=\"95%\" stopColor={s.color} stopOpacity={0.02} />\n </linearGradient>\n ))}\n </defs>\n\n {showGrid ? (\n <CartesianGrid\n vertical={false}\n stroke={chartTokens.grid}\n strokeWidth={1}\n />\n ) : null}\n\n <XAxis\n dataKey={xKey}\n tickLine={false}\n axisLine={false}\n tick={axisTick}\n tickMargin={8}\n minTickGap={16}\n tickFormatter={\n xTickFormat\n ? (value) => xTickFormat(value as string | number)\n : undefined\n }\n />\n <YAxis\n tickLine={false}\n axisLine={false}\n tick={axisTick}\n width={48}\n tickFormatter={(value) => valueFormat(Number(value))}\n />\n\n <Tooltip\n cursor={{ stroke: chartTokens.axis, strokeWidth: 1 }}\n content={\n <ChartTooltip\n valueFormat={valueFormat}\n labelFormat={xTickFormat}\n hideLabel={false}\n />\n }\n />\n\n {withLegend ? <Legend content={<ChartLegend />} /> : null}\n\n {resolved.map((s, index) =>\n type === \"area\" ? (\n <Area\n key={s.key}\n type=\"monotone\"\n dataKey={s.key}\n name={s.label}\n stroke={s.color}\n strokeWidth={2}\n fill={`url(#${gradientBase}-${index})`}\n isAnimationActive={!reducedMotion}\n dot={false}\n activeDot={{\n r: 4,\n strokeWidth: 2,\n stroke: chartTokens.surface,\n fill: s.color,\n }}\n />\n ) : (\n <Line\n key={s.key}\n type=\"monotone\"\n dataKey={s.key}\n name={s.label}\n stroke={s.color}\n strokeWidth={2}\n isAnimationActive={!reducedMotion}\n dot={false}\n activeDot={{\n r: 4,\n strokeWidth: 2,\n stroke: chartTokens.surface,\n fill: s.color,\n }}\n />\n ),\n )}\n\n {showEndDots\n ? resolved.map((s) => {\n const index = lastFiniteIndex(s.key);\n if (index < 0) return null;\n return (\n <ReferenceDot\n key={`end-${s.key}`}\n x={data[index][xKey] as string | number}\n y={data[index][s.key] as number}\n r={4}\n fill={s.color}\n stroke={chartTokens.surface}\n strokeWidth={2}\n isFront\n />\n );\n })\n : null}\n </Chart>\n </ResponsiveContainer>\n </ChartFigure>\n );\n}\n"],"mappings":"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"}
|
|
@@ -25,10 +25,10 @@ function r({ weeksLived: r, totalWeeks: i, weeksPerRow: a = 52, horizonRowsWhenO
|
|
|
25
25
|
l,
|
|
26
26
|
d,
|
|
27
27
|
13
|
|
28
|
-
]);
|
|
28
|
+
]), g = s ?? (i == null ? `Your life in weeks: ${l} weeks lived so far` : `Your life in weeks: ${l} of ${Math.floor(i)} weeks lived`);
|
|
29
29
|
return /* @__PURE__ */ n("figure", {
|
|
30
30
|
role: "img",
|
|
31
|
-
"aria-label":
|
|
31
|
+
"aria-label": g,
|
|
32
32
|
className: c,
|
|
33
33
|
children: /* @__PURE__ */ n("div", {
|
|
34
34
|
className: "w-full overflow-x-auto",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WeeksGrid.js","names":[],"sources":["../../../../src/timecampus/components/charts/WeeksGrid.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { chartTokens } from \"./chartTheme\";\n\nexport interface WeeksGridProps {\n /** Whole weeks lived so far. Null when the user has not given a birth date. */\n weeksLived: number | null;\n /** Total weeks in the expected lifespan. Null when no expectancy is given. */\n totalWeeks: number | null;\n /** Columns per row. Default 52 (one year per row). */\n weeksPerRow?: number;\n /**\n * When there is no expectancy, how many future rows of hollow cells to show\n * as a horizon beyond the weeks lived. Default 12 (about a decade of context).\n */\n horizonRowsWhenOpen?: number;\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * WeeksGrid — the finite-life \"your life in weeks\" memento. Each cell is one\n * week: weeks lived are filled with the brand token, the current week is ringed,\n * and future weeks are hollow. It is honest by construction — it renders only\n * what the user's own (optional, private) birth date and expectancy imply, never\n * a guessed age or an invented mortality date. Drawn as a single SVG so even a\n * ~90-year grid (≈ 4,700 cells) stays light, and it scales responsively via a\n * viewBox inside a horizontally-scrollable frame.\n */\nexport function WeeksGrid({\n weeksLived,\n totalWeeks,\n weeksPerRow = 52,\n horizonRowsWhenOpen = 12,\n ariaLabel,\n className,\n}: WeeksGridProps) {\n const lived =\n weeksLived != null && weeksLived >= 0 ? Math.floor(weeksLived) : 0;\n\n const totalCells = useMemo(() => {\n if (totalWeeks != null && totalWeeks > 0) return Math.floor(totalWeeks);\n // No expectancy: show the weeks lived plus a modest hollow horizon.\n return lived + Math.max(1, horizonRowsWhenOpen) * weeksPerRow;\n }, [totalWeeks, lived, horizonRowsWhenOpen, weeksPerRow]);\n\n const cols = Math.max(1, weeksPerRow);\n const rows = Math.max(1, Math.ceil(totalCells / cols));\n\n // Geometry in SVG user units; the viewBox lets it scale to any width.\n const cell = 10;\n const gap = 3;\n const step = cell + gap;\n const width = cols * step - gap;\n const heightUnits = rows * step - gap;\n\n const cells = useMemo(() => {\n const out: {\n i: number;\n x: number;\n y: number;\n state: \"lived\" | \"current\" | \"future\";\n }[] = [];\n for (let i = 0; i < totalCells; i++) {\n const state = i < lived ? \"lived\" : i === lived ? \"current\" : \"future\";\n out.push({\n i,\n x: (i % cols) * step,\n y: Math.floor(i / cols) * step,\n state,\n });\n }\n return out;\n }, [totalCells, lived, cols, step]);\n\n const label =\n ariaLabel ??\n (totalWeeks != null\n ? `Your life in weeks: ${lived} of ${Math.floor(totalWeeks)} weeks lived`\n : `Your life in weeks: ${lived} weeks lived so far`);\n\n return (\n <figure role=\"img\" aria-label={label} className={className}>\n <div className=\"w-full overflow-x-auto\">\n <svg\n viewBox={`0 0 ${width} ${heightUnits}`}\n width=\"100%\"\n preserveAspectRatio=\"xMinYMin meet\"\n className=\"min-w-[520px]\"\n role=\"presentation\"\n >\n {cells.map((c) => {\n const isLived = c.state === \"lived\";\n const isCurrent = c.state === \"current\";\n return (\n <rect\n key={c.i}\n x={c.x}\n y={c.y}\n width={cell}\n height={cell}\n rx={2}\n ry={2}\n fill={\n isLived\n ? chartTokens.brand\n : isCurrent\n ? chartTokens.surface\n : \"transparent\"\n }\n stroke={\n isCurrent\n ? chartTokens.brand\n : isLived\n ? \"transparent\"\n : chartTokens.border\n }\n strokeWidth={isCurrent ? 1.5 : 1}\n />\n );\n })}\n </svg>\n </div>\n </figure>\n );\n}\n"],"mappings":";;;;AA4BA,SAAgB,EAAU,EACxB,eACA,eACA,iBAAc,IACd,yBAAsB,IACtB,cACA,gBACiB;CACjB,IAAM,IACJ,KAAc,QAAQ,KAAc,IAAI,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"WeeksGrid.js","names":[],"sources":["../../../../src/timecampus/components/charts/WeeksGrid.tsx"],"sourcesContent":["import { useMemo } from \"react\";\nimport { chartTokens } from \"./chartTheme\";\n\nexport interface WeeksGridProps {\n /** Whole weeks lived so far. Null when the user has not given a birth date. */\n weeksLived: number | null;\n /** Total weeks in the expected lifespan. Null when no expectancy is given. */\n totalWeeks: number | null;\n /** Columns per row. Default 52 (one year per row). */\n weeksPerRow?: number;\n /**\n * When there is no expectancy, how many future rows of hollow cells to show\n * as a horizon beyond the weeks lived. Default 12 (about a decade of context).\n */\n horizonRowsWhenOpen?: number;\n ariaLabel?: string;\n className?: string;\n}\n\n/**\n * WeeksGrid — the finite-life \"your life in weeks\" memento. Each cell is one\n * week: weeks lived are filled with the brand token, the current week is ringed,\n * and future weeks are hollow. It is honest by construction — it renders only\n * what the user's own (optional, private) birth date and expectancy imply, never\n * a guessed age or an invented mortality date. Drawn as a single SVG so even a\n * ~90-year grid (≈ 4,700 cells) stays light, and it scales responsively via a\n * viewBox inside a horizontally-scrollable frame.\n */\nexport function WeeksGrid({\n weeksLived,\n totalWeeks,\n weeksPerRow = 52,\n horizonRowsWhenOpen = 12,\n ariaLabel,\n className,\n}: WeeksGridProps) {\n const lived =\n weeksLived != null && weeksLived >= 0 ? Math.floor(weeksLived) : 0;\n\n const totalCells = useMemo(() => {\n if (totalWeeks != null && totalWeeks > 0) return Math.floor(totalWeeks);\n // No expectancy: show the weeks lived plus a modest hollow horizon.\n return lived + Math.max(1, horizonRowsWhenOpen) * weeksPerRow;\n }, [totalWeeks, lived, horizonRowsWhenOpen, weeksPerRow]);\n\n const cols = Math.max(1, weeksPerRow);\n const rows = Math.max(1, Math.ceil(totalCells / cols));\n\n // Geometry in SVG user units; the viewBox lets it scale to any width.\n const cell = 10;\n const gap = 3;\n const step = cell + gap;\n const width = cols * step - gap;\n const heightUnits = rows * step - gap;\n\n const cells = useMemo(() => {\n const out: {\n i: number;\n x: number;\n y: number;\n state: \"lived\" | \"current\" | \"future\";\n }[] = [];\n for (let i = 0; i < totalCells; i++) {\n const state = i < lived ? \"lived\" : i === lived ? \"current\" : \"future\";\n out.push({\n i,\n x: (i % cols) * step,\n y: Math.floor(i / cols) * step,\n state,\n });\n }\n return out;\n }, [totalCells, lived, cols, step]);\n\n const label =\n ariaLabel ??\n (totalWeeks != null\n ? `Your life in weeks: ${lived} of ${Math.floor(totalWeeks)} weeks lived`\n : `Your life in weeks: ${lived} weeks lived so far`);\n\n return (\n <figure role=\"img\" aria-label={label} className={className}>\n <div className=\"w-full overflow-x-auto\">\n <svg\n viewBox={`0 0 ${width} ${heightUnits}`}\n width=\"100%\"\n preserveAspectRatio=\"xMinYMin meet\"\n className=\"min-w-[520px]\"\n role=\"presentation\"\n >\n {cells.map((c) => {\n const isLived = c.state === \"lived\";\n const isCurrent = c.state === \"current\";\n return (\n <rect\n key={c.i}\n x={c.x}\n y={c.y}\n width={cell}\n height={cell}\n rx={2}\n ry={2}\n fill={\n isLived\n ? chartTokens.brand\n : isCurrent\n ? chartTokens.surface\n : \"transparent\"\n }\n stroke={\n isCurrent\n ? chartTokens.brand\n : isLived\n ? \"transparent\"\n : chartTokens.border\n }\n strokeWidth={isCurrent ? 1.5 : 1}\n />\n );\n })}\n </svg>\n </div>\n </figure>\n );\n}\n"],"mappings":";;;;AA4BA,SAAgB,EAAU,EACxB,eACA,eACA,iBAAc,IACd,yBAAsB,IACtB,cACA,gBACiB;CACjB,IAAM,IACJ,KAAc,QAAQ,KAAc,IAAI,KAAK,MAAM,CAAU,IAAI,GAE7D,IAAa,QACb,KAAc,QAAQ,IAAa,IAAU,KAAK,MAAM,CAAU,IAE/D,IAAQ,KAAK,IAAI,GAAG,CAAmB,IAAI,GACjD;EAAC;EAAY;EAAO;EAAqB;CAAW,CAAC,GAElD,IAAO,KAAK,IAAI,GAAG,CAAW,GAC9B,IAAO,KAAK,IAAI,GAAG,KAAK,KAAK,IAAa,CAAI,CAAC,GAM/C,IAAQ,IAAO,KAAO,GACtB,IAAc,IAAO,KAAO,GAE5B,IAAQ,QAAc;EAC1B,IAAM,IAKA,CAAC;EACP,KAAK,IAAI,IAAI,GAAG,IAAI,GAAY,KAAK;GACnC,IAAM,IAAQ,IAAI,IAAQ,UAAU,MAAM,IAAQ,YAAY;GAC9D,EAAI,KAAK;IACP;IACA,GAAI,IAAI,IAAQ;IAChB,GAAG,KAAK,MAAM,IAAI,CAAI,IAAI;IAC1B;GACF,CAAC;EACH;EACA,OAAO;CACT,GAAG;EAAC;EAAY;EAAO;EAAM;CAAI,CAAC,GAE5B,IACJ,MACC,KAAc,OAEX,uBAAuB,EAAM,uBAD7B,uBAAuB,EAAM,MAAM,KAAK,MAAM,CAAU,EAAE;CAGhE,OACE,kBAAC,UAAD;EAAQ,MAAK;EAAM,cAAY;EAAkB;EAC/C,UAAA,kBAAC,OAAD;GAAK,WAAU;GACb,UAAA,kBAAC,OAAD;IACE,SAAS,OAAO,EAAM,GAAG;IACzB,OAAM;IACN,qBAAoB;IACpB,WAAU;IACV,MAAK;IAEJ,UAAA,EAAM,KAAK,MAAM;KAChB,IAAM,IAAU,EAAE,UAAU,SACtB,IAAY,EAAE,UAAU;KAC9B,OACE,kBAAC,QAAD;MAEE,GAAG,EAAE;MACL,GAAG,EAAE;MACL,OAAO;MACP,QAAQ;MACR,IAAI;MACJ,IAAI;MACJ,MACE,IACI,EAAY,QACZ,IACE,EAAY,UACZ;MAER,QACE,IACI,EAAY,QACZ,IACE,gBACA,EAAY;MAEpB,aAAa,IAAY,MAAM;KAChC,GAtBM,EAAE,CAsBR;IAEL,CAAC;GACE,CAAA;EACF,CAAA;CACC,CAAA;AAEZ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chartTheme.js","names":[],"sources":["../../../../src/timecampus/components/charts/chartTheme.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\n\n/**\n * chartTheme — the single source of truth that maps every chart mark to a live\n * semantic CSS custom property from the Boff UI 2.0 design system\n * (`@burdenoff/fe-libs/shared/tokens`).\n *\n * Because every value is a `var(--color-*)` reference rather than a baked hex,\n * the charts are theme-aware for free: they recolour instantly on a light/dark\n * switch and pick up the TimeCampus brand (which the host shell writes\n * into `--color-accent-primary`) with zero JS re-resolution. Nothing here is a\n * raw colour — the design system owns the palette; these components only\n * reference it.\n *\n * Palette provenance: the categorical ramp is the design system's validated\n * 12-step `--color-chart-*` scale. It is CVD-safe (worst adjacent Machado-2009\n * ΔE ≈ 35 in light / ≈ 52 in dark, well above the ≥ 12 target). Slots are\n * assigned in fixed order and NEVER cycled — a series index past the ramp folds\n * onto the last slot rather than repainting an existing hue (see `seriesColor`).\n */\nexport const chartTokens = {\n /** Categorical identity ramp — fixed order, assigned in sequence, never cycled. */\n series: [\n \"var(--color-chart-1)\",\n \"var(--color-chart-2)\",\n \"var(--color-chart-3)\",\n \"var(--color-chart-4)\",\n \"var(--color-chart-5)\",\n \"var(--color-chart-6)\",\n \"var(--color-chart-7)\",\n \"var(--color-chart-8)\",\n \"var(--color-chart-9)\",\n \"var(--color-chart-10)\",\n \"var(--color-chart-11)\",\n \"var(--color-chart-12)\",\n ],\n /** Brand accent (the TimeCampus brand) — the default for a single series. */\n brand: \"var(--color-accent-primary)\",\n /** Value polarity. */\n positive: \"var(--color-chart-positive)\",\n negative: \"var(--color-chart-negative)\",\n /** Reserved status scale — always paired with an icon + label at the call site. */\n status: {\n success: \"var(--color-status-success-bg)\",\n warning: \"var(--color-status-warning-bg)\",\n danger: \"var(--color-status-error-bg)\",\n info: \"var(--color-status-info-bg)\",\n },\n /** Recessive chrome. */\n grid: \"var(--color-chart-grid)\",\n axis: \"var(--color-chart-axis)\",\n surface: \"var(--color-bg-surface)\",\n track: \"var(--color-bg-sunken)\",\n border: \"var(--color-border-seam)\",\n /** Ink — marks never wear these; labels, axes and legends do. */\n textPrimary: \"var(--color-text-primary)\",\n textSecondary: \"var(--color-text-secondary)\",\n textMuted: \"var(--color-text-muted)\",\n} as const;\n\n/** A named data series drawn by TrendChart / BarsChart. */\nexport interface ChartSeries {\n /** Key into each datum object. */\n key: string;\n /** Human label (legend + tooltip). Falls back to `key`. */\n label?: string;\n /** Explicit mark colour (a CSS colour, typically a `var(--color-*)`). */\n color?: string;\n}\n\n/** A single datum row: an x-value plus one or more numeric series values. */\nexport type ChartDatum = Record<string, string | number | null | undefined>;\n\n/** A slice for DonutChart. */\nexport interface DonutSlice {\n name: string;\n value: number;\n color?: string;\n}\n\n/** Severity tone shared by meters and gauges. */\nexport type MeterTone = \"success\" | \"warning\" | \"danger\";\n\n/**\n * Pick the categorical hue for slot `i`, clamped to the ramp — it NEVER cycles.\n * A count beyond the ramp folds onto the last slot (callers that need more\n * distinct categories should aggregate the tail into \"Other\").\n */\nexport function seriesColor(i: number): string {\n const ramp = chartTokens.series;\n if (i <= 0) return ramp[0];\n return i < ramp.length ? ramp[i] : ramp[ramp.length - 1];\n}\n\n/** Resolve a severity tone to its reserved status token. */\nexport function toneColor(tone: MeterTone): string {\n return chartTokens.status[tone];\n}\n\n/**\n * Resolve the default colour for series slot `i` in an N-series chart: a single\n * series reads on-brand; multiple series take the categorical ramp.\n */\nexport function defaultSeriesColor(index: number, total: number): string {\n return total <= 1 ? chartTokens.brand : seriesColor(index);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Number formatting */\n/* -------------------------------------------------------------------------- */\n\n/** A value formatter: `(value) => label`. Passed to every chart's `valueFormat`. */\nexport type ValueFormatter = (value: number) => string;\n\n/** Plain grouped integer/decimal, e.g. `17,960`. Default everywhere. */\nexport const formatNumber: ValueFormatter = (value) => value.toLocaleString();\n\n/** Compact notation, e.g. `12.9K`, `4.2M` — for axis ticks and dense KPIs. */\nexport const formatCompact: ValueFormatter = (value) =>\n new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(value);\n\n/** Compact currency, e.g. `$4.2M`. */\nexport function formatCurrencyCompact(currency = \"USD\"): ValueFormatter {\n return (value) =>\n new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency,\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(value);\n}\n\n/** Percent with a fixed number of fraction digits, e.g. `68%`. */\nexport function formatPercent(fractionDigits = 0): ValueFormatter {\n return (value) => `${value.toFixed(fractionDigits)}%`;\n}\n\n/** Render an unknown cell value through a formatter, tolerant of strings/null. */\nexport function renderValue(\n value: number | string | null | undefined,\n formatter: ValueFormatter = formatNumber,\n): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"number\")\n return Number.isFinite(value) ? formatter(value) : \"—\";\n return String(value);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Motion */\n/* -------------------------------------------------------------------------- */\n\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\n\nfunction subscribeReducedMotion(onChange: () => void): () => void {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return () => {};\n }\n const query = window.matchMedia(REDUCED_MOTION_QUERY);\n query.addEventListener(\"change\", onChange);\n return () => query.removeEventListener(\"change\", onChange);\n}\n\nfunction getReducedMotionSnapshot(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\")\n return false;\n return window.matchMedia(REDUCED_MOTION_QUERY).matches;\n}\n\n/**\n * Tracks the user's `prefers-reduced-motion` setting so charts can disable\n * recharts' enter animation. Subscribes to the media query via\n * `useSyncExternalStore` (SSR-safe — defaults to \"not reduced\" on the server).\n */\nexport function usePrefersReducedMotion(): boolean {\n return useSyncExternalStore(\n subscribeReducedMotion,\n getReducedMotionSnapshot,\n () => false,\n );\n}\n"],"mappings":";;AAoBA,IAAa,IAAc;CAEzB,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;
|
|
1
|
+
{"version":3,"file":"chartTheme.js","names":[],"sources":["../../../../src/timecampus/components/charts/chartTheme.ts"],"sourcesContent":["import { useSyncExternalStore } from \"react\";\n\n/**\n * chartTheme — the single source of truth that maps every chart mark to a live\n * semantic CSS custom property from the Boff UI 2.0 design system\n * (`@burdenoff/fe-libs/shared/tokens`).\n *\n * Because every value is a `var(--color-*)` reference rather than a baked hex,\n * the charts are theme-aware for free: they recolour instantly on a light/dark\n * switch and pick up the TimeCampus brand (which the host shell writes\n * into `--color-accent-primary`) with zero JS re-resolution. Nothing here is a\n * raw colour — the design system owns the palette; these components only\n * reference it.\n *\n * Palette provenance: the categorical ramp is the design system's validated\n * 12-step `--color-chart-*` scale. It is CVD-safe (worst adjacent Machado-2009\n * ΔE ≈ 35 in light / ≈ 52 in dark, well above the ≥ 12 target). Slots are\n * assigned in fixed order and NEVER cycled — a series index past the ramp folds\n * onto the last slot rather than repainting an existing hue (see `seriesColor`).\n */\nexport const chartTokens = {\n /** Categorical identity ramp — fixed order, assigned in sequence, never cycled. */\n series: [\n \"var(--color-chart-1)\",\n \"var(--color-chart-2)\",\n \"var(--color-chart-3)\",\n \"var(--color-chart-4)\",\n \"var(--color-chart-5)\",\n \"var(--color-chart-6)\",\n \"var(--color-chart-7)\",\n \"var(--color-chart-8)\",\n \"var(--color-chart-9)\",\n \"var(--color-chart-10)\",\n \"var(--color-chart-11)\",\n \"var(--color-chart-12)\",\n ],\n /** Brand accent (the TimeCampus brand) — the default for a single series. */\n brand: \"var(--color-accent-primary)\",\n /** Value polarity. */\n positive: \"var(--color-chart-positive)\",\n negative: \"var(--color-chart-negative)\",\n /** Reserved status scale — always paired with an icon + label at the call site. */\n status: {\n success: \"var(--color-status-success-bg)\",\n warning: \"var(--color-status-warning-bg)\",\n danger: \"var(--color-status-error-bg)\",\n info: \"var(--color-status-info-bg)\",\n },\n /** Recessive chrome. */\n grid: \"var(--color-chart-grid)\",\n axis: \"var(--color-chart-axis)\",\n surface: \"var(--color-bg-surface)\",\n track: \"var(--color-bg-sunken)\",\n border: \"var(--color-border-seam)\",\n /** Ink — marks never wear these; labels, axes and legends do. */\n textPrimary: \"var(--color-text-primary)\",\n textSecondary: \"var(--color-text-secondary)\",\n textMuted: \"var(--color-text-muted)\",\n} as const;\n\n/** A named data series drawn by TrendChart / BarsChart. */\nexport interface ChartSeries {\n /** Key into each datum object. */\n key: string;\n /** Human label (legend + tooltip). Falls back to `key`. */\n label?: string;\n /** Explicit mark colour (a CSS colour, typically a `var(--color-*)`). */\n color?: string;\n}\n\n/** A single datum row: an x-value plus one or more numeric series values. */\nexport type ChartDatum = Record<string, string | number | null | undefined>;\n\n/** A slice for DonutChart. */\nexport interface DonutSlice {\n name: string;\n value: number;\n color?: string;\n}\n\n/** Severity tone shared by meters and gauges. */\nexport type MeterTone = \"success\" | \"warning\" | \"danger\";\n\n/**\n * Pick the categorical hue for slot `i`, clamped to the ramp — it NEVER cycles.\n * A count beyond the ramp folds onto the last slot (callers that need more\n * distinct categories should aggregate the tail into \"Other\").\n */\nexport function seriesColor(i: number): string {\n const ramp = chartTokens.series;\n if (i <= 0) return ramp[0];\n return i < ramp.length ? ramp[i] : ramp[ramp.length - 1];\n}\n\n/** Resolve a severity tone to its reserved status token. */\nexport function toneColor(tone: MeterTone): string {\n return chartTokens.status[tone];\n}\n\n/**\n * Resolve the default colour for series slot `i` in an N-series chart: a single\n * series reads on-brand; multiple series take the categorical ramp.\n */\nexport function defaultSeriesColor(index: number, total: number): string {\n return total <= 1 ? chartTokens.brand : seriesColor(index);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Number formatting */\n/* -------------------------------------------------------------------------- */\n\n/** A value formatter: `(value) => label`. Passed to every chart's `valueFormat`. */\nexport type ValueFormatter = (value: number) => string;\n\n/** Plain grouped integer/decimal, e.g. `17,960`. Default everywhere. */\nexport const formatNumber: ValueFormatter = (value) => value.toLocaleString();\n\n/** Compact notation, e.g. `12.9K`, `4.2M` — for axis ticks and dense KPIs. */\nexport const formatCompact: ValueFormatter = (value) =>\n new Intl.NumberFormat(undefined, {\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(value);\n\n/** Compact currency, e.g. `$4.2M`. */\nexport function formatCurrencyCompact(currency = \"USD\"): ValueFormatter {\n return (value) =>\n new Intl.NumberFormat(undefined, {\n style: \"currency\",\n currency,\n notation: \"compact\",\n maximumFractionDigits: 1,\n }).format(value);\n}\n\n/** Percent with a fixed number of fraction digits, e.g. `68%`. */\nexport function formatPercent(fractionDigits = 0): ValueFormatter {\n return (value) => `${value.toFixed(fractionDigits)}%`;\n}\n\n/** Render an unknown cell value through a formatter, tolerant of strings/null. */\nexport function renderValue(\n value: number | string | null | undefined,\n formatter: ValueFormatter = formatNumber,\n): string {\n if (value === null || value === undefined) return \"—\";\n if (typeof value === \"number\")\n return Number.isFinite(value) ? formatter(value) : \"—\";\n return String(value);\n}\n\n/* -------------------------------------------------------------------------- */\n/* Motion */\n/* -------------------------------------------------------------------------- */\n\nconst REDUCED_MOTION_QUERY = \"(prefers-reduced-motion: reduce)\";\n\nfunction subscribeReducedMotion(onChange: () => void): () => void {\n if (\n typeof window === \"undefined\" ||\n typeof window.matchMedia !== \"function\"\n ) {\n return () => {};\n }\n const query = window.matchMedia(REDUCED_MOTION_QUERY);\n query.addEventListener(\"change\", onChange);\n return () => query.removeEventListener(\"change\", onChange);\n}\n\nfunction getReducedMotionSnapshot(): boolean {\n if (typeof window === \"undefined\" || typeof window.matchMedia !== \"function\")\n return false;\n return window.matchMedia(REDUCED_MOTION_QUERY).matches;\n}\n\n/**\n * Tracks the user's `prefers-reduced-motion` setting so charts can disable\n * recharts' enter animation. Subscribes to the media query via\n * `useSyncExternalStore` (SSR-safe — defaults to \"not reduced\" on the server).\n */\nexport function usePrefersReducedMotion(): boolean {\n return useSyncExternalStore(\n subscribeReducedMotion,\n getReducedMotionSnapshot,\n () => false,\n );\n}\n"],"mappings":";;AAoBA,IAAa,IAAc;CAEzB,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,OAAO;CAEP,UAAU;CACV,UAAU;CAEV,QAAQ;EACN,SAAS;EACT,SAAS;EACT,QAAQ;EACR,MAAM;CACR;CAEA,MAAM;CACN,MAAM;CACN,SAAS;CACT,OAAO;CACP,QAAQ;CAER,aAAa;CACb,eAAe;CACf,WAAW;AACb;AA8BA,SAAgB,EAAY,GAAmB;CAC7C,IAAM,IAAO,EAAY;CAEzB,OADI,KAAK,IAAU,EAAK,KACjB,IAAI,EAAK,SAAS,EAAK,KAAK,EAAK,EAAK,SAAS;AACxD;AAGA,SAAgB,EAAU,GAAyB;CACjD,OAAO,EAAY,OAAO;AAC5B;AAMA,SAAgB,EAAmB,GAAe,GAAuB;CACvE,OAAO,KAAS,IAAI,EAAY,QAAQ,EAAY,CAAK;AAC3D;AAUA,IAAa,KAAgC,MAAU,EAAM,eAAe;AA0B5E,SAAgB,EACd,GACA,IAA4B,GACpB;CAIR,OAHI,KAAU,OAAoC,MAC9C,OAAO,KAAU,WACZ,OAAO,SAAS,CAAK,IAAI,EAAU,CAAK,IAAI,MAC9C,OAAO,CAAK;AACrB;AAMA,IAAM,IAAuB;AAE7B,SAAS,EAAuB,GAAkC;CAChE,IACE,OAAO,SAAW,OAClB,OAAO,OAAO,cAAe,YAE7B,aAAa,CAAC;CAEhB,IAAM,IAAQ,OAAO,WAAW,CAAoB;CAEpD,OADA,EAAM,iBAAiB,UAAU,CAAQ,SAC5B,EAAM,oBAAoB,UAAU,CAAQ;AAC3D;AAEA,SAAS,IAAoC;CAG3C,OAFI,OAAO,SAAW,OAAe,OAAO,OAAO,cAAe,aACzD,KACF,OAAO,WAAW,CAAoB,CAAC,CAAC;AACjD;AAOA,SAAgB,IAAmC;CACjD,OAAO,EACL,GACA,SACM,EACR;AACF"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import "./chartTheme.js";
|
|
1
|
+
import { chartTokens as e, formatNumber as t } from "./chartTheme.js";
|
|
2
2
|
import "./Sparkline.js";
|
|
3
3
|
import "./ChartParts.js";
|
|
4
|
-
import "./TrendChart.js";
|
|
5
|
-
import "./BarsChart.js";
|
|
6
|
-
import "./DonutChart.js";
|
|
7
|
-
import "./RadialGauge.js";
|
|
8
|
-
import "./ProgressMeter.js";
|
|
9
|
-
import "./Heatmap.js";
|
|
10
|
-
import "./BalanceWheel.js";
|
|
11
|
-
import "./WeeksGrid.js";
|
|
4
|
+
import { TrendChart as n } from "./TrendChart.js";
|
|
5
|
+
import { BarsChart as r } from "./BarsChart.js";
|
|
6
|
+
import { DonutChart as i } from "./DonutChart.js";
|
|
7
|
+
import { RadialGauge as a } from "./RadialGauge.js";
|
|
8
|
+
import { ProgressMeter as o } from "./ProgressMeter.js";
|
|
9
|
+
import { Heatmap as s } from "./Heatmap.js";
|
|
10
|
+
import { BalanceWheel as c } from "./BalanceWheel.js";
|
|
11
|
+
import { WeeksGrid as l } from "./WeeksGrid.js";
|
|
12
|
+
export { c as BalanceWheel, r as BarsChart, i as DonutChart, s as Heatmap, o as ProgressMeter, a as RadialGauge, n as TrendChart, l as WeeksGrid, e as chartTokens, t as formatNumber };
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import "./StatCard.js";
|
|
2
|
-
import "./LoadingSkeleton.js";
|
|
1
|
+
import { StatCard as e } from "./StatCard.js";
|
|
2
|
+
import { LoadingSkeleton as t } from "./LoadingSkeleton.js";
|
|
3
3
|
import "./ErrorBoundary.js";
|
|
4
|
-
import "./PageLayout.js";
|
|
5
|
-
import "./StatusBadge.js";
|
|
6
|
-
import "./EmptyState.js";
|
|
7
|
-
import "./Modal.js";
|
|
4
|
+
import { PageLayout as n } from "./PageLayout.js";
|
|
5
|
+
import { StatusBadge as r } from "./StatusBadge.js";
|
|
6
|
+
import { EmptyState as i } from "./EmptyState.js";
|
|
7
|
+
import { Modal as a } from "./Modal.js";
|
|
8
8
|
import "./DataTable.js";
|
|
9
|
-
import "./ChartCard.js";
|
|
9
|
+
import { ChartCard as o } from "./ChartCard.js";
|
|
10
10
|
import "./FilterBar.js";
|
|
11
|
-
import "./Toast.js";
|
|
12
|
-
import "./charts/chartTheme.js";
|
|
11
|
+
import { ToastContainer as s, useToast as c } from "./Toast.js";
|
|
12
|
+
import { chartTokens as l, formatNumber as u } from "./charts/chartTheme.js";
|
|
13
13
|
import "./charts/ChartParts.js";
|
|
14
|
-
import "./charts/TrendChart.js";
|
|
15
|
-
import "./charts/BarsChart.js";
|
|
16
|
-
import "./charts/DonutChart.js";
|
|
17
|
-
import "./charts/RadialGauge.js";
|
|
18
|
-
import "./charts/ProgressMeter.js";
|
|
19
|
-
import "./charts/Heatmap.js";
|
|
20
|
-
import "./charts/BalanceWheel.js";
|
|
21
|
-
import "./charts/WeeksGrid.js";
|
|
14
|
+
import { TrendChart as d } from "./charts/TrendChart.js";
|
|
15
|
+
import { BarsChart as f } from "./charts/BarsChart.js";
|
|
16
|
+
import { DonutChart as p } from "./charts/DonutChart.js";
|
|
17
|
+
import { RadialGauge as m } from "./charts/RadialGauge.js";
|
|
18
|
+
import { ProgressMeter as h } from "./charts/ProgressMeter.js";
|
|
19
|
+
import { Heatmap as g } from "./charts/Heatmap.js";
|
|
20
|
+
import { BalanceWheel as _ } from "./charts/BalanceWheel.js";
|
|
21
|
+
import { WeeksGrid as v } from "./charts/WeeksGrid.js";
|
|
22
22
|
import "./charts/index.js";
|
|
23
|
+
export { _ as BalanceWheel, f as BarsChart, o as ChartCard, p as DonutChart, i as EmptyState, g as Heatmap, t as LoadingSkeleton, a as Modal, n as PageLayout, h as ProgressMeter, m as RadialGauge, e as StatCard, r as StatusBadge, s as ToastContainer, d as TrendChart, v as WeeksGrid, l as chartTokens, u as formatNumber, c as useToast };
|
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
* @module @burdenoff/microfe-timecampus
|
|
4
4
|
*/
|
|
5
5
|
export { TimeCampusRoot } from './TimeCampusRoot';
|
|
6
|
-
export
|
|
6
|
+
export { AdminRoot } from './AdminRoot';
|
|
7
|
+
export { AdminRoutes } from './AdminRoutes';
|
|
8
|
+
export type { TimeCampusRootProps, AdminRootProps, NavItem, FooterItem, } from './types';
|
|
7
9
|
export { useTimeCampus, useTimeCampusNavigate, } from './providers/TimeCampusProvider';
|
|
8
10
|
export { useTimeCampusStore } from './store/timecampusStore';
|
|
9
11
|
export * from '../services/createSandboxAssistantTransport';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timecampus/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/timecampus/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,OAAO,EACP,UAAU,GACX,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,aAAa,EACb,qBAAqB,GACtB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAO7D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,gCAAgC,CAAC"}
|
package/dist/timecampus/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import "./providers/TimeCampusProvider.js";
|
|
2
|
-
import "../generated/wspace-operations.js";
|
|
3
|
-
import "./TimeCampusRoot.js";
|
|
4
|
-
import "./
|
|
5
|
-
import "
|
|
1
|
+
import { useTimeCampus as e, useTimeCampusNavigate as t } from "./providers/TimeCampusProvider.js";
|
|
2
|
+
import { AcceptRecommendationDocument as n, ActivateResourcePlanDocument as r, AddParticipantDocument as i, ApplicationUsageFieldsFragmentDoc as a, ApprovalRequestFieldsFragmentDoc as o, ApproveExpenseDocument as s, ApproveRequestDocument as c, ArchiveProjectDocument as l, BalanceTargetFieldsFragmentDoc as u, BulkCreateAllocationsDocument as d, BulkCreateEmailTimeEntriesDocument as f, BulkDeleteTimeEntriesDocument as p, CalculateFocusScoreDocument as m, CaptureEventFieldsFragmentDoc as h, CategorizeApplicationDocument as g, ClientPortalFieldsFragmentDoc as _, CompleteActionItemDocument as v, CompletePomodoroSessionDocument as y, ContextSharingPolicyFieldsFragmentDoc as b, CreateActionItemDocument as x, CreateAllocationDocument as S, CreateClientPortalConfigDocument as C, CreateEmailTimeEntryDocument as w, CreateExpenseDocument as T, CreateGeofenceDocument as E, CreateLifeGoalDocument as D, CreateLocationEntryDocument as O, CreateMeetingDocument as k, CreatePomodoroGoalDocument as A, CreateProjectDocument as j, CreateResourcePlanDocument as M, CreateTaskDocument as N, CreateTimeEntryDocument as P, DeclareLifeValueDocument as F, DeleteActionItemDocument as I, DeleteAllocationDocument as L, DeleteApplicationUsageDocument as R, DeleteClientPortalConfigDocument as z, DeleteEmailTimeEntryDocument as B, DeleteExpenseDocument as V, DeleteFocusScoreDocument as H, DeleteGeofenceDocument as U, DeleteInvoiceDraftDocument as W, DeleteLifeGoalDocument as G, DeleteLifeValueDocument as K, DeleteLocationEntryDocument as q, DeleteMeetingDocument as J, DeletePomodoroGoalDocument as Y, DeleteProjectDocument as X, DeleteResourcePlanDocument as Z, DeleteTaskDocument as Q, DeleteTimeCampusCaptureEventDocument as $, DeleteTimeEntryDocument as ee, DeleteWorkPatternDocument as te, DismissRecommendationDocument as ne, DuplicateTimeEntryDocument as re, EmailTimeEntryFieldsFragmentDoc as ie, ExpenseFieldsFragmentDoc as ae, FocusScoreFieldsFragmentDoc as oe, GenerateInvoiceDraftDocument as se, GenerateMyRecommendationsDocument as ce, GeofenceEventFieldsFragmentDoc as le, GeofenceFieldsFragmentDoc as ue, GetActiveLocationEntryDocument as de, GetActivePomodoroSessionDocument as fe, GetAppUsageSummaryDocument as pe, GetApplicationUsageDocument as me, GetApprovalRequestDocument as he, GetApprovalStatsDocument as ge, GetCapacityOverviewDocument as _e, GetClientPortalConfigDocument as ve, GetClientPortalStatsDocument as ye, GetEmailTimeEntryDocument as be, GetEmailTrackingStatsDocument as xe, GetExpenseDocument as Se, GetExpenseStatsDocument as Ce, GetFocusScoreDocument as we, GetFocusScoreSummaryDocument as Te, GetFocusScoreTrendDocument as Ee, GetGeofenceDocument as De, GetInvoiceDocument as Oe, GetInvoiceHtmlDocument as ke, GetInvoicePdfDocument as Ae, GetInvoiceStatsDocument as je, GetLocationEntryDocument as Me, GetLocationStatsDocument as Ne, GetMeetingDocument as Pe, GetMeetingStatsDocument as Fe, GetPomodoroSessionDocument as Ie, GetPomodoroSettingsDocument as Le, GetPomodoroStatsDocument as Re, GetProjectDocument as ze, GetProjectStatsDocument as Be, GetResourcePlanDocument as Ve, GetTaskDocument as He, GetTeamWorkPatternSummaryDocument as Ue, GetTimeCampusTimelineDocument as We, GetTimeEntryCountDocument as Ge, GetTimeEntryDocument as Ke, GetTimeEntryStatsDocument as qe, GetTodayFocusScoreDocument as Je, GetTodayWorkPatternDocument as Ye, GetWorkPatternDocument as Xe, GetWorkPatternSummaryDocument as Ze, GrantSourceConsentDocument as Qe, IngestTimeCampusCaptureEventsDocument as $e, InterruptPomodoroSessionDocument as et, InvoiceFieldsFragmentDoc as tt, InvoiceLineItemFieldsFragmentDoc as nt, LifeGoalFieldsFragmentDoc as rt, LifeProfileFieldsFragmentDoc as it, LifeTimelineDocument as at, LifeValueFieldsFragmentDoc as ot, ListApplicationUsagesDocument as st, ListApprovalRequestsDocument as ct, ListClientPortalConfigsDocument as lt, ListEmailTimeEntriesDocument as ut, ListExpenseCategoriesDocument as dt, ListExpensesDocument as ft, ListFocusScoresDocument as pt, ListGeofenceEventsDocument as mt, ListGeofencesDocument as ht, ListInvoicesDocument as gt, ListLocationEntriesDocument as _t, ListMeetingsDocument as vt, ListMyApprovalRequestsDocument as yt, ListPendingApprovalsDocument as bt, ListPomodoroGoalsDocument as xt, ListPomodoroSessionsDocument as St, ListProjectsDocument as Ct, ListResourceAllocationsDocument as wt, ListResourcePlansDocument as Tt, ListRunningTimersDocument as Et, ListTasksDocument as Dt, ListTeamWorkPatternsDocument as Ot, ListTimeCampusCaptureEventsDocument as kt, ListTimeEntriesByDateDocument as At, ListTimeEntriesDocument as jt, ListTopApplicationsDocument as Mt, ListUpcomingMeetingsDocument as Nt, ListUserAllocationsDocument as Pt, ListWorkPatternsDocument as Ft, LocationEntryFieldsFragmentDoc as It, LogLifeTimeEntryDocument as Lt, MeetingActionItemFieldsFragmentDoc as Rt, MeetingFieldsFragmentDoc as zt, MeetingParticipantFieldsFragmentDoc as Bt, MyBalanceTargetsDocument as Vt, MyContextSharingPolicyDocument as Ht, MyDeadTimeRadarDocument as Ut, MyLifeBalanceDocument as Wt, MyLifeGoalsDocument as Gt, MyLifeInWeeksDocument as Kt, MyLifeProfileDocument as qt, MyLifeValuesDocument as Jt, MyPersonalDataSummaryDocument as Yt, MyRecommendationPreferencesDocument as Xt, MyRecommendationsDocument as Zt, MySourceConsentsDocument as Qt, MyTimeWellSpentDocument as $t, PomodoroGoalFieldsFragmentDoc as en, PomodoroSessionFieldsFragmentDoc as tn, PomodoroSettingsFieldsFragmentDoc as nn, ProjectFieldsFragmentDoc as rn, RateMeetingDocument as an, RecategorizeTimeCampusCaptureEventDocument as on, RecommendationFieldsFragmentDoc as sn, RecommendationPreferenceFieldsFragmentDoc as cn, RecordApplicationUsageDocument as ln, RecordFocusScoreDocument as un, RecordGeofenceEventDocument as dn, RecordWorkPatternDocument as fn, RegenerateClientPortalShareTokenDocument as pn, RejectExpenseDocument as mn, RejectRequestDocument as hn, RemoveParticipantDocument as gn, ReorderTasksDocument as _n, RequestRevisionDocument as vn, ResourceAllocationFieldsFragmentDoc as yn, ResourcePlanFieldsFragmentDoc as bn, RevokeSourceConsentDocument as xn, SetBalanceTargetDocument as Sn, SnoozeRecommendationDocument as Cn, SourceConsentFieldsFragmentDoc as wn, StartPomodoroSessionDocument as Tn, StartTimerDocument as En, StopTimerDocument as Dn, SubmitApprovalRequestDocument as On, SubmitExpenseForApprovalDocument as kn, TaskFieldsFragmentDoc as An, TeamWorkPatternEntryFieldsFragmentDoc as jn, TimeEntryFieldsFragmentDoc as Mn, TimelineSegmentFieldsFragmentDoc as Nn, TimelineSummaryFieldsFragmentDoc as Pn, ToggleClientPortalDocument as Fn, ToggleGeofenceDocument as In, UpdateActionItemDocument as Ln, UpdateAllocationDocument as Rn, UpdateApplicationUsageDocument as zn, UpdateClientPortalConfigDocument as Bn, UpdateContextSharingPolicyDocument as Vn, UpdateEmailTimeEntryDocument as Hn, UpdateExpenseDocument as Un, UpdateFocusScoreDocument as Wn, UpdateGeofenceDocument as Gn, UpdateInvoiceStatusDocument as Kn, UpdateLifeGoalDocument as qn, UpdateLifeValueDocument as Jn, UpdateLocationEntryDocument as Yn, UpdateMeetingDocument as Xn, UpdateMyLifeProfileDocument as Zn, UpdateMyRecommendationPreferencesDocument as Qn, UpdateParticipantStatusDocument as $n, UpdatePomodoroGoalDocument as er, UpdatePomodoroSettingsDocument as tr, UpdateProjectDocument as nr, UpdateResourcePlanDocument as rr, UpdateTaskDocument as ir, UpdateTaskStatusDocument as ar, UpdateTimeEntryDocument as or, UpdateWorkPatternDocument as sr, WithdrawRequestDocument as cr, WorkPatternFieldsFragmentDoc as lr, useAcceptRecommendationMutation as ur, useActivateResourcePlanMutation as dr, useAddParticipantMutation as fr, useApproveExpenseMutation as pr, useApproveRequestMutation as mr, useArchiveProjectMutation as hr, useBulkCreateAllocationsMutation as gr, useBulkCreateEmailTimeEntriesMutation as _r, useBulkDeleteTimeEntriesMutation as vr, useCalculateFocusScoreMutation as yr, useCategorizeApplicationMutation as br, useCompleteActionItemMutation as xr, useCompletePomodoroSessionMutation as Sr, useCreateActionItemMutation as Cr, useCreateAllocationMutation as wr, useCreateClientPortalConfigMutation as Tr, useCreateEmailTimeEntryMutation as Er, useCreateExpenseMutation as Dr, useCreateGeofenceMutation as Or, useCreateLifeGoalMutation as kr, useCreateLocationEntryMutation as Ar, useCreateMeetingMutation as jr, useCreatePomodoroGoalMutation as Mr, useCreateProjectMutation as Nr, useCreateResourcePlanMutation as Pr, useCreateTaskMutation as Fr, useCreateTimeEntryMutation as Ir, useDeclareLifeValueMutation as Lr, useDeleteActionItemMutation as Rr, useDeleteAllocationMutation as zr, useDeleteApplicationUsageMutation as Br, useDeleteClientPortalConfigMutation as Vr, useDeleteEmailTimeEntryMutation as Hr, useDeleteExpenseMutation as Ur, useDeleteFocusScoreMutation as Wr, useDeleteGeofenceMutation as Gr, useDeleteInvoiceDraftMutation as Kr, useDeleteLifeGoalMutation as qr, useDeleteLifeValueMutation as Jr, useDeleteLocationEntryMutation as Yr, useDeleteMeetingMutation as Xr, useDeletePomodoroGoalMutation as Zr, useDeleteProjectMutation as Qr, useDeleteResourcePlanMutation as $r, useDeleteTaskMutation as ei, useDeleteTimeCampusCaptureEventMutation as ti, useDeleteTimeEntryMutation as ni, useDeleteWorkPatternMutation as ri, useDismissRecommendationMutation as ii, useDuplicateTimeEntryMutation as ai, useGenerateInvoiceDraftMutation as oi, useGenerateMyRecommendationsMutation as si, useGetActiveLocationEntryLazyQuery as ci, useGetActiveLocationEntryQuery as li, useGetActiveLocationEntrySuspenseQuery as ui, useGetActivePomodoroSessionLazyQuery as di, useGetActivePomodoroSessionQuery as fi, useGetActivePomodoroSessionSuspenseQuery as pi, useGetAppUsageSummaryLazyQuery as mi, useGetAppUsageSummaryQuery as hi, useGetAppUsageSummarySuspenseQuery as gi, useGetApplicationUsageLazyQuery as _i, useGetApplicationUsageQuery as vi, useGetApplicationUsageSuspenseQuery as yi, useGetApprovalRequestLazyQuery as bi, useGetApprovalRequestQuery as xi, useGetApprovalRequestSuspenseQuery as Si, useGetApprovalStatsLazyQuery as Ci, useGetApprovalStatsQuery as wi, useGetApprovalStatsSuspenseQuery as Ti, useGetCapacityOverviewLazyQuery as Ei, useGetCapacityOverviewQuery as Di, useGetCapacityOverviewSuspenseQuery as Oi, useGetClientPortalConfigLazyQuery as ki, useGetClientPortalConfigQuery as Ai, useGetClientPortalConfigSuspenseQuery as ji, useGetClientPortalStatsLazyQuery as Mi, useGetClientPortalStatsQuery as Ni, useGetClientPortalStatsSuspenseQuery as Pi, useGetEmailTimeEntryLazyQuery as Fi, useGetEmailTimeEntryQuery as Ii, useGetEmailTimeEntrySuspenseQuery as Li, useGetEmailTrackingStatsLazyQuery as Ri, useGetEmailTrackingStatsQuery as zi, useGetEmailTrackingStatsSuspenseQuery as Bi, useGetExpenseLazyQuery as Vi, useGetExpenseQuery as Hi, useGetExpenseStatsLazyQuery as Ui, useGetExpenseStatsQuery as Wi, useGetExpenseStatsSuspenseQuery as Gi, useGetExpenseSuspenseQuery as Ki, useGetFocusScoreLazyQuery as qi, useGetFocusScoreQuery as Ji, useGetFocusScoreSummaryLazyQuery as Yi, useGetFocusScoreSummaryQuery as Xi, useGetFocusScoreSummarySuspenseQuery as Zi, useGetFocusScoreSuspenseQuery as Qi, useGetFocusScoreTrendLazyQuery as $i, useGetFocusScoreTrendQuery as ea, useGetFocusScoreTrendSuspenseQuery as ta, useGetGeofenceLazyQuery as na, useGetGeofenceQuery as ra, useGetGeofenceSuspenseQuery as ia, useGetInvoiceHtmlLazyQuery as aa, useGetInvoiceHtmlQuery as oa, useGetInvoiceHtmlSuspenseQuery as sa, useGetInvoiceLazyQuery as ca, useGetInvoicePdfLazyQuery as la, useGetInvoicePdfQuery as ua, useGetInvoicePdfSuspenseQuery as da, useGetInvoiceQuery as fa, useGetInvoiceStatsLazyQuery as pa, useGetInvoiceStatsQuery as ma, useGetInvoiceStatsSuspenseQuery as ha, useGetInvoiceSuspenseQuery as ga, useGetLocationEntryLazyQuery as _a, useGetLocationEntryQuery as va, useGetLocationEntrySuspenseQuery as ya, useGetLocationStatsLazyQuery as ba, useGetLocationStatsQuery as xa, useGetLocationStatsSuspenseQuery as Sa, useGetMeetingLazyQuery as Ca, useGetMeetingQuery as wa, useGetMeetingStatsLazyQuery as Ta, useGetMeetingStatsQuery as Ea, useGetMeetingStatsSuspenseQuery as Da, useGetMeetingSuspenseQuery as Oa, useGetPomodoroSessionLazyQuery as ka, useGetPomodoroSessionQuery as Aa, useGetPomodoroSessionSuspenseQuery as ja, useGetPomodoroSettingsLazyQuery as Ma, useGetPomodoroSettingsQuery as Na, useGetPomodoroSettingsSuspenseQuery as Pa, useGetPomodoroStatsLazyQuery as Fa, useGetPomodoroStatsQuery as Ia, useGetPomodoroStatsSuspenseQuery as La, useGetProjectLazyQuery as Ra, useGetProjectQuery as za, useGetProjectStatsLazyQuery as Ba, useGetProjectStatsQuery as Va, useGetProjectStatsSuspenseQuery as Ha, useGetProjectSuspenseQuery as Ua, useGetResourcePlanLazyQuery as Wa, useGetResourcePlanQuery as Ga, useGetResourcePlanSuspenseQuery as Ka, useGetTaskLazyQuery as qa, useGetTaskQuery as Ja, useGetTaskSuspenseQuery as Ya, useGetTeamWorkPatternSummaryLazyQuery as Xa, useGetTeamWorkPatternSummaryQuery as Za, useGetTeamWorkPatternSummarySuspenseQuery as Qa, useGetTimeCampusTimelineLazyQuery as $a, useGetTimeCampusTimelineQuery as eo, useGetTimeCampusTimelineSuspenseQuery as to, useGetTimeEntryCountLazyQuery as no, useGetTimeEntryCountQuery as ro, useGetTimeEntryCountSuspenseQuery as io, useGetTimeEntryLazyQuery as ao, useGetTimeEntryQuery as oo, useGetTimeEntryStatsLazyQuery as so, useGetTimeEntryStatsQuery as co, useGetTimeEntryStatsSuspenseQuery as lo, useGetTimeEntrySuspenseQuery as uo, useGetTodayFocusScoreLazyQuery as fo, useGetTodayFocusScoreQuery as po, useGetTodayFocusScoreSuspenseQuery as mo, useGetTodayWorkPatternLazyQuery as ho, useGetTodayWorkPatternQuery as go, useGetTodayWorkPatternSuspenseQuery as _o, useGetWorkPatternLazyQuery as vo, useGetWorkPatternQuery as yo, useGetWorkPatternSummaryLazyQuery as bo, useGetWorkPatternSummaryQuery as xo, useGetWorkPatternSummarySuspenseQuery as So, useGetWorkPatternSuspenseQuery as Co, useGrantSourceConsentMutation as wo, useIngestTimeCampusCaptureEventsMutation as To, useInterruptPomodoroSessionMutation as Eo, useLifeTimelineLazyQuery as Do, useLifeTimelineQuery as Oo, useLifeTimelineSuspenseQuery as ko, useListApplicationUsagesLazyQuery as Ao, useListApplicationUsagesQuery as jo, useListApplicationUsagesSuspenseQuery as Mo, useListApprovalRequestsLazyQuery as No, useListApprovalRequestsQuery as Po, useListApprovalRequestsSuspenseQuery as Fo, useListClientPortalConfigsLazyQuery as Io, useListClientPortalConfigsQuery as Lo, useListClientPortalConfigsSuspenseQuery as Ro, useListEmailTimeEntriesLazyQuery as zo, useListEmailTimeEntriesQuery as Bo, useListEmailTimeEntriesSuspenseQuery as Vo, useListExpenseCategoriesLazyQuery as Ho, useListExpenseCategoriesQuery as Uo, useListExpenseCategoriesSuspenseQuery as Wo, useListExpensesLazyQuery as Go, useListExpensesQuery as Ko, useListExpensesSuspenseQuery as qo, useListFocusScoresLazyQuery as Jo, useListFocusScoresQuery as Yo, useListFocusScoresSuspenseQuery as Xo, useListGeofenceEventsLazyQuery as Zo, useListGeofenceEventsQuery as Qo, useListGeofenceEventsSuspenseQuery as $o, useListGeofencesLazyQuery as es, useListGeofencesQuery as ts, useListGeofencesSuspenseQuery as ns, useListInvoicesLazyQuery as rs, useListInvoicesQuery as is, useListInvoicesSuspenseQuery as as, useListLocationEntriesLazyQuery as os, useListLocationEntriesQuery as ss, useListLocationEntriesSuspenseQuery as cs, useListMeetingsLazyQuery as ls, useListMeetingsQuery as us, useListMeetingsSuspenseQuery as ds, useListMyApprovalRequestsLazyQuery as fs, useListMyApprovalRequestsQuery as ps, useListMyApprovalRequestsSuspenseQuery as ms, useListPendingApprovalsLazyQuery as hs, useListPendingApprovalsQuery as gs, useListPendingApprovalsSuspenseQuery as _s, useListPomodoroGoalsLazyQuery as vs, useListPomodoroGoalsQuery as ys, useListPomodoroGoalsSuspenseQuery as bs, useListPomodoroSessionsLazyQuery as xs, useListPomodoroSessionsQuery as Ss, useListPomodoroSessionsSuspenseQuery as Cs, useListProjectsLazyQuery as ws, useListProjectsQuery as Ts, useListProjectsSuspenseQuery as Es, useListResourceAllocationsLazyQuery as Ds, useListResourceAllocationsQuery as Os, useListResourceAllocationsSuspenseQuery as ks, useListResourcePlansLazyQuery as As, useListResourcePlansQuery as js, useListResourcePlansSuspenseQuery as Ms, useListRunningTimersLazyQuery as Ns, useListRunningTimersQuery as Ps, useListRunningTimersSuspenseQuery as Fs, useListTasksLazyQuery as Is, useListTasksQuery as Ls, useListTasksSuspenseQuery as Rs, useListTeamWorkPatternsLazyQuery as zs, useListTeamWorkPatternsQuery as Bs, useListTeamWorkPatternsSuspenseQuery as Vs, useListTimeCampusCaptureEventsLazyQuery as Hs, useListTimeCampusCaptureEventsQuery as Us, useListTimeCampusCaptureEventsSuspenseQuery as Ws, useListTimeEntriesByDateLazyQuery as Gs, useListTimeEntriesByDateQuery as Ks, useListTimeEntriesByDateSuspenseQuery as qs, useListTimeEntriesLazyQuery as Js, useListTimeEntriesQuery as Ys, useListTimeEntriesSuspenseQuery as Xs, useListTopApplicationsLazyQuery as Zs, useListTopApplicationsQuery as Qs, useListTopApplicationsSuspenseQuery as $s, useListUpcomingMeetingsLazyQuery as ec, useListUpcomingMeetingsQuery as tc, useListUpcomingMeetingsSuspenseQuery as nc, useListUserAllocationsLazyQuery as rc, useListUserAllocationsQuery as ic, useListUserAllocationsSuspenseQuery as ac, useListWorkPatternsLazyQuery as oc, useListWorkPatternsQuery as sc, useListWorkPatternsSuspenseQuery as cc, useLogLifeTimeEntryMutation as lc, useMyBalanceTargetsLazyQuery as uc, useMyBalanceTargetsQuery as dc, useMyBalanceTargetsSuspenseQuery as fc, useMyContextSharingPolicyLazyQuery as pc, useMyContextSharingPolicyQuery as mc, useMyContextSharingPolicySuspenseQuery as hc, useMyDeadTimeRadarLazyQuery as gc, useMyDeadTimeRadarQuery as _c, useMyDeadTimeRadarSuspenseQuery as vc, useMyLifeBalanceLazyQuery as yc, useMyLifeBalanceQuery as bc, useMyLifeBalanceSuspenseQuery as xc, useMyLifeGoalsLazyQuery as Sc, useMyLifeGoalsQuery as Cc, useMyLifeGoalsSuspenseQuery as wc, useMyLifeInWeeksLazyQuery as Tc, useMyLifeInWeeksQuery as Ec, useMyLifeInWeeksSuspenseQuery as Dc, useMyLifeProfileLazyQuery as Oc, useMyLifeProfileQuery as kc, useMyLifeProfileSuspenseQuery as Ac, useMyLifeValuesLazyQuery as jc, useMyLifeValuesQuery as Mc, useMyLifeValuesSuspenseQuery as Nc, useMyPersonalDataSummaryLazyQuery as Pc, useMyPersonalDataSummaryQuery as Fc, useMyPersonalDataSummarySuspenseQuery as Ic, useMyRecommendationPreferencesLazyQuery as Lc, useMyRecommendationPreferencesQuery as Rc, useMyRecommendationPreferencesSuspenseQuery as zc, useMyRecommendationsLazyQuery as Bc, useMyRecommendationsQuery as Vc, useMyRecommendationsSuspenseQuery as Hc, useMySourceConsentsLazyQuery as Uc, useMySourceConsentsQuery as Wc, useMySourceConsentsSuspenseQuery as Gc, useMyTimeWellSpentLazyQuery as Kc, useMyTimeWellSpentQuery as qc, useMyTimeWellSpentSuspenseQuery as Jc, useRateMeetingMutation as Yc, useRecategorizeTimeCampusCaptureEventMutation as Xc, useRecordApplicationUsageMutation as Zc, useRecordFocusScoreMutation as Qc, useRecordGeofenceEventMutation as $c, useRecordWorkPatternMutation as el, useRegenerateClientPortalShareTokenMutation as tl, useRejectExpenseMutation as nl, useRejectRequestMutation as rl, useRemoveParticipantMutation as il, useReorderTasksMutation as al, useRequestRevisionMutation as ol, useRevokeSourceConsentMutation as sl, useSetBalanceTargetMutation as cl, useSnoozeRecommendationMutation as ll, useStartPomodoroSessionMutation as ul, useStartTimerMutation as dl, useStopTimerMutation as fl, useSubmitApprovalRequestMutation as pl, useSubmitExpenseForApprovalMutation as ml, useToggleClientPortalMutation as hl, useToggleGeofenceMutation as gl, useUpdateActionItemMutation as _l, useUpdateAllocationMutation as vl, useUpdateApplicationUsageMutation as yl, useUpdateClientPortalConfigMutation as bl, useUpdateContextSharingPolicyMutation as xl, useUpdateEmailTimeEntryMutation as Sl, useUpdateExpenseMutation as Cl, useUpdateFocusScoreMutation as wl, useUpdateGeofenceMutation as Tl, useUpdateInvoiceStatusMutation as El, useUpdateLifeGoalMutation as Dl, useUpdateLifeValueMutation as Ol, useUpdateLocationEntryMutation as kl, useUpdateMeetingMutation as Al, useUpdateMyLifeProfileMutation as jl, useUpdateMyRecommendationPreferencesMutation as Ml, useUpdateParticipantStatusMutation as Nl, useUpdatePomodoroGoalMutation as Pl, useUpdatePomodoroSettingsMutation as Fl, useUpdateProjectMutation as Il, useUpdateResourcePlanMutation as Ll, useUpdateTaskMutation as Rl, useUpdateTaskStatusMutation as zl, useUpdateTimeEntryMutation as Bl, useUpdateWorkPatternMutation as Vl, useWithdrawRequestMutation as Hl } from "../generated/wspace-operations.js";
|
|
3
|
+
import { TimeCampusRoot as Ul } from "./TimeCampusRoot.js";
|
|
4
|
+
import { AdminRoot as Wl } from "./AdminRoot.js";
|
|
5
|
+
import { AdminRoutes as Gl } from "./AdminRoutes.js";
|
|
6
|
+
import { useTimeCampusStore as Kl } from "./store/timecampusStore.js";
|
|
7
|
+
import { useSandboxAssistantTransport as ql } from "../services/createSandboxAssistantTransport.js";
|
|
8
|
+
export { n as AcceptRecommendationDocument, r as ActivateResourcePlanDocument, i as AddParticipantDocument, Wl as AdminRoot, Gl as AdminRoutes, a as ApplicationUsageFieldsFragmentDoc, o as ApprovalRequestFieldsFragmentDoc, s as ApproveExpenseDocument, c as ApproveRequestDocument, l as ArchiveProjectDocument, u as BalanceTargetFieldsFragmentDoc, d as BulkCreateAllocationsDocument, f as BulkCreateEmailTimeEntriesDocument, p as BulkDeleteTimeEntriesDocument, m as CalculateFocusScoreDocument, h as CaptureEventFieldsFragmentDoc, g as CategorizeApplicationDocument, _ as ClientPortalFieldsFragmentDoc, v as CompleteActionItemDocument, y as CompletePomodoroSessionDocument, b as ContextSharingPolicyFieldsFragmentDoc, x as CreateActionItemDocument, S as CreateAllocationDocument, C as CreateClientPortalConfigDocument, w as CreateEmailTimeEntryDocument, T as CreateExpenseDocument, E as CreateGeofenceDocument, D as CreateLifeGoalDocument, O as CreateLocationEntryDocument, k as CreateMeetingDocument, A as CreatePomodoroGoalDocument, j as CreateProjectDocument, M as CreateResourcePlanDocument, N as CreateTaskDocument, P as CreateTimeEntryDocument, F as DeclareLifeValueDocument, I as DeleteActionItemDocument, L as DeleteAllocationDocument, R as DeleteApplicationUsageDocument, z as DeleteClientPortalConfigDocument, B as DeleteEmailTimeEntryDocument, V as DeleteExpenseDocument, H as DeleteFocusScoreDocument, U as DeleteGeofenceDocument, W as DeleteInvoiceDraftDocument, G as DeleteLifeGoalDocument, K as DeleteLifeValueDocument, q as DeleteLocationEntryDocument, J as DeleteMeetingDocument, Y as DeletePomodoroGoalDocument, X as DeleteProjectDocument, Z as DeleteResourcePlanDocument, Q as DeleteTaskDocument, $ as DeleteTimeCampusCaptureEventDocument, ee as DeleteTimeEntryDocument, te as DeleteWorkPatternDocument, ne as DismissRecommendationDocument, re as DuplicateTimeEntryDocument, ie as EmailTimeEntryFieldsFragmentDoc, ae as ExpenseFieldsFragmentDoc, oe as FocusScoreFieldsFragmentDoc, se as GenerateInvoiceDraftDocument, ce as GenerateMyRecommendationsDocument, le as GeofenceEventFieldsFragmentDoc, ue as GeofenceFieldsFragmentDoc, de as GetActiveLocationEntryDocument, fe as GetActivePomodoroSessionDocument, pe as GetAppUsageSummaryDocument, me as GetApplicationUsageDocument, he as GetApprovalRequestDocument, ge as GetApprovalStatsDocument, _e as GetCapacityOverviewDocument, ve as GetClientPortalConfigDocument, ye as GetClientPortalStatsDocument, be as GetEmailTimeEntryDocument, xe as GetEmailTrackingStatsDocument, Se as GetExpenseDocument, Ce as GetExpenseStatsDocument, we as GetFocusScoreDocument, Te as GetFocusScoreSummaryDocument, Ee as GetFocusScoreTrendDocument, De as GetGeofenceDocument, Oe as GetInvoiceDocument, ke as GetInvoiceHtmlDocument, Ae as GetInvoicePdfDocument, je as GetInvoiceStatsDocument, Me as GetLocationEntryDocument, Ne as GetLocationStatsDocument, Pe as GetMeetingDocument, Fe as GetMeetingStatsDocument, Ie as GetPomodoroSessionDocument, Le as GetPomodoroSettingsDocument, Re as GetPomodoroStatsDocument, ze as GetProjectDocument, Be as GetProjectStatsDocument, Ve as GetResourcePlanDocument, He as GetTaskDocument, Ue as GetTeamWorkPatternSummaryDocument, We as GetTimeCampusTimelineDocument, Ge as GetTimeEntryCountDocument, Ke as GetTimeEntryDocument, qe as GetTimeEntryStatsDocument, Je as GetTodayFocusScoreDocument, Ye as GetTodayWorkPatternDocument, Xe as GetWorkPatternDocument, Ze as GetWorkPatternSummaryDocument, Qe as GrantSourceConsentDocument, $e as IngestTimeCampusCaptureEventsDocument, et as InterruptPomodoroSessionDocument, tt as InvoiceFieldsFragmentDoc, nt as InvoiceLineItemFieldsFragmentDoc, rt as LifeGoalFieldsFragmentDoc, it as LifeProfileFieldsFragmentDoc, at as LifeTimelineDocument, ot as LifeValueFieldsFragmentDoc, st as ListApplicationUsagesDocument, ct as ListApprovalRequestsDocument, lt as ListClientPortalConfigsDocument, ut as ListEmailTimeEntriesDocument, dt as ListExpenseCategoriesDocument, ft as ListExpensesDocument, pt as ListFocusScoresDocument, mt as ListGeofenceEventsDocument, ht as ListGeofencesDocument, gt as ListInvoicesDocument, _t as ListLocationEntriesDocument, vt as ListMeetingsDocument, yt as ListMyApprovalRequestsDocument, bt as ListPendingApprovalsDocument, xt as ListPomodoroGoalsDocument, St as ListPomodoroSessionsDocument, Ct as ListProjectsDocument, wt as ListResourceAllocationsDocument, Tt as ListResourcePlansDocument, Et as ListRunningTimersDocument, Dt as ListTasksDocument, Ot as ListTeamWorkPatternsDocument, kt as ListTimeCampusCaptureEventsDocument, At as ListTimeEntriesByDateDocument, jt as ListTimeEntriesDocument, Mt as ListTopApplicationsDocument, Nt as ListUpcomingMeetingsDocument, Pt as ListUserAllocationsDocument, Ft as ListWorkPatternsDocument, It as LocationEntryFieldsFragmentDoc, Lt as LogLifeTimeEntryDocument, Rt as MeetingActionItemFieldsFragmentDoc, zt as MeetingFieldsFragmentDoc, Bt as MeetingParticipantFieldsFragmentDoc, Vt as MyBalanceTargetsDocument, Ht as MyContextSharingPolicyDocument, Ut as MyDeadTimeRadarDocument, Wt as MyLifeBalanceDocument, Gt as MyLifeGoalsDocument, Kt as MyLifeInWeeksDocument, qt as MyLifeProfileDocument, Jt as MyLifeValuesDocument, Yt as MyPersonalDataSummaryDocument, Xt as MyRecommendationPreferencesDocument, Zt as MyRecommendationsDocument, Qt as MySourceConsentsDocument, $t as MyTimeWellSpentDocument, en as PomodoroGoalFieldsFragmentDoc, tn as PomodoroSessionFieldsFragmentDoc, nn as PomodoroSettingsFieldsFragmentDoc, rn as ProjectFieldsFragmentDoc, an as RateMeetingDocument, on as RecategorizeTimeCampusCaptureEventDocument, sn as RecommendationFieldsFragmentDoc, cn as RecommendationPreferenceFieldsFragmentDoc, ln as RecordApplicationUsageDocument, un as RecordFocusScoreDocument, dn as RecordGeofenceEventDocument, fn as RecordWorkPatternDocument, pn as RegenerateClientPortalShareTokenDocument, mn as RejectExpenseDocument, hn as RejectRequestDocument, gn as RemoveParticipantDocument, _n as ReorderTasksDocument, vn as RequestRevisionDocument, yn as ResourceAllocationFieldsFragmentDoc, bn as ResourcePlanFieldsFragmentDoc, xn as RevokeSourceConsentDocument, Sn as SetBalanceTargetDocument, Cn as SnoozeRecommendationDocument, wn as SourceConsentFieldsFragmentDoc, Tn as StartPomodoroSessionDocument, En as StartTimerDocument, Dn as StopTimerDocument, On as SubmitApprovalRequestDocument, kn as SubmitExpenseForApprovalDocument, An as TaskFieldsFragmentDoc, jn as TeamWorkPatternEntryFieldsFragmentDoc, Ul as TimeCampusRoot, Mn as TimeEntryFieldsFragmentDoc, Nn as TimelineSegmentFieldsFragmentDoc, Pn as TimelineSummaryFieldsFragmentDoc, Fn as ToggleClientPortalDocument, In as ToggleGeofenceDocument, Ln as UpdateActionItemDocument, Rn as UpdateAllocationDocument, zn as UpdateApplicationUsageDocument, Bn as UpdateClientPortalConfigDocument, Vn as UpdateContextSharingPolicyDocument, Hn as UpdateEmailTimeEntryDocument, Un as UpdateExpenseDocument, Wn as UpdateFocusScoreDocument, Gn as UpdateGeofenceDocument, Kn as UpdateInvoiceStatusDocument, qn as UpdateLifeGoalDocument, Jn as UpdateLifeValueDocument, Yn as UpdateLocationEntryDocument, Xn as UpdateMeetingDocument, Zn as UpdateMyLifeProfileDocument, Qn as UpdateMyRecommendationPreferencesDocument, $n as UpdateParticipantStatusDocument, er as UpdatePomodoroGoalDocument, tr as UpdatePomodoroSettingsDocument, nr as UpdateProjectDocument, rr as UpdateResourcePlanDocument, ir as UpdateTaskDocument, ar as UpdateTaskStatusDocument, or as UpdateTimeEntryDocument, sr as UpdateWorkPatternDocument, cr as WithdrawRequestDocument, lr as WorkPatternFieldsFragmentDoc, ur as useAcceptRecommendationMutation, dr as useActivateResourcePlanMutation, fr as useAddParticipantMutation, pr as useApproveExpenseMutation, mr as useApproveRequestMutation, hr as useArchiveProjectMutation, gr as useBulkCreateAllocationsMutation, _r as useBulkCreateEmailTimeEntriesMutation, vr as useBulkDeleteTimeEntriesMutation, yr as useCalculateFocusScoreMutation, br as useCategorizeApplicationMutation, xr as useCompleteActionItemMutation, Sr as useCompletePomodoroSessionMutation, Cr as useCreateActionItemMutation, wr as useCreateAllocationMutation, Tr as useCreateClientPortalConfigMutation, Er as useCreateEmailTimeEntryMutation, Dr as useCreateExpenseMutation, Or as useCreateGeofenceMutation, kr as useCreateLifeGoalMutation, Ar as useCreateLocationEntryMutation, jr as useCreateMeetingMutation, Mr as useCreatePomodoroGoalMutation, Nr as useCreateProjectMutation, Pr as useCreateResourcePlanMutation, Fr as useCreateTaskMutation, Ir as useCreateTimeEntryMutation, Lr as useDeclareLifeValueMutation, Rr as useDeleteActionItemMutation, zr as useDeleteAllocationMutation, Br as useDeleteApplicationUsageMutation, Vr as useDeleteClientPortalConfigMutation, Hr as useDeleteEmailTimeEntryMutation, Ur as useDeleteExpenseMutation, Wr as useDeleteFocusScoreMutation, Gr as useDeleteGeofenceMutation, Kr as useDeleteInvoiceDraftMutation, qr as useDeleteLifeGoalMutation, Jr as useDeleteLifeValueMutation, Yr as useDeleteLocationEntryMutation, Xr as useDeleteMeetingMutation, Zr as useDeletePomodoroGoalMutation, Qr as useDeleteProjectMutation, $r as useDeleteResourcePlanMutation, ei as useDeleteTaskMutation, ti as useDeleteTimeCampusCaptureEventMutation, ni as useDeleteTimeEntryMutation, ri as useDeleteWorkPatternMutation, ii as useDismissRecommendationMutation, ai as useDuplicateTimeEntryMutation, oi as useGenerateInvoiceDraftMutation, si as useGenerateMyRecommendationsMutation, ci as useGetActiveLocationEntryLazyQuery, li as useGetActiveLocationEntryQuery, ui as useGetActiveLocationEntrySuspenseQuery, di as useGetActivePomodoroSessionLazyQuery, fi as useGetActivePomodoroSessionQuery, pi as useGetActivePomodoroSessionSuspenseQuery, mi as useGetAppUsageSummaryLazyQuery, hi as useGetAppUsageSummaryQuery, gi as useGetAppUsageSummarySuspenseQuery, _i as useGetApplicationUsageLazyQuery, vi as useGetApplicationUsageQuery, yi as useGetApplicationUsageSuspenseQuery, bi as useGetApprovalRequestLazyQuery, xi as useGetApprovalRequestQuery, Si as useGetApprovalRequestSuspenseQuery, Ci as useGetApprovalStatsLazyQuery, wi as useGetApprovalStatsQuery, Ti as useGetApprovalStatsSuspenseQuery, Ei as useGetCapacityOverviewLazyQuery, Di as useGetCapacityOverviewQuery, Oi as useGetCapacityOverviewSuspenseQuery, ki as useGetClientPortalConfigLazyQuery, Ai as useGetClientPortalConfigQuery, ji as useGetClientPortalConfigSuspenseQuery, Mi as useGetClientPortalStatsLazyQuery, Ni as useGetClientPortalStatsQuery, Pi as useGetClientPortalStatsSuspenseQuery, Fi as useGetEmailTimeEntryLazyQuery, Ii as useGetEmailTimeEntryQuery, Li as useGetEmailTimeEntrySuspenseQuery, Ri as useGetEmailTrackingStatsLazyQuery, zi as useGetEmailTrackingStatsQuery, Bi as useGetEmailTrackingStatsSuspenseQuery, Vi as useGetExpenseLazyQuery, Hi as useGetExpenseQuery, Ui as useGetExpenseStatsLazyQuery, Wi as useGetExpenseStatsQuery, Gi as useGetExpenseStatsSuspenseQuery, Ki as useGetExpenseSuspenseQuery, qi as useGetFocusScoreLazyQuery, Ji as useGetFocusScoreQuery, Yi as useGetFocusScoreSummaryLazyQuery, Xi as useGetFocusScoreSummaryQuery, Zi as useGetFocusScoreSummarySuspenseQuery, Qi as useGetFocusScoreSuspenseQuery, $i as useGetFocusScoreTrendLazyQuery, ea as useGetFocusScoreTrendQuery, ta as useGetFocusScoreTrendSuspenseQuery, na as useGetGeofenceLazyQuery, ra as useGetGeofenceQuery, ia as useGetGeofenceSuspenseQuery, aa as useGetInvoiceHtmlLazyQuery, oa as useGetInvoiceHtmlQuery, sa as useGetInvoiceHtmlSuspenseQuery, ca as useGetInvoiceLazyQuery, la as useGetInvoicePdfLazyQuery, ua as useGetInvoicePdfQuery, da as useGetInvoicePdfSuspenseQuery, fa as useGetInvoiceQuery, pa as useGetInvoiceStatsLazyQuery, ma as useGetInvoiceStatsQuery, ha as useGetInvoiceStatsSuspenseQuery, ga as useGetInvoiceSuspenseQuery, _a as useGetLocationEntryLazyQuery, va as useGetLocationEntryQuery, ya as useGetLocationEntrySuspenseQuery, ba as useGetLocationStatsLazyQuery, xa as useGetLocationStatsQuery, Sa as useGetLocationStatsSuspenseQuery, Ca as useGetMeetingLazyQuery, wa as useGetMeetingQuery, Ta as useGetMeetingStatsLazyQuery, Ea as useGetMeetingStatsQuery, Da as useGetMeetingStatsSuspenseQuery, Oa as useGetMeetingSuspenseQuery, ka as useGetPomodoroSessionLazyQuery, Aa as useGetPomodoroSessionQuery, ja as useGetPomodoroSessionSuspenseQuery, Ma as useGetPomodoroSettingsLazyQuery, Na as useGetPomodoroSettingsQuery, Pa as useGetPomodoroSettingsSuspenseQuery, Fa as useGetPomodoroStatsLazyQuery, Ia as useGetPomodoroStatsQuery, La as useGetPomodoroStatsSuspenseQuery, Ra as useGetProjectLazyQuery, za as useGetProjectQuery, Ba as useGetProjectStatsLazyQuery, Va as useGetProjectStatsQuery, Ha as useGetProjectStatsSuspenseQuery, Ua as useGetProjectSuspenseQuery, Wa as useGetResourcePlanLazyQuery, Ga as useGetResourcePlanQuery, Ka as useGetResourcePlanSuspenseQuery, qa as useGetTaskLazyQuery, Ja as useGetTaskQuery, Ya as useGetTaskSuspenseQuery, Xa as useGetTeamWorkPatternSummaryLazyQuery, Za as useGetTeamWorkPatternSummaryQuery, Qa as useGetTeamWorkPatternSummarySuspenseQuery, $a as useGetTimeCampusTimelineLazyQuery, eo as useGetTimeCampusTimelineQuery, to as useGetTimeCampusTimelineSuspenseQuery, no as useGetTimeEntryCountLazyQuery, ro as useGetTimeEntryCountQuery, io as useGetTimeEntryCountSuspenseQuery, ao as useGetTimeEntryLazyQuery, oo as useGetTimeEntryQuery, so as useGetTimeEntryStatsLazyQuery, co as useGetTimeEntryStatsQuery, lo as useGetTimeEntryStatsSuspenseQuery, uo as useGetTimeEntrySuspenseQuery, fo as useGetTodayFocusScoreLazyQuery, po as useGetTodayFocusScoreQuery, mo as useGetTodayFocusScoreSuspenseQuery, ho as useGetTodayWorkPatternLazyQuery, go as useGetTodayWorkPatternQuery, _o as useGetTodayWorkPatternSuspenseQuery, vo as useGetWorkPatternLazyQuery, yo as useGetWorkPatternQuery, bo as useGetWorkPatternSummaryLazyQuery, xo as useGetWorkPatternSummaryQuery, So as useGetWorkPatternSummarySuspenseQuery, Co as useGetWorkPatternSuspenseQuery, wo as useGrantSourceConsentMutation, To as useIngestTimeCampusCaptureEventsMutation, Eo as useInterruptPomodoroSessionMutation, Do as useLifeTimelineLazyQuery, Oo as useLifeTimelineQuery, ko as useLifeTimelineSuspenseQuery, Ao as useListApplicationUsagesLazyQuery, jo as useListApplicationUsagesQuery, Mo as useListApplicationUsagesSuspenseQuery, No as useListApprovalRequestsLazyQuery, Po as useListApprovalRequestsQuery, Fo as useListApprovalRequestsSuspenseQuery, Io as useListClientPortalConfigsLazyQuery, Lo as useListClientPortalConfigsQuery, Ro as useListClientPortalConfigsSuspenseQuery, zo as useListEmailTimeEntriesLazyQuery, Bo as useListEmailTimeEntriesQuery, Vo as useListEmailTimeEntriesSuspenseQuery, Ho as useListExpenseCategoriesLazyQuery, Uo as useListExpenseCategoriesQuery, Wo as useListExpenseCategoriesSuspenseQuery, Go as useListExpensesLazyQuery, Ko as useListExpensesQuery, qo as useListExpensesSuspenseQuery, Jo as useListFocusScoresLazyQuery, Yo as useListFocusScoresQuery, Xo as useListFocusScoresSuspenseQuery, Zo as useListGeofenceEventsLazyQuery, Qo as useListGeofenceEventsQuery, $o as useListGeofenceEventsSuspenseQuery, es as useListGeofencesLazyQuery, ts as useListGeofencesQuery, ns as useListGeofencesSuspenseQuery, rs as useListInvoicesLazyQuery, is as useListInvoicesQuery, as as useListInvoicesSuspenseQuery, os as useListLocationEntriesLazyQuery, ss as useListLocationEntriesQuery, cs as useListLocationEntriesSuspenseQuery, ls as useListMeetingsLazyQuery, us as useListMeetingsQuery, ds as useListMeetingsSuspenseQuery, fs as useListMyApprovalRequestsLazyQuery, ps as useListMyApprovalRequestsQuery, ms as useListMyApprovalRequestsSuspenseQuery, hs as useListPendingApprovalsLazyQuery, gs as useListPendingApprovalsQuery, _s as useListPendingApprovalsSuspenseQuery, vs as useListPomodoroGoalsLazyQuery, ys as useListPomodoroGoalsQuery, bs as useListPomodoroGoalsSuspenseQuery, xs as useListPomodoroSessionsLazyQuery, Ss as useListPomodoroSessionsQuery, Cs as useListPomodoroSessionsSuspenseQuery, ws as useListProjectsLazyQuery, Ts as useListProjectsQuery, Es as useListProjectsSuspenseQuery, Ds as useListResourceAllocationsLazyQuery, Os as useListResourceAllocationsQuery, ks as useListResourceAllocationsSuspenseQuery, As as useListResourcePlansLazyQuery, js as useListResourcePlansQuery, Ms as useListResourcePlansSuspenseQuery, Ns as useListRunningTimersLazyQuery, Ps as useListRunningTimersQuery, Fs as useListRunningTimersSuspenseQuery, Is as useListTasksLazyQuery, Ls as useListTasksQuery, Rs as useListTasksSuspenseQuery, zs as useListTeamWorkPatternsLazyQuery, Bs as useListTeamWorkPatternsQuery, Vs as useListTeamWorkPatternsSuspenseQuery, Hs as useListTimeCampusCaptureEventsLazyQuery, Us as useListTimeCampusCaptureEventsQuery, Ws as useListTimeCampusCaptureEventsSuspenseQuery, Gs as useListTimeEntriesByDateLazyQuery, Ks as useListTimeEntriesByDateQuery, qs as useListTimeEntriesByDateSuspenseQuery, Js as useListTimeEntriesLazyQuery, Ys as useListTimeEntriesQuery, Xs as useListTimeEntriesSuspenseQuery, Zs as useListTopApplicationsLazyQuery, Qs as useListTopApplicationsQuery, $s as useListTopApplicationsSuspenseQuery, ec as useListUpcomingMeetingsLazyQuery, tc as useListUpcomingMeetingsQuery, nc as useListUpcomingMeetingsSuspenseQuery, rc as useListUserAllocationsLazyQuery, ic as useListUserAllocationsQuery, ac as useListUserAllocationsSuspenseQuery, oc as useListWorkPatternsLazyQuery, sc as useListWorkPatternsQuery, cc as useListWorkPatternsSuspenseQuery, lc as useLogLifeTimeEntryMutation, uc as useMyBalanceTargetsLazyQuery, dc as useMyBalanceTargetsQuery, fc as useMyBalanceTargetsSuspenseQuery, pc as useMyContextSharingPolicyLazyQuery, mc as useMyContextSharingPolicyQuery, hc as useMyContextSharingPolicySuspenseQuery, gc as useMyDeadTimeRadarLazyQuery, _c as useMyDeadTimeRadarQuery, vc as useMyDeadTimeRadarSuspenseQuery, yc as useMyLifeBalanceLazyQuery, bc as useMyLifeBalanceQuery, xc as useMyLifeBalanceSuspenseQuery, Sc as useMyLifeGoalsLazyQuery, Cc as useMyLifeGoalsQuery, wc as useMyLifeGoalsSuspenseQuery, Tc as useMyLifeInWeeksLazyQuery, Ec as useMyLifeInWeeksQuery, Dc as useMyLifeInWeeksSuspenseQuery, Oc as useMyLifeProfileLazyQuery, kc as useMyLifeProfileQuery, Ac as useMyLifeProfileSuspenseQuery, jc as useMyLifeValuesLazyQuery, Mc as useMyLifeValuesQuery, Nc as useMyLifeValuesSuspenseQuery, Pc as useMyPersonalDataSummaryLazyQuery, Fc as useMyPersonalDataSummaryQuery, Ic as useMyPersonalDataSummarySuspenseQuery, Lc as useMyRecommendationPreferencesLazyQuery, Rc as useMyRecommendationPreferencesQuery, zc as useMyRecommendationPreferencesSuspenseQuery, Bc as useMyRecommendationsLazyQuery, Vc as useMyRecommendationsQuery, Hc as useMyRecommendationsSuspenseQuery, Uc as useMySourceConsentsLazyQuery, Wc as useMySourceConsentsQuery, Gc as useMySourceConsentsSuspenseQuery, Kc as useMyTimeWellSpentLazyQuery, qc as useMyTimeWellSpentQuery, Jc as useMyTimeWellSpentSuspenseQuery, Yc as useRateMeetingMutation, Xc as useRecategorizeTimeCampusCaptureEventMutation, Zc as useRecordApplicationUsageMutation, Qc as useRecordFocusScoreMutation, $c as useRecordGeofenceEventMutation, el as useRecordWorkPatternMutation, tl as useRegenerateClientPortalShareTokenMutation, nl as useRejectExpenseMutation, rl as useRejectRequestMutation, il as useRemoveParticipantMutation, al as useReorderTasksMutation, ol as useRequestRevisionMutation, sl as useRevokeSourceConsentMutation, ql as useSandboxAssistantTransport, cl as useSetBalanceTargetMutation, ll as useSnoozeRecommendationMutation, ul as useStartPomodoroSessionMutation, dl as useStartTimerMutation, fl as useStopTimerMutation, pl as useSubmitApprovalRequestMutation, ml as useSubmitExpenseForApprovalMutation, e as useTimeCampus, t as useTimeCampusNavigate, Kl as useTimeCampusStore, hl as useToggleClientPortalMutation, gl as useToggleGeofenceMutation, _l as useUpdateActionItemMutation, vl as useUpdateAllocationMutation, yl as useUpdateApplicationUsageMutation, bl as useUpdateClientPortalConfigMutation, xl as useUpdateContextSharingPolicyMutation, Sl as useUpdateEmailTimeEntryMutation, Cl as useUpdateExpenseMutation, wl as useUpdateFocusScoreMutation, Tl as useUpdateGeofenceMutation, El as useUpdateInvoiceStatusMutation, Dl as useUpdateLifeGoalMutation, Ol as useUpdateLifeValueMutation, kl as useUpdateLocationEntryMutation, Al as useUpdateMeetingMutation, jl as useUpdateMyLifeProfileMutation, Ml as useUpdateMyRecommendationPreferencesMutation, Nl as useUpdateParticipantStatusMutation, Pl as useUpdatePomodoroGoalMutation, Fl as useUpdatePomodoroSettingsMutation, Il as useUpdateProjectMutation, Ll as useUpdateResourcePlanMutation, Rl as useUpdateTaskMutation, zl as useUpdateTaskStatusMutation, Bl as useUpdateTimeEntryMutation, Vl as useUpdateWorkPatternMutation, Hl as useWithdrawRequestMutation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/timecampus/pages/HomePage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport {\n Clock,\n FolderOpen,\n Users,\n TrendingUp,\n CheckCircle,\n BarChart3,\n Play,\n ArrowRight,\n} from \"lucide-react\";\nimport {\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n CTAOverflowMenu,\n} from \"@burdenoff/fe-libs/ui\";\nimport { StatCard } from \"../components/StatCard\";\nimport { LoadingSkeleton } from \"../components/LoadingSkeleton\";\nimport { cn, formatHours } from \"../utils/helpers\";\nimport { useTimeCampusNavigate } from \"../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\n\nexport const HomePage: FC = () => {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const navigate = useTimeCampusNavigate();\n\n const { data: statsData, loading: statsLoading } =\n useGetTimeEntryStatsQuery();\n const { data: entriesData, loading: entriesLoading } =\n useListTimeEntriesQuery({\n variables: { pagination: { limit: 4 } },\n });\n\n const stats = statsData?.timeEntryStats;\n const recentEntries = entriesData?.timeEntries?.items ?? [];\n\n const headerActions = (\n <CTAOverflowMenu\n primary={{\n label: t(\"timecampus.home.actions.startTimer\", \"Start Timer\"),\n onSelect: () => navigate(\"/time/timer\"),\n icon: <Play className=\"h-4 w-4\" />,\n }}\n actions={[\n {\n label: t(\n \"timecampus.home.quickActions.viewProjects.label\",\n \"View Projects\",\n ),\n onSelect: () => navigate(\"/projects\"),\n icon: <FolderOpen className=\"h-4 w-4\" />,\n },\n {\n label: t(\"timecampus.home.quickActions.reports.label\", \"Reports\"),\n onSelect: () => navigate(\"/reports\"),\n icon: <BarChart3 className=\"h-4 w-4\" />,\n },\n ]}\n />\n );\n\n const renderHeader = () => (\n <div className=\"relative overflow-hidden rounded-2xl border border-border-seam bg-gloss-card p-5 sm:p-6\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>\n {t(\"timecampus.home.title\", \"Dashboard\")}\n </GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t(\n \"timecampus.home.description\",\n \"Overview of your time tracking and productivity\",\n )}\n </p>\n </div>\n {headerActions}\n </div>\n </div>\n );\n\n if (statsLoading && entriesLoading) {\n return (\n <div className=\"min-h-full space-y-6 p-4 sm:p-6\">\n {renderHeader()}\n <LoadingSkeleton variant=\"card\" count={4} />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full space-y-6 p-4 sm:p-6\">\n {renderHeader()}\n\n {/* Hero metric + supporting metrics */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n <StatCard\n featured\n title={t(\"timecampus.home.stats.today\", \"Today\")}\n value={formatHours(stats?.totalHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{\n value: 12.5,\n label: t(\"timecampus.home.stats.vsYesterday\", \"vs yesterday\"),\n }}\n />\n <StatCard\n title={t(\"timecampus.home.stats.billable\", \"Billable\")}\n value={formatHours(stats?.billableHours ?? 0)}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n description={`${stats?.totalEntries ?? 0} ${t(\"timecampus.home.stats.entries\", \"entries\")}`}\n />\n <StatCard\n title={t(\"timecampus.home.stats.activeTimers\", \"Active Timers\")}\n value={stats?.activeTimers ?? 0}\n icon={<FolderOpen className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.home.stats.currentlyRunning\",\n \"Currently running\",\n )}\n />\n <StatCard\n title={t(\"timecampus.home.stats.totalEntries\", \"Entries\")}\n value={stats?.totalEntries ?? 0}\n icon={<BarChart3 className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.home.stats.totalEntriesDescription\",\n \"Total time entries\",\n )}\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Recent Time Entries */}\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam p-6 lg:col-span-2\"\n >\n <div className=\"mb-4 flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\n \"timecampus.home.recentEntries.title\",\n \"Recent Time Entries\",\n )}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.recentEntries.description\",\n \"Your latest tracked activities\",\n )}\n </p>\n </div>\n <button\n onClick={() => navigate(\"/time/entries\")}\n className=\"inline-flex min-h-[2.75rem] items-center gap-1 rounded-md px-2 text-xs font-medium text-primary transition-colors hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border\"\n >\n {t(\"timecampus.home.recentEntries.viewAll\", \"View all\")}{\" \"}\n <ArrowRight className=\"h-3 w-3\" />\n </button>\n </div>\n {entriesLoading ? (\n <LoadingSkeleton variant=\"list\" count={4} />\n ) : (\n <div className=\"flex flex-col gap-3\">\n {recentEntries.map((entry: TimeEntryFieldsFragment) => (\n <div\n key={entry.id}\n className=\"flex items-center justify-between rounded-lg border border-border-seam p-3 transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {entry.project?.name ??\n t(\n \"timecampus.home.recentEntries.noProject\",\n \"No Project\",\n )}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {entry.description ??\n t(\n \"timecampus.home.recentEntries.noDescription\",\n \"No description\",\n )}\n </p>\n </div>\n <div className=\"ml-4 text-right\">\n <p className=\"font-mono text-sm font-medium tabular-nums text-text-primary\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </p>\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium\",\n entry.isRunning\n ? \"bg-status-info-bg text-status-info-text\"\n : \"bg-status-success-bg text-status-success-text\",\n )}\n >\n {entry.isRunning && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-status-info-text motion-safe:animate-vc-glow-pulse\" />\n )}\n {entry.isRunning\n ? t(\n \"timecampus.home.recentEntries.status.running\",\n \"running\",\n )\n : t(\n \"timecampus.home.recentEntries.status.completed\",\n \"completed\",\n )}\n </span>\n </div>\n </div>\n ))}\n {recentEntries.length === 0 && (\n <p className=\"py-4 text-center text-sm text-text-secondary\">\n {t(\n \"timecampus.home.recentEntries.empty\",\n \"No time entries yet\",\n )}\n </p>\n )}\n </div>\n )}\n </GlassCard>\n\n {/* Quick Summary — the one emphasis zone */}\n <EmphasisPanel className=\"p-6\">\n <div className=\"mb-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\"timecampus.home.summary.title\", \"Quick Summary\")}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.summary.description\",\n \"Time tracking overview\",\n )}\n </p>\n </div>\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.totalHours\", \"Total Hours\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {formatHours(stats?.totalHours ?? 0)}\n </p>\n </div>\n <Clock className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.billableHours\", \"Billable Hours\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {formatHours(stats?.billableHours ?? 0)}\n </p>\n </div>\n <TrendingUp className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.activeTimers\", \"Active Timers\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {stats?.activeTimers ?? 0}\n </p>\n </div>\n <Users className=\"h-5 w-5 text-text-secondary\" />\n </div>\n </div>\n </EmphasisPanel>\n </div>\n\n {/* Quick Actions */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <div className=\"mb-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\"timecampus.home.quickActions.title\", \"Quick Actions\")}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.quickActions.description\",\n \"Frequently used features\",\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6\">\n {[\n {\n label: t(\n \"timecampus.home.quickActions.startTimer.label\",\n \"Start Timer\",\n ),\n icon: Play,\n route: \"/time/timer\",\n description: t(\n \"timecampus.home.quickActions.startTimer.description\",\n \"Track your time\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.viewProjects.label\",\n \"View Projects\",\n ),\n icon: FolderOpen,\n route: \"/projects\",\n description: t(\n \"timecampus.home.quickActions.viewProjects.description\",\n \"Manage projects\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.timeEntries.label\",\n \"Time Entries\",\n ),\n icon: Clock,\n route: \"/time/entries\",\n description: t(\n \"timecampus.home.quickActions.timeEntries.description\",\n \"View all entries\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.teamActivity.label\",\n \"Team Activity\",\n ),\n icon: Users,\n route: \"/team-activity\",\n description: t(\n \"timecampus.home.quickActions.teamActivity.description\",\n \"See team status\",\n ),\n },\n {\n label: t(\"timecampus.home.quickActions.reports.label\", \"Reports\"),\n icon: BarChart3,\n route: \"/reports\",\n description: t(\n \"timecampus.home.quickActions.reports.description\",\n \"Generate reports\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.approvals.label\",\n \"Approvals\",\n ),\n icon: CheckCircle,\n route: \"/time-approval\",\n description: t(\n \"timecampus.home.quickActions.approvals.description\",\n \"Review timesheets\",\n ),\n },\n ].map(({ label, icon: Icon, description, route }) => (\n <button\n key={label}\n onClick={() => navigate(route)}\n className=\"flex min-h-[2.75rem] flex-col items-center gap-2 rounded-lg border border-border-seam bg-bg-surface p-4 text-center transition-colors hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border\"\n >\n <div className=\"rounded-full bg-action-primary-bg/10 p-3\">\n <Icon className=\"h-5 w-5 text-primary\" />\n </div>\n <span className=\"text-sm font-medium text-text-primary\">\n {label}\n </span>\n <span className=\"text-xs text-text-secondary\">{description}</span>\n </button>\n ))}\n </div>\n </GlassCard>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/timecampus/pages/HomePage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport {\n Clock,\n FolderOpen,\n Users,\n TrendingUp,\n CheckCircle,\n BarChart3,\n Play,\n ArrowRight,\n} from \"lucide-react\";\nimport {\n GlassCard,\n EmphasisPanel,\n AuroraBackground,\n GradientText,\n CTAOverflowMenu,\n} from \"@burdenoff/fe-libs/ui\";\nimport { StatCard } from \"../components/StatCard\";\nimport { LoadingSkeleton } from \"../components/LoadingSkeleton\";\nimport { cn, formatHours } from \"../utils/helpers\";\nimport { useTimeCampusNavigate } from \"../providers/TimeCampusProvider\";\nimport {\n useGetTimeEntryStatsQuery,\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\n\nexport const HomePage: FC = () => {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const navigate = useTimeCampusNavigate();\n\n const { data: statsData, loading: statsLoading } =\n useGetTimeEntryStatsQuery();\n const { data: entriesData, loading: entriesLoading } =\n useListTimeEntriesQuery({\n variables: { pagination: { limit: 4 } },\n });\n\n const stats = statsData?.timeEntryStats;\n const recentEntries = entriesData?.timeEntries?.items ?? [];\n\n const headerActions = (\n <CTAOverflowMenu\n primary={{\n label: t(\"timecampus.home.actions.startTimer\", \"Start Timer\"),\n onSelect: () => navigate(\"/time/timer\"),\n icon: <Play className=\"h-4 w-4\" />,\n }}\n actions={[\n {\n label: t(\n \"timecampus.home.quickActions.viewProjects.label\",\n \"View Projects\",\n ),\n onSelect: () => navigate(\"/projects\"),\n icon: <FolderOpen className=\"h-4 w-4\" />,\n },\n {\n label: t(\"timecampus.home.quickActions.reports.label\", \"Reports\"),\n onSelect: () => navigate(\"/reports\"),\n icon: <BarChart3 className=\"h-4 w-4\" />,\n },\n ]}\n />\n );\n\n const renderHeader = () => (\n <div className=\"relative overflow-hidden rounded-2xl border border-border-seam bg-gloss-card p-5 sm:p-6\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"min-w-0\">\n <h1 className=\"text-2xl font-bold text-text-primary\">\n <GradientText>\n {t(\"timecampus.home.title\", \"Dashboard\")}\n </GradientText>\n </h1>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {t(\n \"timecampus.home.description\",\n \"Overview of your time tracking and productivity\",\n )}\n </p>\n </div>\n {headerActions}\n </div>\n </div>\n );\n\n if (statsLoading && entriesLoading) {\n return (\n <div className=\"min-h-full space-y-6 p-4 sm:p-6\">\n {renderHeader()}\n <LoadingSkeleton variant=\"card\" count={4} />\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full space-y-6 p-4 sm:p-6\">\n {renderHeader()}\n\n {/* Hero metric + supporting metrics */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\n <StatCard\n featured\n title={t(\"timecampus.home.stats.today\", \"Today\")}\n value={formatHours(stats?.totalHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{\n value: 12.5,\n label: t(\"timecampus.home.stats.vsYesterday\", \"vs yesterday\"),\n }}\n />\n <StatCard\n title={t(\"timecampus.home.stats.billable\", \"Billable\")}\n value={formatHours(stats?.billableHours ?? 0)}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n description={`${stats?.totalEntries ?? 0} ${t(\"timecampus.home.stats.entries\", \"entries\")}`}\n />\n <StatCard\n title={t(\"timecampus.home.stats.activeTimers\", \"Active Timers\")}\n value={stats?.activeTimers ?? 0}\n icon={<FolderOpen className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.home.stats.currentlyRunning\",\n \"Currently running\",\n )}\n />\n <StatCard\n title={t(\"timecampus.home.stats.totalEntries\", \"Entries\")}\n value={stats?.totalEntries ?? 0}\n icon={<BarChart3 className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.home.stats.totalEntriesDescription\",\n \"Total time entries\",\n )}\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Recent Time Entries */}\n <GlassCard\n treatment=\"plain\"\n className=\"border-border-seam p-6 lg:col-span-2\"\n >\n <div className=\"mb-4 flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\n \"timecampus.home.recentEntries.title\",\n \"Recent Time Entries\",\n )}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.recentEntries.description\",\n \"Your latest tracked activities\",\n )}\n </p>\n </div>\n <button\n onClick={() => navigate(\"/time/entries\")}\n className=\"inline-flex min-h-[2.75rem] items-center gap-1 rounded-md px-2 text-xs font-medium text-primary transition-colors hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border\"\n >\n {t(\"timecampus.home.recentEntries.viewAll\", \"View all\")}{\" \"}\n <ArrowRight className=\"h-3 w-3\" />\n </button>\n </div>\n {entriesLoading ? (\n <LoadingSkeleton variant=\"list\" count={4} />\n ) : (\n <div className=\"flex flex-col gap-3\">\n {recentEntries.map((entry: TimeEntryFieldsFragment) => (\n <div\n key={entry.id}\n className=\"flex items-center justify-between rounded-lg border border-border-seam p-3 transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-text-primary\">\n {entry.project?.name ??\n t(\n \"timecampus.home.recentEntries.noProject\",\n \"No Project\",\n )}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {entry.description ??\n t(\n \"timecampus.home.recentEntries.noDescription\",\n \"No description\",\n )}\n </p>\n </div>\n <div className=\"ml-4 text-right\">\n <p className=\"font-mono text-sm font-medium tabular-nums text-text-primary\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </p>\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium\",\n entry.isRunning\n ? \"bg-status-info-bg text-status-info-text\"\n : \"bg-status-success-bg text-status-success-text\",\n )}\n >\n {entry.isRunning && (\n <span className=\"h-1.5 w-1.5 rounded-full bg-status-info-text motion-safe:animate-vc-glow-pulse\" />\n )}\n {entry.isRunning\n ? t(\n \"timecampus.home.recentEntries.status.running\",\n \"running\",\n )\n : t(\n \"timecampus.home.recentEntries.status.completed\",\n \"completed\",\n )}\n </span>\n </div>\n </div>\n ))}\n {recentEntries.length === 0 && (\n <p className=\"py-4 text-center text-sm text-text-secondary\">\n {t(\n \"timecampus.home.recentEntries.empty\",\n \"No time entries yet\",\n )}\n </p>\n )}\n </div>\n )}\n </GlassCard>\n\n {/* Quick Summary — the one emphasis zone */}\n <EmphasisPanel className=\"p-6\">\n <div className=\"mb-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\"timecampus.home.summary.title\", \"Quick Summary\")}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.summary.description\",\n \"Time tracking overview\",\n )}\n </p>\n </div>\n <div className=\"flex flex-col gap-4\">\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.totalHours\", \"Total Hours\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {formatHours(stats?.totalHours ?? 0)}\n </p>\n </div>\n <Clock className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.billableHours\", \"Billable Hours\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {formatHours(stats?.billableHours ?? 0)}\n </p>\n </div>\n <TrendingUp className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex items-center justify-between rounded-lg border border-border-seam bg-bg-surface/40 p-3\">\n <div>\n <p className=\"text-xs font-medium text-text-secondary\">\n {t(\"timecampus.home.summary.activeTimers\", \"Active Timers\")}\n </p>\n <p className=\"mt-1 text-xl font-bold tabular-nums text-text-primary\">\n {stats?.activeTimers ?? 0}\n </p>\n </div>\n <Users className=\"h-5 w-5 text-text-secondary\" />\n </div>\n </div>\n </EmphasisPanel>\n </div>\n\n {/* Quick Actions */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <div className=\"mb-4\">\n <h3 className=\"text-sm font-semibold text-text-primary\">\n {t(\"timecampus.home.quickActions.title\", \"Quick Actions\")}\n </h3>\n <p className=\"text-xs text-text-secondary\">\n {t(\n \"timecampus.home.quickActions.description\",\n \"Frequently used features\",\n )}\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3 lg:grid-cols-6\">\n {[\n {\n label: t(\n \"timecampus.home.quickActions.startTimer.label\",\n \"Start Timer\",\n ),\n icon: Play,\n route: \"/time/timer\",\n description: t(\n \"timecampus.home.quickActions.startTimer.description\",\n \"Track your time\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.viewProjects.label\",\n \"View Projects\",\n ),\n icon: FolderOpen,\n route: \"/projects\",\n description: t(\n \"timecampus.home.quickActions.viewProjects.description\",\n \"Manage projects\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.timeEntries.label\",\n \"Time Entries\",\n ),\n icon: Clock,\n route: \"/time/entries\",\n description: t(\n \"timecampus.home.quickActions.timeEntries.description\",\n \"View all entries\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.teamActivity.label\",\n \"Team Activity\",\n ),\n icon: Users,\n route: \"/team-activity\",\n description: t(\n \"timecampus.home.quickActions.teamActivity.description\",\n \"See team status\",\n ),\n },\n {\n label: t(\"timecampus.home.quickActions.reports.label\", \"Reports\"),\n icon: BarChart3,\n route: \"/reports\",\n description: t(\n \"timecampus.home.quickActions.reports.description\",\n \"Generate reports\",\n ),\n },\n {\n label: t(\n \"timecampus.home.quickActions.approvals.label\",\n \"Approvals\",\n ),\n icon: CheckCircle,\n route: \"/time-approval\",\n description: t(\n \"timecampus.home.quickActions.approvals.description\",\n \"Review timesheets\",\n ),\n },\n ].map(({ label, icon: Icon, description, route }) => (\n <button\n key={label}\n onClick={() => navigate(route)}\n className=\"flex min-h-[2.75rem] flex-col items-center gap-2 rounded-lg border border-border-seam bg-bg-surface p-4 text-center transition-colors hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border\"\n >\n <div className=\"rounded-full bg-action-primary-bg/10 p-3\">\n <Icon className=\"h-5 w-5 text-primary\" />\n </div>\n <span className=\"text-sm font-medium text-text-primary\">\n {label}\n </span>\n <span className=\"text-xs text-text-secondary\">{description}</span>\n </button>\n ))}\n </div>\n </GlassCard>\n </div>\n );\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AdminPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/admin/AdminPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AA+U1C,eAAO,MAAM,SAAS,EAAE,EAMvB,CAAC"}
|