@burdenoff/microfe-timecampus 2026.608.1 → 2026.625.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/timecampus/components/ErrorBoundary.js +4 -4
- 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 +17 -13
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/components/StatCard.js +22 -19
- package/dist/timecampus/components/StatCard.js.map +1 -1
- package/dist/timecampus/pages/HomePage.js +183 -163
- package/dist/timecampus/pages/HomePage.js.map +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +17 -17
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +18 -18
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +28 -28
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +19 -19
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +15 -15
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +22 -22
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +20 -20
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js +20 -20
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +18 -18
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +22 -22
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +14 -14
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +22 -22
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +27 -27
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +19 -19
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +16 -16
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +18 -18
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +16 -16
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +21 -21
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +22 -22
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +18 -18
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +16 -16
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +29 -29
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js +20 -20
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +23 -23
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +23 -23
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +30 -30
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +19 -19
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +23 -23
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js +20 -20
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js +15 -15
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +25 -25
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +19 -19
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +21 -21
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js +19 -19
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +21 -21
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +20 -20
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +16 -16
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +21 -21
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +16 -16
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js +25 -25
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +24 -24
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +20 -20
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +27 -27
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +20 -20
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +18 -18
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +23 -23
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +19 -19
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +17 -17
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
2
|
+
import { StatCard as t } from "../../components/StatCard.js";
|
|
3
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useGetFocusScoreSummaryQuery as r, useGetTodayFocusScoreQuery as i, useListFocusScoresQuery as a } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { PageLayout as o } from "../../components/PageLayout.js";
|
|
6
6
|
import { Brain as s, Shield as c, Target as l, Zap as u } from "lucide-react";
|
|
7
7
|
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
8
8
|
//#region src/timecampus/pages/focus-score/FocusScorePage.tsx
|
|
9
9
|
var p = {
|
|
10
|
-
deepWork: "bg-blue
|
|
11
|
-
consistency: "bg-
|
|
12
|
-
taskCompletion: "bg-
|
|
13
|
-
distractionResistance: "bg-
|
|
14
|
-
energyManagement: "bg-
|
|
10
|
+
deepWork: "bg-accent-blue",
|
|
11
|
+
consistency: "bg-status-success-text",
|
|
12
|
+
taskCompletion: "bg-accent-purple",
|
|
13
|
+
distractionResistance: "bg-status-warning-text",
|
|
14
|
+
energyManagement: "bg-accent-teal"
|
|
15
15
|
};
|
|
16
16
|
function m() {
|
|
17
|
-
let { workspaceId: m = "" } = e(), { data: h, loading: g, error: _ } =
|
|
17
|
+
let { workspaceId: m = "" } = e(), { data: h, loading: g, error: _ } = a({
|
|
18
18
|
variables: { limit: 30 },
|
|
19
19
|
skip: !m
|
|
20
|
-
}), { data: v, loading: y, error: b } =
|
|
20
|
+
}), { data: v, loading: y, error: b } = r({ skip: !m }), { data: x, loading: S, error: C } = i({ skip: !m }), w = g || y || S, T = _ || b || C, E = x?.todayFocusScore, D = v?.focusScoreSummary, O = h?.focusScores ?? [], k = E ? [
|
|
21
21
|
{
|
|
22
22
|
label: "Deep Work",
|
|
23
23
|
score: E.deepWorkScore ?? 0,
|
|
@@ -44,27 +44,27 @@ function m() {
|
|
|
44
44
|
color: p.energyManagement
|
|
45
45
|
}
|
|
46
46
|
] : [], A = E?.overallScore == null ? "--" : `${E.overallScore}/100`, j = O.filter((e) => e.overallScore >= 70).length, M = O.reduce((e, t) => e + (t.overallScore ?? 0), 0), N = Math.floor(M / 60), P = M % 60, F = N > 0 ? `${N}h ${P}m` : `${P}m`, I = D?.trend === "up" ? 7 : D?.trend === "down" ? -5 : 0, L = D?.highestScore == null ? "--" : `${D.highestScore}`;
|
|
47
|
-
return w ? /* @__PURE__ */ d(
|
|
47
|
+
return w ? /* @__PURE__ */ d(o, {
|
|
48
48
|
title: "Focus Score",
|
|
49
49
|
description: "Measure and improve your focus",
|
|
50
|
-
children: /* @__PURE__ */ d(
|
|
50
|
+
children: /* @__PURE__ */ d(n, {
|
|
51
51
|
variant: "card",
|
|
52
52
|
count: 4
|
|
53
53
|
})
|
|
54
|
-
}) : T ? /* @__PURE__ */ d(
|
|
54
|
+
}) : T ? /* @__PURE__ */ d(o, {
|
|
55
55
|
title: "Focus Score",
|
|
56
56
|
description: "Measure and improve your focus",
|
|
57
57
|
children: /* @__PURE__ */ d("div", {
|
|
58
|
-
className: "rounded-xl border border-
|
|
58
|
+
className: "rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text",
|
|
59
59
|
children: "Failed to load focus score data. Please try again later."
|
|
60
60
|
})
|
|
61
|
-
}) : /* @__PURE__ */ f(
|
|
61
|
+
}) : /* @__PURE__ */ f(o, {
|
|
62
62
|
title: "Focus Score",
|
|
63
63
|
description: "Measure and improve your focus",
|
|
64
64
|
children: [/* @__PURE__ */ f("div", {
|
|
65
65
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
66
66
|
children: [
|
|
67
|
-
/* @__PURE__ */ d(
|
|
67
|
+
/* @__PURE__ */ d(t, {
|
|
68
68
|
title: "Overall Score",
|
|
69
69
|
value: A,
|
|
70
70
|
icon: /* @__PURE__ */ d(s, { className: "h-5 w-5" }),
|
|
@@ -72,20 +72,20 @@ function m() {
|
|
|
72
72
|
value: I,
|
|
73
73
|
label: "vs last week"
|
|
74
74
|
},
|
|
75
|
-
iconBgColor: "bg-
|
|
75
|
+
iconBgColor: "bg-status-info-bg text-status-info-text"
|
|
76
76
|
}),
|
|
77
|
-
/* @__PURE__ */ d(
|
|
77
|
+
/* @__PURE__ */ d(t, {
|
|
78
78
|
title: "Focus Sessions",
|
|
79
79
|
value: String(j),
|
|
80
80
|
icon: /* @__PURE__ */ d(l, { className: "h-5 w-5" }),
|
|
81
81
|
description: "Completed today"
|
|
82
82
|
}),
|
|
83
|
-
/* @__PURE__ */ d(
|
|
83
|
+
/* @__PURE__ */ d(t, {
|
|
84
84
|
title: "Total Focus Time",
|
|
85
85
|
value: F,
|
|
86
86
|
icon: /* @__PURE__ */ d(u, { className: "h-5 w-5" })
|
|
87
87
|
}),
|
|
88
|
-
/* @__PURE__ */ d(
|
|
88
|
+
/* @__PURE__ */ d(t, {
|
|
89
89
|
title: "Highest Score",
|
|
90
90
|
value: L,
|
|
91
91
|
icon: /* @__PURE__ */ d(c, { className: "h-5 w-5" }),
|
|
@@ -93,12 +93,12 @@ function m() {
|
|
|
93
93
|
})
|
|
94
94
|
]
|
|
95
95
|
}), /* @__PURE__ */ f("div", {
|
|
96
|
-
className: "rounded-xl border border-border bg-card p-6",
|
|
96
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
|
|
97
97
|
children: [/* @__PURE__ */ d("h3", {
|
|
98
|
-
className: "mb-4 text-sm font-semibold text-
|
|
98
|
+
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
99
99
|
children: "Focus Components"
|
|
100
100
|
}), k.length === 0 ? /* @__PURE__ */ d("div", {
|
|
101
|
-
className: "flex h-32 items-center justify-center text-sm text-
|
|
101
|
+
className: "flex h-32 items-center justify-center text-sm text-text-secondary",
|
|
102
102
|
children: "No focus score recorded today."
|
|
103
103
|
}) : /* @__PURE__ */ d("div", {
|
|
104
104
|
className: "space-y-4",
|
|
@@ -107,14 +107,14 @@ function m() {
|
|
|
107
107
|
children: [/* @__PURE__ */ f("div", {
|
|
108
108
|
className: "flex items-center justify-between text-sm",
|
|
109
109
|
children: [/* @__PURE__ */ d("span", {
|
|
110
|
-
className: "font-medium text-
|
|
110
|
+
className: "font-medium text-text-primary",
|
|
111
111
|
children: e.label
|
|
112
112
|
}), /* @__PURE__ */ f("span", {
|
|
113
|
-
className: "text-
|
|
113
|
+
className: "text-text-secondary",
|
|
114
114
|
children: [e.score, "%"]
|
|
115
115
|
})]
|
|
116
116
|
}), /* @__PURE__ */ d("div", {
|
|
117
|
-
className: "h-2.5 w-full rounded-full bg-
|
|
117
|
+
className: "h-2.5 w-full rounded-full bg-bg-sunken",
|
|
118
118
|
children: /* @__PURE__ */ d("div", {
|
|
119
119
|
className: `h-2.5 rounded-full ${e.color}`,
|
|
120
120
|
style: { width: `${e.score}%` }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FocusScorePage.js","names":[],"sources":["../../../../src/timecampus/pages/focus-score/FocusScorePage.tsx"],"sourcesContent":["import { Brain, Target, Zap, Shield } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListFocusScoresQuery,\n useGetFocusScoreSummaryQuery,\n useGetTodayFocusScoreQuery,\n type FocusScoreFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst COMPONENT_COLORS: Record<string, string> = {\n deepWork: \"bg-blue
|
|
1
|
+
{"version":3,"file":"FocusScorePage.js","names":[],"sources":["../../../../src/timecampus/pages/focus-score/FocusScorePage.tsx"],"sourcesContent":["import { Brain, Target, Zap, Shield } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListFocusScoresQuery,\n useGetFocusScoreSummaryQuery,\n useGetTodayFocusScoreQuery,\n type FocusScoreFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst COMPONENT_COLORS: Record<string, string> = {\n deepWork: \"bg-accent-blue\",\n consistency: \"bg-status-success-text\",\n taskCompletion: \"bg-accent-purple\",\n distractionResistance: \"bg-status-warning-text\",\n energyManagement: \"bg-accent-teal\",\n};\n\nexport function FocusScorePage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: scoresData,\n loading: scoresLoading,\n error: scoresError,\n } = useListFocusScoresQuery({\n variables: { limit: 30 },\n skip: !workspaceId,\n });\n\n const {\n data: summaryData,\n loading: summaryLoading,\n error: summaryError,\n } = useGetFocusScoreSummaryQuery({\n skip: !workspaceId,\n });\n\n const {\n data: todayData,\n loading: todayLoading,\n error: todayError,\n } = useGetTodayFocusScoreQuery({\n skip: !workspaceId,\n });\n\n const loading = scoresLoading || summaryLoading || todayLoading;\n const error = scoresError || summaryError || todayError;\n const today = todayData?.todayFocusScore;\n const summary = summaryData?.focusScoreSummary;\n const scores = scoresData?.focusScores ?? [];\n\n // Build focus components from today's score\n const focusComponents = today\n ? [\n {\n label: \"Deep Work\",\n score: today.deepWorkScore ?? 0,\n color: COMPONENT_COLORS.deepWork,\n },\n {\n label: \"Consistency\",\n score: today.consistencyScore ?? 0,\n color: COMPONENT_COLORS.consistency,\n },\n {\n label: \"Task Completion\",\n score: today.taskCompletionScore ?? 0,\n color: COMPONENT_COLORS.taskCompletion,\n },\n {\n label: \"Distraction Resistance\",\n score: today.distractionResistanceScore ?? 0,\n color: COMPONENT_COLORS.distractionResistance,\n },\n {\n label: \"Energy Management\",\n score: today.energyManagementScore ?? 0,\n color: COMPONENT_COLORS.energyManagement,\n },\n ]\n : [];\n\n // Calculate stats\n const overallScore =\n today?.overallScore != null ? `${today.overallScore}/100` : \"--\";\n const completedSessions = scores.filter(\n (s: FocusScoreFieldsFragment) => s.overallScore >= 70,\n ).length;\n const totalFocusMinutes = scores.reduce(\n (sum: number, s: FocusScoreFieldsFragment) => sum + (s.overallScore ?? 0),\n 0,\n );\n const totalFocusHours = Math.floor(totalFocusMinutes / 60);\n const totalFocusMins = totalFocusMinutes % 60;\n const focusTimeDisplay =\n totalFocusHours > 0\n ? `${totalFocusHours}h ${totalFocusMins}m`\n : `${totalFocusMins}m`;\n const trendValue =\n summary?.trend === \"up\" ? 7 : summary?.trend === \"down\" ? -5 : 0;\n\n // Longest streak from highest score\n const highestScore =\n summary?.highestScore != null ? `${summary.highestScore}` : \"--\";\n\n if (loading) {\n return (\n <PageLayout\n title=\"Focus Score\"\n description=\"Measure and improve your focus\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Focus Score\"\n description=\"Measure and improve your focus\"\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 focus score data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Focus Score\"\n description=\"Measure and improve your focus\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Overall Score\"\n value={overallScore}\n icon={<Brain className=\"h-5 w-5\" />}\n trend={\n trendValue !== 0\n ? { value: trendValue, label: \"vs last week\" }\n : undefined\n }\n iconBgColor=\"bg-status-info-bg text-status-info-text\"\n />\n <StatCard\n title=\"Focus Sessions\"\n value={String(completedSessions)}\n icon={<Target className=\"h-5 w-5\" />}\n description=\"Completed today\"\n />\n <StatCard\n title=\"Total Focus Time\"\n value={focusTimeDisplay}\n icon={<Zap className=\"h-5 w-5\" />}\n />\n <StatCard\n title=\"Highest Score\"\n value={highestScore}\n icon={<Shield className=\"h-5 w-5\" />}\n description=\"Personal best\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Focus Components\n </h3>\n {focusComponents.length === 0 ? (\n <div className=\"flex h-32 items-center justify-center text-sm text-text-secondary\">\n No focus score recorded today.\n </div>\n ) : (\n <div className=\"space-y-4\">\n {focusComponents.map((component) => (\n <div key={component.label} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"font-medium text-text-primary\">\n {component.label}\n </span>\n <span className=\"text-text-secondary\">\n {component.score}%\n </span>\n </div>\n <div className=\"h-2.5 w-full rounded-full bg-bg-sunken\">\n <div\n className={`h-2.5 rounded-full ${component.color}`}\n style={{ width: `${component.score}%` }}\n />\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
|
|
3
|
+
import { useListConfigurationsQuery as n, useSetConfigurationMutation as r } from "../../../generated/wspace-operations.js";
|
|
4
|
+
import { PageLayout as i } from "../../components/PageLayout.js";
|
|
5
5
|
import { useCallback as a, useEffect as o, useState as s } from "react";
|
|
6
6
|
import { Settings as c } from "lucide-react";
|
|
7
7
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
@@ -11,13 +11,13 @@ var d = "timecampus.focus.settings", f = {
|
|
|
11
11
|
minSessionLength: 25
|
|
12
12
|
};
|
|
13
13
|
function p() {
|
|
14
|
-
let { workspaceId: p = "" } = e(), { data: m, loading: h, error: g } =
|
|
14
|
+
let { workspaceId: p = "" } = e(), { data: m, loading: h, error: g } = n({
|
|
15
15
|
variables: {
|
|
16
16
|
scope: "WORKSPACE",
|
|
17
17
|
limit: 100
|
|
18
18
|
},
|
|
19
19
|
skip: !p
|
|
20
|
-
}), [_, { loading: v }] =
|
|
20
|
+
}), [_, { loading: v }] = r(), [y, b] = s(f);
|
|
21
21
|
o(() => {
|
|
22
22
|
if (m?.configurations) {
|
|
23
23
|
let e = m.configurations.find((e) => e.key === d);
|
|
@@ -38,36 +38,36 @@ function p() {
|
|
|
38
38
|
scope: "WORKSPACE"
|
|
39
39
|
} } });
|
|
40
40
|
}, [_, y]);
|
|
41
|
-
return h ? /* @__PURE__ */ l(
|
|
41
|
+
return h ? /* @__PURE__ */ l(i, {
|
|
42
42
|
title: "Focus Score Settings",
|
|
43
43
|
description: "Configure focus tracking preferences",
|
|
44
|
-
children: /* @__PURE__ */ l(
|
|
45
|
-
}) : g ? /* @__PURE__ */ l(
|
|
44
|
+
children: /* @__PURE__ */ l(t, { variant: "detail" })
|
|
45
|
+
}) : g ? /* @__PURE__ */ l(i, {
|
|
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
|
-
}) : /* @__PURE__ */ l(
|
|
52
|
+
}) : /* @__PURE__ */ l(i, {
|
|
53
53
|
title: "Focus Score Settings",
|
|
54
54
|
description: "Configure focus tracking preferences",
|
|
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-card p-6",
|
|
58
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop 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-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n 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"}
|
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
2
|
import { getStatusColor as t } from "../../utils/helpers.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useListGeofencesQuery as r } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { PageLayout as i } from "../../components/PageLayout.js";
|
|
6
6
|
import { MapPin as a, Plus as o } from "lucide-react";
|
|
7
7
|
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
8
8
|
//#region src/timecampus/pages/geofencing/GeofencingPage.tsx
|
|
9
9
|
function l() {
|
|
10
|
-
let { workspaceId: l = "" } = e(), { data: u, loading: d, error: f } =
|
|
11
|
-
return d ? /* @__PURE__ */ s(
|
|
10
|
+
let { workspaceId: l = "" } = e(), { data: u, loading: d, error: f } = r(), p = u?.geofences?.items ?? [];
|
|
11
|
+
return d ? /* @__PURE__ */ s(i, {
|
|
12
12
|
title: "Geofencing",
|
|
13
13
|
description: "Set up location-based triggers and zones",
|
|
14
|
-
children: /* @__PURE__ */ s(
|
|
14
|
+
children: /* @__PURE__ */ s(n, {
|
|
15
15
|
variant: "card",
|
|
16
16
|
count: 4
|
|
17
17
|
})
|
|
18
|
-
}) : f ? /* @__PURE__ */ s(
|
|
18
|
+
}) : f ? /* @__PURE__ */ s(i, {
|
|
19
19
|
title: "Geofencing",
|
|
20
20
|
description: "Set up location-based triggers and zones",
|
|
21
21
|
children: /* @__PURE__ */ s("div", {
|
|
22
|
-
className: "rounded-lg border border-
|
|
22
|
+
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
23
23
|
children: "Failed to load geofences. Please try again later."
|
|
24
24
|
})
|
|
25
|
-
}) : /* @__PURE__ */ s(
|
|
25
|
+
}) : /* @__PURE__ */ s(i, {
|
|
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-card p-5 transition-colors hover:bg-
|
|
38
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop 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-
|
|
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-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\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-seam bg-gloss-card shadow-pop 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;aAAoG;GAE7G,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"}
|
|
@@ -1,40 +1,40 @@
|
|
|
1
1
|
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { LoadingSkeleton as t } from "../../components/LoadingSkeleton.js";
|
|
3
|
+
import { useGetConfigurationByKeyQuery as n, useSetConfigurationMutation as r } from "../../../generated/wspace-operations.js";
|
|
4
|
+
import { PageLayout as i } from "../../components/PageLayout.js";
|
|
5
5
|
import { useEffect as a, useState as o } from "react";
|
|
6
6
|
import { Settings as s } from "lucide-react";
|
|
7
7
|
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
8
8
|
//#region src/timecampus/pages/geofencing/GeofencingSettingsPage.tsx
|
|
9
9
|
var u = "geofencing.settings";
|
|
10
10
|
function d() {
|
|
11
|
-
let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } =
|
|
11
|
+
let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = n({ variables: { key: u } }), [h, { loading: g }] = r(), _ = f?.configurationByKey?.value ?? {}, [v, y] = o(!0), [b, x] = o(!0), [S, C] = o(!0);
|
|
12
12
|
return a(() => {
|
|
13
13
|
_ && (y(_.autoStartOnEntry ?? !0), x(_.autoStopOnExit ?? !0), C(_.notificationsOnEvents ?? !0));
|
|
14
14
|
}, [
|
|
15
15
|
_.autoStartOnEntry,
|
|
16
16
|
_.autoStopOnExit,
|
|
17
17
|
_.notificationsOnEvents
|
|
18
|
-
]), p ? /* @__PURE__ */ c(
|
|
18
|
+
]), p ? /* @__PURE__ */ c(i, {
|
|
19
19
|
title: "Geofencing Settings",
|
|
20
20
|
description: "Configure geofencing preferences",
|
|
21
|
-
children: /* @__PURE__ */ c(
|
|
22
|
-
}) : m ? /* @__PURE__ */ c(
|
|
21
|
+
children: /* @__PURE__ */ c(t, { variant: "detail" })
|
|
22
|
+
}) : m ? /* @__PURE__ */ c(i, {
|
|
23
23
|
title: "Geofencing Settings",
|
|
24
24
|
description: "Configure geofencing preferences",
|
|
25
25
|
children: /* @__PURE__ */ c("div", {
|
|
26
|
-
className: "rounded-lg border border-
|
|
26
|
+
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
27
27
|
children: "Failed to load geofencing settings. Please try again later."
|
|
28
28
|
})
|
|
29
|
-
}) : /* @__PURE__ */ c(
|
|
29
|
+
}) : /* @__PURE__ */ c(i, {
|
|
30
30
|
title: "Geofencing Settings",
|
|
31
31
|
description: "Configure geofencing preferences",
|
|
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-card p-6",
|
|
35
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop 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-
|
|
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-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\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-seam bg-gloss-card shadow-pop p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n 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;aAAoG;GAE7G,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,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"}
|