@burdenoff/microfe-timecampus 2026.529.2 → 2026.624.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/timecampus/components/ErrorBoundary.js +2 -2
- package/dist/timecampus/components/ErrorBoundary.js.map +1 -1
- package/dist/timecampus/components/LoadingSkeleton.js +8 -8
- package/dist/timecampus/components/LoadingSkeleton.js.map +1 -1
- package/dist/timecampus/components/PageLayout.js +2 -2
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/components/StatCard.js +6 -6
- package/dist/timecampus/components/StatCard.js.map +1 -1
- package/dist/timecampus/pages/HomePage.js +31 -31
- package/dist/timecampus/pages/HomePage.js.map +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +7 -7
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +8 -8
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +10 -10
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +10 -10
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +6 -6
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +8 -8
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +11 -11
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js +10 -10
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +5 -5
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +13 -13
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +8 -8
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +8 -8
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +7 -7
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +10 -10
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +7 -7
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +9 -9
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +7 -7
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +12 -12
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +8 -8
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +4 -4
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +12 -12
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +15 -15
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js +11 -11
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +8 -8
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +8 -8
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +20 -20
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +14 -14
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +8 -8
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js +11 -11
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js +7 -7
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +8 -8
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +10 -10
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +10 -10
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js +4 -4
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +6 -6
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +11 -11
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +6 -6
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +10 -10
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +6 -6
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js +16 -16
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +9 -9
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +12 -12
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +8 -8
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +10 -10
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +7 -7
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +9 -9
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +10 -10
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +8 -8
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@ function p() {
|
|
|
46
46
|
title: "Focus Score Settings",
|
|
47
47
|
description: "Configure focus tracking preferences",
|
|
48
48
|
children: /* @__PURE__ */ l("div", {
|
|
49
|
-
className: "rounded-xl border border-
|
|
49
|
+
className: "rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text",
|
|
50
50
|
children: "Failed to load settings. Please try again later."
|
|
51
51
|
})
|
|
52
52
|
}) : /* @__PURE__ */ l(t, {
|
|
@@ -55,19 +55,19 @@ function p() {
|
|
|
55
55
|
children: /* @__PURE__ */ u("div", {
|
|
56
56
|
className: "mx-auto max-w-2xl space-y-6",
|
|
57
57
|
children: [/* @__PURE__ */ u("div", {
|
|
58
|
-
className: "rounded-xl border border-border bg-
|
|
58
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
59
59
|
children: [/* @__PURE__ */ u("h3", {
|
|
60
|
-
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-
|
|
60
|
+
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
61
61
|
children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Focus Goals"]
|
|
62
62
|
}), /* @__PURE__ */ u("div", {
|
|
63
63
|
className: "space-y-4",
|
|
64
64
|
children: [/* @__PURE__ */ u("div", {
|
|
65
65
|
className: "flex items-center justify-between",
|
|
66
66
|
children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
67
|
-
className: "text-sm font-medium text-
|
|
67
|
+
className: "text-sm font-medium text-text-primary",
|
|
68
68
|
children: "Daily focus target"
|
|
69
69
|
}), /* @__PURE__ */ l("p", {
|
|
70
|
-
className: "text-xs text-
|
|
70
|
+
className: "text-xs text-text-secondary",
|
|
71
71
|
children: "Hours of deep focus per day"
|
|
72
72
|
})] }), /* @__PURE__ */ l("input", {
|
|
73
73
|
type: "number",
|
|
@@ -76,15 +76,15 @@ function p() {
|
|
|
76
76
|
...t,
|
|
77
77
|
dailyFocusTarget: Number(e.target.value)
|
|
78
78
|
})),
|
|
79
|
-
className: "w-20 rounded-md border border-border bg-
|
|
79
|
+
className: "w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right"
|
|
80
80
|
})]
|
|
81
81
|
}), /* @__PURE__ */ u("div", {
|
|
82
82
|
className: "flex items-center justify-between",
|
|
83
83
|
children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
84
|
-
className: "text-sm font-medium text-
|
|
84
|
+
className: "text-sm font-medium text-text-primary",
|
|
85
85
|
children: "Min. session length"
|
|
86
86
|
}), /* @__PURE__ */ l("p", {
|
|
87
|
-
className: "text-xs text-
|
|
87
|
+
className: "text-xs text-text-secondary",
|
|
88
88
|
children: "Minimum minutes for a focus session"
|
|
89
89
|
})] }), /* @__PURE__ */ l("input", {
|
|
90
90
|
type: "number",
|
|
@@ -93,7 +93,7 @@ function p() {
|
|
|
93
93
|
...t,
|
|
94
94
|
minSessionLength: Number(e.target.value)
|
|
95
95
|
})),
|
|
96
|
-
className: "w-20 rounded-md border border-border bg-
|
|
96
|
+
className: "w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right"
|
|
97
97
|
})]
|
|
98
98
|
})]
|
|
99
99
|
})]
|
|
@@ -102,7 +102,7 @@ function p() {
|
|
|
102
102
|
children: /* @__PURE__ */ l("button", {
|
|
103
103
|
onClick: x,
|
|
104
104
|
disabled: v,
|
|
105
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
105
|
+
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
106
106
|
children: v ? "Saving..." : "Save Settings"
|
|
107
107
|
})
|
|
108
108
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusScoreSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/focus-score/FocusScoreSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst FOCUS_SETTINGS_KEY = \"timecampus.focus.settings\";\n\ninterface FocusSettings {\n dailyFocusTarget: number;\n minSessionLength: number;\n}\n\nconst DEFAULT_SETTINGS: FocusSettings = {\n dailyFocusTarget: 4,\n minSessionLength: 25,\n};\n\nexport function FocusScoreSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] = useState<FocusSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const config = data.configurations.find(\n (c: ConfigurationFieldsFragment) => c.key === FOCUS_SETTINGS_KEY,\n );\n if (config?.value) {\n const val = config.value as Partial<FocusSettings>;\n setSettings({\n dailyFocusTarget:\n val.dailyFocusTarget ?? DEFAULT_SETTINGS.dailyFocusTarget,\n minSessionLength:\n val.minSessionLength ?? DEFAULT_SETTINGS.minSessionLength,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: FOCUS_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Focus score settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Focus Score Settings\"\n description=\"Configure focus tracking preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Focus Score Settings\"\n description=\"Configure focus tracking preferences\"\n >\n <div className=\"rounded-xl border border-
|
|
1
|
+
{"version":3,"file":"FocusScoreSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/focus-score/FocusScoreSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst FOCUS_SETTINGS_KEY = \"timecampus.focus.settings\";\n\ninterface FocusSettings {\n dailyFocusTarget: number;\n minSessionLength: number;\n}\n\nconst DEFAULT_SETTINGS: FocusSettings = {\n dailyFocusTarget: 4,\n minSessionLength: 25,\n};\n\nexport function FocusScoreSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] = useState<FocusSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const config = data.configurations.find(\n (c: ConfigurationFieldsFragment) => c.key === FOCUS_SETTINGS_KEY,\n );\n if (config?.value) {\n const val = config.value as Partial<FocusSettings>;\n setSettings({\n dailyFocusTarget:\n val.dailyFocusTarget ?? DEFAULT_SETTINGS.dailyFocusTarget,\n minSessionLength:\n val.minSessionLength ?? DEFAULT_SETTINGS.minSessionLength,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: FOCUS_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Focus score settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Focus Score Settings\"\n description=\"Configure focus tracking preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Focus Score Settings\"\n description=\"Configure focus tracking preferences\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Focus Score Settings\"\n description=\"Configure focus tracking preferences\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Focus Goals\n </h3>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n Daily focus target\n </p>\n <p className=\"text-xs text-text-secondary\">\n Hours of deep focus per day\n </p>\n </div>\n <input\n type=\"number\"\n value={settings.dailyFocusTarget}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n dailyFocusTarget: Number(e.target.value),\n }))\n }\n className=\"w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right\"\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n Min. session length\n </p>\n <p className=\"text-xs text-text-secondary\">\n Minimum minutes for a focus session\n </p>\n </div>\n <input\n type=\"number\"\n value={settings.minSessionLength}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n minSessionLength: Number(e.target.value),\n }))\n }\n className=\"w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right\"\n />\n </div>\n </div>\n </div>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAWA,IAAM,IAAqB,6BAOrB,IAAkC;CACtC,kBAAkB;CAClB,kBAAkB;CACnB;AAED,SAAgB,IAAyB;CACvC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,EAAE,SAAM,YAAS,aAAU,EAA2B;EAC1D,WAAW;GAAE,OAAO;GAAsB,OAAO;GAAK;EACtD,MAAM,CAAC;EACR,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EACvE,CAAC,GAAU,KAAe,EAAwB,EAAiB;AAEzE,SAAgB;AACd,MAAI,GAAM,gBAAgB;GACxB,IAAM,IAAS,EAAK,eAAe,MAChC,MAAmC,EAAE,QAAQ,EAC/C;AACD,OAAI,GAAQ,OAAO;IACjB,IAAM,IAAM,EAAO;AACnB,MAAY;KACV,kBACE,EAAI,oBAAoB,EAAiB;KAC3C,kBACE,EAAI,oBAAoB,EAAiB;KAC5C,CAAC;;;IAGL,CAAC,EAAK,CAAC;CAEV,IAAM,IAAa,EAAY,YAAY;AACzC,QAAM,EAAiB,EACrB,WAAW,EACT,OAAO;GACL,KAAK;GACL,OAAO;GACP,aAAa;GACb,OAAO;GACR,EACF,EACF,CAAC;IACD,CAAC,GAAkB,EAAS,CAAC;AA0BhC,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,cAE7B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAwC;OAEjD,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;OACE,MAAK;OACL,OAAO,EAAS;OAChB,WAAW,MACT,GAAa,OAAO;QAClB,GAAG;QACH,kBAAkB,OAAO,EAAE,OAAO,MAAM;QACzC,EAAE;OAEL,WAAU;OACV,CAAA,CACE;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBAAwC;OAEjD,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;OACE,MAAK;OACL,OAAO,EAAS;OAChB,WAAW,MACT,GAAa,OAAO;QAClB,GAAG;QACH,kBAAkB,OAAO,EAAE,OAAO,MAAM;QACzC,EAAE;OAEL,WAAU;OACV,CAAA,CACE;QACF;OACF;OACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SAAS;KACT,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
|
|
@@ -26,25 +26,25 @@ function l() {
|
|
|
26
26
|
title: "Geofencing",
|
|
27
27
|
description: "Set up location-based triggers and zones",
|
|
28
28
|
actions: /* @__PURE__ */ c("button", {
|
|
29
|
-
className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
29
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
30
30
|
children: [/* @__PURE__ */ s(o, { className: "h-4 w-4" }), "Create Geofence"]
|
|
31
31
|
}),
|
|
32
32
|
children: /* @__PURE__ */ c("div", {
|
|
33
33
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
34
34
|
children: [p.length === 0 && /* @__PURE__ */ s("div", {
|
|
35
|
-
className: "col-span-full p-4 text-center text-sm text-
|
|
35
|
+
className: "col-span-full p-4 text-center text-sm text-text-secondary",
|
|
36
36
|
children: "No geofences configured yet."
|
|
37
37
|
}), p.map((e) => /* @__PURE__ */ c("div", {
|
|
38
|
-
className: "rounded-xl border border-border bg-
|
|
38
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer",
|
|
39
39
|
children: [/* @__PURE__ */ c("div", {
|
|
40
40
|
className: "flex items-start justify-between",
|
|
41
41
|
children: [/* @__PURE__ */ c("div", {
|
|
42
42
|
className: "flex items-center gap-2",
|
|
43
|
-
children: [/* @__PURE__ */ s(a, { className: "h-5 w-5 text-
|
|
44
|
-
className: "text-sm font-semibold text-
|
|
43
|
+
children: [/* @__PURE__ */ s(a, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
44
|
+
className: "text-sm font-semibold text-text-primary",
|
|
45
45
|
children: e.name
|
|
46
46
|
}), /* @__PURE__ */ c("p", {
|
|
47
|
-
className: "text-xs text-
|
|
47
|
+
className: "text-xs text-text-secondary",
|
|
48
48
|
children: [
|
|
49
49
|
e.trigger,
|
|
50
50
|
" · ",
|
|
@@ -57,7 +57,7 @@ function l() {
|
|
|
57
57
|
children: e.isActive ? "Active" : "Inactive"
|
|
58
58
|
})]
|
|
59
59
|
}), /* @__PURE__ */ c("div", {
|
|
60
|
-
className: "mt-3 flex items-center justify-between text-xs text-
|
|
60
|
+
className: "mt-3 flex items-center justify-between text-xs text-text-secondary",
|
|
61
61
|
children: [/* @__PURE__ */ s("span", { children: e.address ?? "No address" }), /* @__PURE__ */ c("span", { children: [e.events?.length ?? 0, " events"] })]
|
|
62
62
|
})]
|
|
63
63
|
}, e.id))]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeofencingPage.js","names":[],"sources":["../../../../src/timecampus/pages/geofencing/GeofencingPage.tsx"],"sourcesContent":["import { MapPin, Plus } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListGeofencesQuery,\n type ListGeofencesQuery,\n} from \"@/generated/wspace-operations\";\n\ntype GeofenceItem = NonNullable<\n ListGeofencesQuery[\"geofences\"]\n>[\"items\"][number];\n\nexport function GeofencingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListGeofencesQuery();\n\n const geofences = data?.geofences?.items ?? [];\n\n if (loading) {\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load geofences. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
1
|
+
{"version":3,"file":"GeofencingPage.js","names":[],"sources":["../../../../src/timecampus/pages/geofencing/GeofencingPage.tsx"],"sourcesContent":["import { MapPin, Plus } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListGeofencesQuery,\n type ListGeofencesQuery,\n} from \"@/generated/wspace-operations\";\n\ntype GeofenceItem = NonNullable<\n ListGeofencesQuery[\"geofences\"]\n>[\"items\"][number];\n\nexport function GeofencingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListGeofencesQuery();\n\n const geofences = data?.geofences?.items ?? [];\n\n if (loading) {\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load geofences. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Geofencing\"\n description=\"Set up location-based triggers and zones\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Create Geofence\n </button>\n }\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {geofences.length === 0 && (\n <div className=\"col-span-full p-4 text-center text-sm text-text-secondary\">\n No geofences configured yet.\n </div>\n )}\n {geofences.map((fence: GeofenceItem) => (\n <div\n key={fence.id}\n className=\"rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-2\">\n <MapPin className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">\n {fence.name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {fence.trigger} · {fence.radius}m radius\n </p>\n </div>\n </div>\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(fence.isActive ? \"active\" : \"inactive\")}`}\n >\n {fence.isActive ? \"Active\" : \"Inactive\"}\n </span>\n </div>\n <div className=\"mt-3 flex items-center justify-between text-xs text-text-secondary\">\n <span>{fence.address ?? \"No address\"}</span>\n <span>{fence.events?.length ?? 0} events</span>\n </div>\n </div>\n ))}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,IAAiB;CAC/B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,GAAuB,EAElD,IAAY,GAAM,WAAW,SAAS,EAAE;AA0B9C,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAU,WAAW,KACpB,kBAAC,OAAD;IAAK,WAAU;cAA4D;IAErE,CAAA,EAEP,EAAU,KAAK,MACd,kBAAC,OAAD;IAEE,WAAU;cAFZ,CAIE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,+BAAgC,CAAA,EAClD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAM;OACL,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAM;QAAQ;QAAW,EAAM;QAAO;QACrC;SACA,EAAA,CAAA,CACF;SACN,kBAAC,QAAD;MACE,WAAW,4DAA4D,EAAe,EAAM,WAAW,WAAW,WAAW;gBAE5H,EAAM,WAAW,WAAW;MACxB,CAAA,CACH;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAM,WAAW,cAAoB,CAAA,EAC5C,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAM,QAAQ,UAAU,GAAE,UAAc,EAAA,CAAA,CAC3C;OACF;MAzBC,EAAM,GAyBP,CACN,CACE;;EACK,CAAA"}
|
|
@@ -32,9 +32,9 @@ function d() {
|
|
|
32
32
|
children: /* @__PURE__ */ l("div", {
|
|
33
33
|
className: "mx-auto max-w-2xl space-y-6",
|
|
34
34
|
children: [/* @__PURE__ */ l("div", {
|
|
35
|
-
className: "rounded-xl border border-border bg-
|
|
35
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
36
36
|
children: [/* @__PURE__ */ l("h3", {
|
|
37
|
-
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-
|
|
37
|
+
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
38
38
|
children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Trigger Settings"]
|
|
39
39
|
}), /* @__PURE__ */ l("div", {
|
|
40
40
|
className: "space-y-3",
|
|
@@ -42,37 +42,37 @@ function d() {
|
|
|
42
42
|
/* @__PURE__ */ l("label", {
|
|
43
43
|
className: "flex items-center justify-between",
|
|
44
44
|
children: [/* @__PURE__ */ c("span", {
|
|
45
|
-
className: "text-sm text-
|
|
45
|
+
className: "text-sm text-text-primary",
|
|
46
46
|
children: "Auto-start timer on entry"
|
|
47
47
|
}), /* @__PURE__ */ c("input", {
|
|
48
48
|
type: "checkbox",
|
|
49
49
|
checked: v,
|
|
50
50
|
onChange: (e) => y(e.target.checked),
|
|
51
|
-
className: "h-4 w-4 rounded border-border"
|
|
51
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
52
52
|
})]
|
|
53
53
|
}),
|
|
54
54
|
/* @__PURE__ */ l("label", {
|
|
55
55
|
className: "flex items-center justify-between",
|
|
56
56
|
children: [/* @__PURE__ */ c("span", {
|
|
57
|
-
className: "text-sm text-
|
|
57
|
+
className: "text-sm text-text-primary",
|
|
58
58
|
children: "Auto-stop timer on exit"
|
|
59
59
|
}), /* @__PURE__ */ c("input", {
|
|
60
60
|
type: "checkbox",
|
|
61
61
|
checked: b,
|
|
62
62
|
onChange: (e) => x(e.target.checked),
|
|
63
|
-
className: "h-4 w-4 rounded border-border"
|
|
63
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
64
64
|
})]
|
|
65
65
|
}),
|
|
66
66
|
/* @__PURE__ */ l("label", {
|
|
67
67
|
className: "flex items-center justify-between",
|
|
68
68
|
children: [/* @__PURE__ */ c("span", {
|
|
69
|
-
className: "text-sm text-
|
|
69
|
+
className: "text-sm text-text-primary",
|
|
70
70
|
children: "Notifications on events"
|
|
71
71
|
}), /* @__PURE__ */ c("input", {
|
|
72
72
|
type: "checkbox",
|
|
73
73
|
checked: S,
|
|
74
74
|
onChange: (e) => C(e.target.checked),
|
|
75
|
-
className: "h-4 w-4 rounded border-border"
|
|
75
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
76
76
|
})]
|
|
77
77
|
})
|
|
78
78
|
]
|
|
@@ -93,7 +93,7 @@ function d() {
|
|
|
93
93
|
} } });
|
|
94
94
|
},
|
|
95
95
|
disabled: g,
|
|
96
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
96
|
+
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
97
97
|
children: g ? "Saving..." : "Save Settings"
|
|
98
98
|
})
|
|
99
99
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GeofencingSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/geofencing/GeofencingSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"geofencing.settings\";\n\nexport function GeofencingSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [autoStartOnEntry, setAutoStartOnEntry] = useState(true);\n const [autoStopOnExit, setAutoStopOnExit] = useState(true);\n const [notificationsOnEvents, setNotificationsOnEvents] = useState(true);\n\n useEffect(() => {\n if (configValue) {\n setAutoStartOnEntry(configValue.autoStartOnEntry ?? true);\n setAutoStopOnExit(configValue.autoStopOnExit ?? true);\n setNotificationsOnEvents(configValue.notificationsOnEvents ?? true);\n }\n }, [\n configValue.autoStartOnEntry,\n configValue.autoStopOnExit,\n configValue.notificationsOnEvents,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { autoStartOnEntry, autoStopOnExit, notificationsOnEvents },\n description: \"Geofencing trigger settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load geofencing settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border bg-
|
|
1
|
+
{"version":3,"file":"GeofencingSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/geofencing/GeofencingSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"geofencing.settings\";\n\nexport function GeofencingSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [autoStartOnEntry, setAutoStartOnEntry] = useState(true);\n const [autoStopOnExit, setAutoStopOnExit] = useState(true);\n const [notificationsOnEvents, setNotificationsOnEvents] = useState(true);\n\n useEffect(() => {\n if (configValue) {\n setAutoStartOnEntry(configValue.autoStartOnEntry ?? true);\n setAutoStopOnExit(configValue.autoStopOnExit ?? true);\n setNotificationsOnEvents(configValue.notificationsOnEvents ?? true);\n }\n }, [\n configValue.autoStartOnEntry,\n configValue.autoStopOnExit,\n configValue.notificationsOnEvents,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { autoStartOnEntry, autoStopOnExit, notificationsOnEvents },\n description: \"Geofencing trigger settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load geofencing settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Geofencing Settings\"\n description=\"Configure geofencing preferences\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Trigger Settings\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">\n Auto-start timer on entry\n </span>\n <input\n type=\"checkbox\"\n checked={autoStartOnEntry}\n onChange={(e) => setAutoStartOnEntry(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">\n Auto-stop timer on exit\n </span>\n <input\n type=\"checkbox\"\n checked={autoStopOnExit}\n onChange={(e) => setAutoStopOnExit(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">\n Notifications on events\n </span>\n <input\n type=\"checkbox\"\n checked={notificationsOnEvents}\n onChange={(e) => setNotificationsOnEvents(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,IAAM,IAAa;AAEnB,SAAgB,IAAyB;CACvC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,WAAW,EAAE,KAAK,GAAY,EAC/B,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EAEvE,IAAe,GAAM,oBAAoB,SAAS,EAAE,EAKpD,CAAC,GAAkB,KAAuB,EAAS,GAAK,EACxD,CAAC,GAAgB,KAAqB,EAAS,GAAK,EACpD,CAAC,GAAuB,KAA4B,EAAS,GAAK;AAmDxE,QAjDA,QAAgB;AACd,EAAI,MACF,EAAoB,EAAY,oBAAoB,GAAK,EACzD,EAAkB,EAAY,kBAAkB,GAAK,EACrD,EAAyB,EAAY,yBAAyB,GAAK;IAEpE;EACD,EAAY;EACZ,EAAY;EACZ,EAAY;EACb,CAAC,EAeE,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,mBAE7B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAErC,CAAA,EACP,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAoB,EAAE,OAAO,QAAQ;QACtD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAErC,CAAA,EACP,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAkB,EAAE,OAAO,QAAQ;QACpD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAErC,CAAA,EACP,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAyB,EAAE,OAAO,QAAQ;QAC3D,WAAU;QACV,CAAA,CACI;;MACJ;OACF;OACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SAtFS,YAAY;AAC7B,YAAM,EAAiB,EACrB,WAAW,EACT,OAAO;OACL,KAAK;OACL,OAAO;QAAE;QAAkB;QAAgB;QAAuB;OAClE,aAAa;OACb,OAAO;OACR,EACF,EACF,CAAC;;KA6EM,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
|
|
@@ -27,37 +27,37 @@ function c() {
|
|
|
27
27
|
children: /* @__PURE__ */ o("div", {
|
|
28
28
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
29
29
|
children: f.length === 0 ? /* @__PURE__ */ o("div", {
|
|
30
|
-
className: "col-span-full p-8 text-center text-sm text-
|
|
30
|
+
className: "col-span-full p-8 text-center text-sm text-text-secondary",
|
|
31
31
|
children: "No industry solutions configured yet. Solutions are stored as workspace configurations with the \"industry.\" key prefix."
|
|
32
32
|
}) : f.map((e) => {
|
|
33
33
|
let t = e.value, n = t.name ?? e.key.replace("industry.", ""), r = t.industry ?? "General", c = e.description ?? t.description ?? "", l = t.features ?? [];
|
|
34
34
|
return /* @__PURE__ */ s("div", {
|
|
35
|
-
className: "rounded-xl border border-border bg-
|
|
35
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer",
|
|
36
36
|
children: [
|
|
37
37
|
/* @__PURE__ */ s("div", {
|
|
38
38
|
className: "flex items-start gap-3",
|
|
39
39
|
children: [/* @__PURE__ */ o("div", {
|
|
40
|
-
className: "flex h-12 w-12 items-center justify-center rounded-xl bg-primary/10",
|
|
40
|
+
className: "flex h-12 w-12 items-center justify-center rounded-xl bg-action-primary-bg/10",
|
|
41
41
|
children: /* @__PURE__ */ o(a, { className: "h-6 w-6 text-primary" })
|
|
42
42
|
}), /* @__PURE__ */ s("div", {
|
|
43
43
|
className: "flex-1",
|
|
44
44
|
children: [/* @__PURE__ */ o("p", {
|
|
45
|
-
className: "text-sm font-semibold text-
|
|
45
|
+
className: "text-sm font-semibold text-text-primary",
|
|
46
46
|
children: n
|
|
47
47
|
}), /* @__PURE__ */ o("p", {
|
|
48
|
-
className: "text-xs text-
|
|
48
|
+
className: "text-xs text-text-secondary",
|
|
49
49
|
children: r
|
|
50
50
|
})]
|
|
51
51
|
})]
|
|
52
52
|
}),
|
|
53
53
|
/* @__PURE__ */ o("p", {
|
|
54
|
-
className: "mt-3 text-xs text-
|
|
54
|
+
className: "mt-3 text-xs text-text-secondary",
|
|
55
55
|
children: c
|
|
56
56
|
}),
|
|
57
57
|
/* @__PURE__ */ o("div", {
|
|
58
58
|
className: "mt-3 flex flex-wrap gap-1",
|
|
59
59
|
children: l.map((e) => /* @__PURE__ */ o("span", {
|
|
60
|
-
className: "inline-flex rounded-full bg-
|
|
60
|
+
className: "inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
|
|
61
61
|
children: e
|
|
62
62
|
}, e))
|
|
63
63
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IndustrySolutionsPage.js","names":[],"sources":["../../../../src/timecampus/pages/industry-solutions/IndustrySolutionsPage.tsx"],"sourcesContent":["import { Factory, ArrowRight } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function IndustrySolutionsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent industry solutions (key starts with 'industry.')\n const solutions = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"industry.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load industry solutions. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {solutions.length === 0 ? (\n <div className=\"col-span-full p-8 text-center text-sm text-
|
|
1
|
+
{"version":3,"file":"IndustrySolutionsPage.js","names":[],"sources":["../../../../src/timecampus/pages/industry-solutions/IndustrySolutionsPage.tsx"],"sourcesContent":["import { Factory, ArrowRight } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function IndustrySolutionsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent industry solutions (key starts with 'industry.')\n const solutions = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"industry.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load industry solutions. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Industry Solutions\"\n description=\"Time tracking solutions tailored to your industry\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {solutions.length === 0 ? (\n <div className=\"col-span-full p-8 text-center text-sm text-text-secondary\">\n No industry solutions configured yet. Solutions are stored as\n workspace configurations with the \"industry.\" key prefix.\n </div>\n ) : (\n solutions.map((solution: ConfigurationFieldsFragment) => {\n const val = solution.value as Record<string, unknown>;\n const name =\n (val.name as string) ?? solution.key.replace(\"industry.\", \"\");\n const industry = (val.industry as string) ?? \"General\";\n const description =\n solution.description ?? (val.description as string) ?? \"\";\n const features = (val.features as string[]) ?? [];\n\n return (\n <div\n key={solution.id}\n className=\"rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-12 w-12 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <Factory className=\"h-6 w-6 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">\n {name}\n </p>\n <p className=\"text-xs text-text-secondary\">{industry}</p>\n </div>\n </div>\n <p className=\"mt-3 text-xs text-text-secondary\">\n {description}\n </p>\n <div className=\"mt-3 flex flex-wrap gap-1\">\n {features.map((feature) => (\n <span\n key={feature}\n className=\"inline-flex rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {feature}\n </span>\n ))}\n </div>\n <button className=\"mt-3 flex items-center gap-1 text-xs font-medium text-primary hover:underline\">\n Learn more <ArrowRight className=\"h-3 w-3\" />\n </button>\n </div>\n );\n })\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AASA,SAAgB,IAAwB;CACtC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGhB,QAAQ,MACvC,EAAE,IAAI,WAAW,YAAY,CAC9B;AA0BD,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAU,WAAW,IACpB,kBAAC,OAAD;IAAK,WAAU;cAA4D;IAGrE,CAAA,GAEN,EAAU,KAAK,MAA0C;IACvD,IAAM,IAAM,EAAS,OACf,IACH,EAAI,QAAmB,EAAS,IAAI,QAAQ,aAAa,GAAG,EACzD,IAAY,EAAI,YAAuB,WACvC,IACJ,EAAS,eAAgB,EAAI,eAA0B,IACnD,IAAY,EAAI,YAAyB,EAAE;AAEjD,WACE,kBAAC,OAAD;KAEE,WAAU;eAFZ;MAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA;QACxC,CAAA,EACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV;SACC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAA+B;SAAa,CAAA,CACrD;UACF;;MACN,kBAAC,KAAD;OAAG,WAAU;iBACV;OACC,CAAA;MACJ,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAS,KAAK,MACb,kBAAC,QAAD;QAEE,WAAU;kBAET;QACI,EAJA,EAIA,CACP;OACE,CAAA;MACN,kBAAC,UAAD;OAAQ,WAAU;iBAAlB,CAAkG,eACrF,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA,CACtC;;MACL;OA9BC,EAAS,GA8BV;KAER;GAEA,CAAA;EACK,CAAA"}
|
|
@@ -32,9 +32,9 @@ function d() {
|
|
|
32
32
|
children: /* @__PURE__ */ l("div", {
|
|
33
33
|
className: "mx-auto max-w-2xl space-y-6",
|
|
34
34
|
children: [/* @__PURE__ */ l("div", {
|
|
35
|
-
className: "rounded-xl border border-border bg-
|
|
35
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
36
36
|
children: [/* @__PURE__ */ l("h3", {
|
|
37
|
-
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-
|
|
37
|
+
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
38
38
|
children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Privacy Controls"]
|
|
39
39
|
}), /* @__PURE__ */ l("div", {
|
|
40
40
|
className: "space-y-3",
|
|
@@ -42,46 +42,46 @@ function d() {
|
|
|
42
42
|
/* @__PURE__ */ l("label", {
|
|
43
43
|
className: "flex items-center justify-between",
|
|
44
44
|
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("span", {
|
|
45
|
-
className: "text-sm font-medium text-
|
|
45
|
+
className: "text-sm font-medium text-text-primary",
|
|
46
46
|
children: "Enable location tracking"
|
|
47
47
|
}), /* @__PURE__ */ c("p", {
|
|
48
|
-
className: "text-xs text-
|
|
48
|
+
className: "text-xs text-text-secondary",
|
|
49
49
|
children: "Allow the app to track your work location"
|
|
50
50
|
})] }), /* @__PURE__ */ c("input", {
|
|
51
51
|
type: "checkbox",
|
|
52
52
|
checked: v,
|
|
53
53
|
onChange: (e) => y(e.target.checked),
|
|
54
|
-
className: "h-4 w-4 rounded border-border"
|
|
54
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
55
55
|
})]
|
|
56
56
|
}),
|
|
57
57
|
/* @__PURE__ */ l("label", {
|
|
58
58
|
className: "flex items-center justify-between",
|
|
59
59
|
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("span", {
|
|
60
|
-
className: "text-sm font-medium text-
|
|
60
|
+
className: "text-sm font-medium text-text-primary",
|
|
61
61
|
children: "Share with team"
|
|
62
62
|
}), /* @__PURE__ */ c("p", {
|
|
63
|
-
className: "text-xs text-
|
|
63
|
+
className: "text-xs text-text-secondary",
|
|
64
64
|
children: "Let team members see your current location"
|
|
65
65
|
})] }), /* @__PURE__ */ c("input", {
|
|
66
66
|
type: "checkbox",
|
|
67
67
|
checked: b,
|
|
68
68
|
onChange: (e) => x(e.target.checked),
|
|
69
|
-
className: "h-4 w-4 rounded border-border"
|
|
69
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
70
70
|
})]
|
|
71
71
|
}),
|
|
72
72
|
/* @__PURE__ */ l("label", {
|
|
73
73
|
className: "flex items-center justify-between",
|
|
74
74
|
children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("span", {
|
|
75
|
-
className: "text-sm font-medium text-
|
|
75
|
+
className: "text-sm font-medium text-text-primary",
|
|
76
76
|
children: "Precise location"
|
|
77
77
|
}), /* @__PURE__ */ c("p", {
|
|
78
|
-
className: "text-xs text-
|
|
78
|
+
className: "text-xs text-text-secondary",
|
|
79
79
|
children: "Use precise GPS vs approximate location"
|
|
80
80
|
})] }), /* @__PURE__ */ c("input", {
|
|
81
81
|
type: "checkbox",
|
|
82
82
|
checked: S,
|
|
83
83
|
onChange: (e) => C(e.target.checked),
|
|
84
|
-
className: "h-4 w-4 rounded border-border"
|
|
84
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
85
85
|
})]
|
|
86
86
|
})
|
|
87
87
|
]
|
|
@@ -102,7 +102,7 @@ function d() {
|
|
|
102
102
|
} } });
|
|
103
103
|
},
|
|
104
104
|
disabled: g,
|
|
105
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
105
|
+
className: "rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
106
106
|
children: g ? "Saving..." : "Save Settings"
|
|
107
107
|
})
|
|
108
108
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationPrivacySettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationPrivacySettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Shield } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"location.privacy\";\n\nexport function LocationPrivacySettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [trackingEnabled, setTrackingEnabled] = useState(true);\n const [shareWithTeam, setShareWithTeam] = useState(false);\n const [preciseLocation, setPreciseLocation] = useState(false);\n\n useEffect(() => {\n if (configValue) {\n setTrackingEnabled(configValue.trackingEnabled ?? true);\n setShareWithTeam(configValue.shareWithTeam ?? false);\n setPreciseLocation(configValue.preciseLocation ?? false);\n }\n }, [\n configValue.trackingEnabled,\n configValue.shareWithTeam,\n configValue.preciseLocation,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { trackingEnabled, shareWithTeam, preciseLocation },\n description: \"Location privacy settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load privacy settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border bg-
|
|
1
|
+
{"version":3,"file":"LocationPrivacySettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationPrivacySettingsPage.tsx"],"sourcesContent":["import { useState, useEffect } from \"react\";\nimport { Shield } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetConfigurationByKeyQuery,\n useSetConfigurationMutation,\n} from \"@/generated/wspace-operations\";\n\nconst CONFIG_KEY = \"location.privacy\";\n\nexport function LocationPrivacySettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationByKeyQuery({\n variables: { key: CONFIG_KEY },\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n\n const configValue = (data?.configurationByKey?.value ?? {}) as Record<\n string,\n boolean\n >;\n\n const [trackingEnabled, setTrackingEnabled] = useState(true);\n const [shareWithTeam, setShareWithTeam] = useState(false);\n const [preciseLocation, setPreciseLocation] = useState(false);\n\n useEffect(() => {\n if (configValue) {\n setTrackingEnabled(configValue.trackingEnabled ?? true);\n setShareWithTeam(configValue.shareWithTeam ?? false);\n setPreciseLocation(configValue.preciseLocation ?? false);\n }\n }, [\n configValue.trackingEnabled,\n configValue.shareWithTeam,\n configValue.preciseLocation,\n ]);\n\n const handleSave = async () => {\n await setConfiguration({\n variables: {\n input: {\n key: CONFIG_KEY,\n value: { trackingEnabled, shareWithTeam, preciseLocation },\n description: \"Location privacy settings\",\n scope: \"USER\" as never,\n },\n },\n });\n };\n\n if (loading) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load privacy settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Privacy Settings\"\n description=\"Control location tracking and data sharing\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Shield className=\"h-4 w-4\" />\n Privacy Controls\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Enable location tracking\n </span>\n <p className=\"text-xs text-text-secondary\">\n Allow the app to track your work location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={trackingEnabled}\n onChange={(e) => setTrackingEnabled(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Share with team\n </span>\n <p className=\"text-xs text-text-secondary\">\n Let team members see your current location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={shareWithTeam}\n onChange={(e) => setShareWithTeam(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <div>\n <span className=\"text-sm font-medium text-text-primary\">\n Precise location\n </span>\n <p className=\"text-xs text-text-secondary\">\n Use precise GPS vs approximate location\n </p>\n </div>\n <input\n type=\"checkbox\"\n checked={preciseLocation}\n onChange={(e) => setPreciseLocation(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,IAAM,IAAa;AAEnB,SAAgB,IAA8B;CAC5C,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA8B,EAC7D,WAAW,EAAE,KAAK,GAAY,EAC/B,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EAEvE,IAAe,GAAM,oBAAoB,SAAS,EAAE,EAKpD,CAAC,GAAiB,KAAsB,EAAS,GAAK,EACtD,CAAC,GAAe,KAAoB,EAAS,GAAM,EACnD,CAAC,GAAiB,KAAsB,EAAS,GAAM;AAmD7D,QAjDA,QAAgB;AACd,EAAI,MACF,EAAmB,EAAY,mBAAmB,GAAK,EACvD,EAAiB,EAAY,iBAAiB,GAAM,EACpD,EAAmB,EAAY,mBAAmB,GAAM;IAEzD;EACD,EAAY;EACZ,EAAY;EACZ,EAAY;EACb,CAAC,EAeE,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,mBAE3B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAiB,EAAE,OAAO,QAAQ;QACnD,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAwC;QAEjD,CAAA,EACP,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAEvC,CAAA,CACA,EAAA,CAAA,EACN,kBAAC,SAAD;QACE,MAAK;QACL,SAAS;QACT,WAAW,MAAM,EAAmB,EAAE,OAAO,QAAQ;QACrD,WAAU;QACV,CAAA,CACI;;MACJ;OACF;OACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SArGS,YAAY;AAC7B,YAAM,EAAiB,EACrB,WAAW,EACT,OAAO;OACL,KAAK;OACL,OAAO;QAAE;QAAiB;QAAe;QAAiB;OAC1D,aAAa;OACb,OAAO;OACR,EACF,EACF,CAAC;;KA4FM,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
|
|
@@ -51,21 +51,21 @@ function d() {
|
|
|
51
51
|
})
|
|
52
52
|
]
|
|
53
53
|
}), /* @__PURE__ */ l("div", {
|
|
54
|
-
className: "rounded-xl border border-border bg-
|
|
54
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface",
|
|
55
55
|
children: /* @__PURE__ */ u("div", {
|
|
56
56
|
className: "divide-y divide-border",
|
|
57
57
|
children: [v.length === 0 && !p && /* @__PURE__ */ l("div", {
|
|
58
|
-
className: "p-4 text-center text-sm text-
|
|
58
|
+
className: "p-4 text-center text-sm text-text-secondary",
|
|
59
59
|
children: "No location entries found."
|
|
60
60
|
}), v.map((e) => /* @__PURE__ */ u("div", {
|
|
61
|
-
className: "flex items-center justify-between p-4 hover:bg-
|
|
61
|
+
className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors",
|
|
62
62
|
children: [/* @__PURE__ */ u("div", {
|
|
63
63
|
className: "flex items-center gap-3",
|
|
64
|
-
children: [/* @__PURE__ */ l(c, { className: "h-5 w-5 text-
|
|
65
|
-
className: "text-sm font-medium text-
|
|
64
|
+
children: [/* @__PURE__ */ l(c, { className: "h-5 w-5 text-text-secondary" }), /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
65
|
+
className: "text-sm font-medium text-text-primary",
|
|
66
66
|
children: e.address ?? "Unknown Location"
|
|
67
67
|
}), /* @__PURE__ */ u("p", {
|
|
68
|
-
className: "text-xs text-
|
|
68
|
+
className: "text-xs text-text-secondary",
|
|
69
69
|
children: [
|
|
70
70
|
e.geofenceId ? "Geofenced" : "Manual",
|
|
71
71
|
" ·",
|
|
@@ -78,10 +78,10 @@ function d() {
|
|
|
78
78
|
children: /* @__PURE__ */ u("div", {
|
|
79
79
|
className: "text-right",
|
|
80
80
|
children: [/* @__PURE__ */ l("p", {
|
|
81
|
-
className: "text-sm font-medium text-
|
|
81
|
+
className: "text-sm font-medium text-text-primary",
|
|
82
82
|
children: e.duration ? t(e.duration / 3600) : "Active"
|
|
83
83
|
}), /* @__PURE__ */ l("p", {
|
|
84
|
-
className: "text-xs text-
|
|
84
|
+
className: "text-xs text-text-secondary",
|
|
85
85
|
children: "duration"
|
|
86
86
|
})]
|
|
87
87
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocationTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationTrackingPage.tsx"],"sourcesContent":["import { MapPin, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListLocationEntriesQuery,\n useGetLocationStatsQuery,\n type LocationEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function LocationTrackingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: entriesData,\n loading: entriesLoading,\n error: entriesError,\n } = useListLocationEntriesQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetLocationStatsQuery();\n\n const locations = entriesData?.locationEntries?.items ?? [];\n const stats = statsData?.locationStats;\n\n if (entriesLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (entriesError && statsError) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load location data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Locations\"\n value={String(stats?.totalLocations ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Unique Addresses\"\n value={String(stats?.uniqueAddresses ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Most Frequent\"\n value={stats?.mostFrequentLocation ?? \"N/A\"}\n />\n <StatCard\n title=\"Total Duration\"\n value={formatHours((stats?.totalDuration ?? 0) / 3600)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"Tracked time\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border bg-
|
|
1
|
+
{"version":3,"file":"LocationTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/location-tracking/LocationTrackingPage.tsx"],"sourcesContent":["import { MapPin, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListLocationEntriesQuery,\n useGetLocationStatsQuery,\n type LocationEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function LocationTrackingPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: entriesData,\n loading: entriesLoading,\n error: entriesError,\n } = useListLocationEntriesQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetLocationStatsQuery();\n\n const locations = entriesData?.locationEntries?.items ?? [];\n const stats = statsData?.locationStats;\n\n if (entriesLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (entriesError && statsError) {\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load location data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Location Tracking\"\n description=\"Track work locations and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Locations\"\n value={String(stats?.totalLocations ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Unique Addresses\"\n value={String(stats?.uniqueAddresses ?? 0)}\n icon={<MapPin className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Most Frequent\"\n value={stats?.mostFrequentLocation ?? \"N/A\"}\n />\n <StatCard\n title=\"Total Duration\"\n value={formatHours((stats?.totalDuration ?? 0) / 3600)}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"Tracked time\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface\">\n <div className=\"divide-y divide-border\">\n {locations.length === 0 && !entriesLoading && (\n <div className=\"p-4 text-center text-sm text-text-secondary\">\n No location entries found.\n </div>\n )}\n {locations.map((location: LocationEntryFieldsFragment) => (\n <div\n key={location.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <MapPin className=\"h-5 w-5 text-text-secondary\" />\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {location.address ?? \"Unknown Location\"}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {location.geofenceId ? \"Geofenced\" : \"Manual\"} ·{\" \"}\n {new Date(location.startTime).toLocaleDateString()}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">\n {location.duration\n ? formatHours(location.duration / 3600)\n : \"Active\"}\n </p>\n <p className=\"text-xs text-text-secondary\">duration</p>\n </div>\n </div>\n </div>\n ))}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAYA,SAAgB,IAAuB;CACrC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA6B,EAC3B,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA0B,EAExB,IAAY,GAAa,iBAAiB,SAAS,EAAE,EACrD,IAAQ,GAAW;AA0BzB,QAxBI,KAAkB,IAElB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,KAAgB,IAEhB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,kBAAkB,EAAE;KACzC,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,mBAAmB,EAAE;KAC1C,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAO,wBAAwB;KACtC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAa,GAAO,iBAAiB,KAAK,KAAK;KACtD,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,EAAU,WAAW,KAAK,CAAC,KAC1B,kBAAC,OAAD;KAAK,WAAU;eAA8C;KAEvD,CAAA,EAEP,EAAU,KAAK,MACd,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD,EAAQ,WAAU,+BAAgC,CAAA,EAClD,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAS,WAAW;OACnB,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAS,aAAa,cAAc;QAAS;QAAU;QACvD,IAAI,KAAK,EAAS,UAAU,CAAC,oBAAoB;QAChD;SACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAS,WACN,EAAY,EAAS,WAAW,KAAK,GACrC;QACF,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAA8B;QAAY,CAAA,CACnD;;MACF,CAAA,CACF;OAzBC,EAAS,GAyBV,CACN,CACE;;GACF,CAAA,CACK"}
|
|
@@ -69,14 +69,14 @@ function f() {
|
|
|
69
69
|
})
|
|
70
70
|
]
|
|
71
71
|
}), /* @__PURE__ */ d("div", {
|
|
72
|
-
className: "rounded-xl border border-border bg-
|
|
72
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
73
73
|
children: [/* @__PURE__ */ u("h3", {
|
|
74
|
-
className: "mb-4 text-sm font-semibold text-
|
|
74
|
+
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
75
75
|
children: "Meeting Time Distribution"
|
|
76
76
|
}), /* @__PURE__ */ u("div", {
|
|
77
|
-
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
77
|
+
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
|
|
78
78
|
children: /* @__PURE__ */ u("p", {
|
|
79
|
-
className: "text-sm text-
|
|
79
|
+
className: "text-sm text-text-secondary",
|
|
80
80
|
children: g ? `${g.totalMeetings} meetings · ${g.actionItemsTotal} action items (${g.actionItemsCompleted} completed)` : "Chart will render here"
|
|
81
81
|
})
|
|
82
82
|
})]
|