@burdenoff/microfe-timecampus 2026.625.1 → 2026.626.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/timecampus/components/EmptyState.js +14 -0
- package/dist/timecampus/components/EmptyState.js.map +1 -0
- package/dist/timecampus/components/PageLayout.js +23 -15
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +33 -30
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +37 -31
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +48 -44
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +35 -31
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +27 -24
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +46 -38
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +66 -39
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js +42 -36
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +35 -31
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +31 -25
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +43 -35
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +55 -51
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +32 -28
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +32 -25
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +29 -25
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +32 -29
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +29 -25
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +39 -35
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +33 -29
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +122 -104
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js +42 -32
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +2 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +145 -114
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +49 -45
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +28 -24
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +109 -78
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js +11 -7
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js +40 -30
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +50 -46
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +18 -14
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +41 -35
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js +91 -61
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +40 -36
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +33 -29
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +17 -13
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +67 -49
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +34 -31
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js +48 -39
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +65 -64
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +103 -69
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +53 -49
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +65 -47
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +38 -31
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +2 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +35 -31
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +43 -33
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,160 +1,191 @@
|
|
|
1
|
-
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
-
import { StatCard as
|
|
3
|
-
import { LoadingSkeleton as
|
|
4
|
-
import { useCompletePomodoroSessionMutation as
|
|
5
|
-
import { PageLayout as
|
|
6
|
-
import { useCallback as
|
|
7
|
-
import { Pause as
|
|
8
|
-
import { jsx as
|
|
1
|
+
import { useTimeCampus as e, useTimeCampusNavigate as t } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { StatCard as n } from "../../components/StatCard.js";
|
|
3
|
+
import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useCompletePomodoroSessionMutation as i, useGetActivePomodoroSessionQuery as a, useGetPomodoroStatsQuery as o, useStartPomodoroSessionMutation as s } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { PageLayout as c } from "../../components/PageLayout.js";
|
|
6
|
+
import { useCallback as l, useEffect as u, useState as d } from "react";
|
|
7
|
+
import { Pause as f, Play as p, RotateCcw as m, SkipForward as h } from "lucide-react";
|
|
8
|
+
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
9
|
+
import { GlassCard as v, NextSteps as y } from "@burdenoff/fe-libs/ui";
|
|
9
10
|
//#region src/timecampus/pages/pomodoro/PomodoroPage.tsx
|
|
10
|
-
function
|
|
11
|
-
let { workspaceId:
|
|
12
|
-
variables: { workspaceId:
|
|
13
|
-
skip: !
|
|
14
|
-
}), { data:
|
|
15
|
-
variables: { workspaceId:
|
|
16
|
-
skip: !
|
|
17
|
-
}), [
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
let e = Math.floor((Date.now() - new Date(
|
|
21
|
-
|
|
11
|
+
function b() {
|
|
12
|
+
let { workspaceId: b = "" } = e(), x = t(), { data: S, loading: C, error: w } = o({
|
|
13
|
+
variables: { workspaceId: b },
|
|
14
|
+
skip: !b
|
|
15
|
+
}), { data: T, loading: E, error: D } = a({
|
|
16
|
+
variables: { workspaceId: b },
|
|
17
|
+
skip: !b
|
|
18
|
+
}), [O] = s(), [k] = i(), A = S?.pomodoroStats, j = T?.activePomodoroSession, [M, N] = d(1500), [P, F] = d(!1);
|
|
19
|
+
u(() => {
|
|
20
|
+
if (j && !j.completed) {
|
|
21
|
+
let e = Math.floor((Date.now() - new Date(j.startTime).getTime()) / 1e3), t = j.duration ?? 1500, n = Math.max(0, t - e);
|
|
22
|
+
N(n), F(n > 0);
|
|
22
23
|
}
|
|
23
|
-
}, [
|
|
24
|
-
if (!
|
|
24
|
+
}, [j]), u(() => {
|
|
25
|
+
if (!P || M <= 0) return;
|
|
25
26
|
let e = setInterval(() => {
|
|
26
|
-
|
|
27
|
+
N((e) => e <= 1 ? (F(!1), 0) : e - 1);
|
|
27
28
|
}, 1e3);
|
|
28
29
|
return () => clearInterval(e);
|
|
29
|
-
}, [
|
|
30
|
-
let
|
|
30
|
+
}, [P, M]);
|
|
31
|
+
let I = (e) => {
|
|
31
32
|
let t = Math.floor(e / 60), n = e % 60;
|
|
32
33
|
return `${String(t).padStart(2, "0")}:${String(n).padStart(2, "0")}`;
|
|
33
|
-
},
|
|
34
|
-
if (
|
|
35
|
-
if (
|
|
36
|
-
|
|
34
|
+
}, L = l(async () => {
|
|
35
|
+
if (b) {
|
|
36
|
+
if (j && !j.completed) {
|
|
37
|
+
F(!0);
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
39
|
-
await
|
|
40
|
+
await O({
|
|
40
41
|
variables: { input: {
|
|
41
|
-
workspaceId:
|
|
42
|
+
workspaceId: b,
|
|
42
43
|
type: "FOCUS"
|
|
43
44
|
} },
|
|
44
45
|
refetchQueries: ["GetActivePomodoroSession", "GetPomodoroStats"]
|
|
45
|
-
}),
|
|
46
|
+
}), N(1500), F(!0);
|
|
46
47
|
}
|
|
47
48
|
}, [
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
]),
|
|
52
|
-
!
|
|
49
|
+
b,
|
|
50
|
+
j,
|
|
51
|
+
O
|
|
52
|
+
]), R = l(async () => {
|
|
53
|
+
!j || !b || (await k({
|
|
53
54
|
variables: {
|
|
54
|
-
id:
|
|
55
|
-
workspaceId:
|
|
55
|
+
id: j.id,
|
|
56
|
+
workspaceId: b
|
|
56
57
|
},
|
|
57
58
|
refetchQueries: ["GetActivePomodoroSession", "GetPomodoroStats"]
|
|
58
|
-
}),
|
|
59
|
+
}), F(!1), N(1500));
|
|
59
60
|
}, [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]),
|
|
64
|
-
|
|
61
|
+
j,
|
|
62
|
+
b,
|
|
63
|
+
k
|
|
64
|
+
]), z = () => {
|
|
65
|
+
F(!1), N(1500);
|
|
65
66
|
};
|
|
66
|
-
if (
|
|
67
|
+
if (C || E) return /* @__PURE__ */ g(c, {
|
|
67
68
|
title: "Pomodoro Timer",
|
|
68
69
|
description: "Focus with the Pomodoro Technique",
|
|
69
|
-
children: /* @__PURE__ */
|
|
70
|
+
children: /* @__PURE__ */ g(r, {
|
|
70
71
|
variant: "card",
|
|
71
72
|
count: 3
|
|
72
73
|
})
|
|
73
74
|
});
|
|
74
|
-
if (
|
|
75
|
+
if (w || D) return /* @__PURE__ */ g(c, {
|
|
75
76
|
title: "Pomodoro Timer",
|
|
76
77
|
description: "Focus with the Pomodoro Technique",
|
|
77
|
-
children: /* @__PURE__ */
|
|
78
|
+
children: /* @__PURE__ */ g("div", {
|
|
78
79
|
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
79
80
|
children: "Failed to load pomodoro data. Please try again later."
|
|
80
81
|
})
|
|
81
82
|
});
|
|
82
|
-
let
|
|
83
|
-
return /* @__PURE__ */
|
|
83
|
+
let B = Math.floor((A?.totalFocusMinutes ?? 0) / 60), V = (A?.totalFocusMinutes ?? 0) % 60;
|
|
84
|
+
return /* @__PURE__ */ _(c, {
|
|
84
85
|
title: "Pomodoro Timer",
|
|
85
86
|
description: "Focus with the Pomodoro Technique",
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
87
|
+
purpose: "Work in focused 25-minute sprints with short breaks — the Pomodoro technique helps you beat procrastination and build a streak of deep-work sessions you can actually measure.",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ g(y, {
|
|
90
|
+
storageKey: "timecampus-pomodoro",
|
|
91
|
+
className: "mb-6",
|
|
92
|
+
steps: [
|
|
93
|
+
{
|
|
94
|
+
id: "start",
|
|
95
|
+
label: "Start a focus session",
|
|
96
|
+
description: "Begin a 25-minute sprint on one task.",
|
|
97
|
+
onClick: () => L()
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: "analytics",
|
|
101
|
+
label: "Review your pomodoro stats",
|
|
102
|
+
description: "See streaks, completion rate and focus time.",
|
|
103
|
+
onClick: () => x("/pomodoro/analytics")
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "settings",
|
|
107
|
+
label: "Tune your intervals",
|
|
108
|
+
description: "Adjust focus and break lengths to fit you.",
|
|
109
|
+
onClick: () => x("/pomodoro/settings")
|
|
100
110
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
description: `Avg: ${E?.averageSessionMinutes ?? 0}m per session`
|
|
106
|
-
})
|
|
107
|
-
]
|
|
108
|
-
}), /* @__PURE__ */ h("div", {
|
|
109
|
-
className: "mx-auto max-w-md",
|
|
110
|
-
children: /* @__PURE__ */ g("div", {
|
|
111
|
-
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-8 text-center",
|
|
111
|
+
]
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ _("div", {
|
|
114
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
112
115
|
children: [
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
children: D ? "Focus Session" : "Ready"
|
|
118
|
-
})
|
|
119
|
-
}),
|
|
120
|
-
/* @__PURE__ */ h("p", {
|
|
121
|
-
className: "text-7xl font-mono font-bold text-text-primary",
|
|
122
|
-
children: M(O)
|
|
116
|
+
/* @__PURE__ */ g(n, {
|
|
117
|
+
title: "Sessions Today",
|
|
118
|
+
value: String(A?.completedSessions ?? 0),
|
|
119
|
+
description: `Total: ${A?.totalSessions ?? 0} sessions`
|
|
123
120
|
}),
|
|
124
|
-
/* @__PURE__ */
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
/* @__PURE__ */ g(n, {
|
|
122
|
+
title: "Focus Time",
|
|
123
|
+
value: `${B}h ${V}m`,
|
|
124
|
+
trend: {
|
|
125
|
+
value: A?.completionRate ?? 0,
|
|
126
|
+
label: "completion rate"
|
|
127
|
+
}
|
|
127
128
|
}),
|
|
128
|
-
/* @__PURE__ */ g(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
onClick: () => j(!1),
|
|
133
|
-
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
134
|
-
children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), "Pause"]
|
|
135
|
-
}) : /* @__PURE__ */ g("button", {
|
|
136
|
-
onClick: N,
|
|
137
|
-
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
138
|
-
children: [/* @__PURE__ */ h(f, { className: "h-4 w-4" }), "Start"]
|
|
139
|
-
}),
|
|
140
|
-
/* @__PURE__ */ g("button", {
|
|
141
|
-
onClick: P,
|
|
142
|
-
className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
143
|
-
children: [/* @__PURE__ */ h(m, { className: "h-4 w-4" }), "Skip"]
|
|
144
|
-
}),
|
|
145
|
-
/* @__PURE__ */ g("button", {
|
|
146
|
-
onClick: F,
|
|
147
|
-
className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
148
|
-
children: [/* @__PURE__ */ h(p, { className: "h-4 w-4" }), "Reset"]
|
|
149
|
-
})
|
|
150
|
-
]
|
|
129
|
+
/* @__PURE__ */ g(n, {
|
|
130
|
+
title: "Current Streak",
|
|
131
|
+
value: `${A?.streakDays ?? 0} days`,
|
|
132
|
+
description: `Avg: ${A?.averageSessionMinutes ?? 0}m per session`
|
|
151
133
|
})
|
|
152
134
|
]
|
|
135
|
+
}),
|
|
136
|
+
/* @__PURE__ */ g("div", {
|
|
137
|
+
className: "mx-auto max-w-md",
|
|
138
|
+
children: /* @__PURE__ */ _(v, {
|
|
139
|
+
treatment: "glass",
|
|
140
|
+
glow: !0,
|
|
141
|
+
className: "p-8 text-center",
|
|
142
|
+
children: [
|
|
143
|
+
/* @__PURE__ */ g("div", {
|
|
144
|
+
className: "mb-2",
|
|
145
|
+
children: /* @__PURE__ */ g("span", {
|
|
146
|
+
className: "inline-flex rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
|
|
147
|
+
children: j ? "Focus Session" : "Ready"
|
|
148
|
+
})
|
|
149
|
+
}),
|
|
150
|
+
/* @__PURE__ */ g("p", {
|
|
151
|
+
className: "text-7xl font-mono font-bold text-text-primary",
|
|
152
|
+
children: I(M)
|
|
153
|
+
}),
|
|
154
|
+
/* @__PURE__ */ g("p", {
|
|
155
|
+
className: "mt-2 text-sm text-text-secondary",
|
|
156
|
+
children: A ? `${A.completedSessions} of ${A.totalSessions} sessions` : "No sessions yet"
|
|
157
|
+
}),
|
|
158
|
+
/* @__PURE__ */ _("div", {
|
|
159
|
+
className: "mt-6 flex items-center justify-center gap-3",
|
|
160
|
+
children: [
|
|
161
|
+
P ? /* @__PURE__ */ _("button", {
|
|
162
|
+
onClick: () => F(!1),
|
|
163
|
+
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
164
|
+
children: [/* @__PURE__ */ g(f, { className: "h-4 w-4" }), "Pause"]
|
|
165
|
+
}) : /* @__PURE__ */ _("button", {
|
|
166
|
+
onClick: L,
|
|
167
|
+
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
168
|
+
children: [/* @__PURE__ */ g(p, { className: "h-4 w-4" }), "Start"]
|
|
169
|
+
}),
|
|
170
|
+
/* @__PURE__ */ _("button", {
|
|
171
|
+
onClick: R,
|
|
172
|
+
className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
173
|
+
children: [/* @__PURE__ */ g(h, { className: "h-4 w-4" }), "Skip"]
|
|
174
|
+
}),
|
|
175
|
+
/* @__PURE__ */ _("button", {
|
|
176
|
+
onClick: z,
|
|
177
|
+
className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
178
|
+
children: [/* @__PURE__ */ g(m, { className: "h-4 w-4" }), "Reset"]
|
|
179
|
+
})
|
|
180
|
+
]
|
|
181
|
+
})
|
|
182
|
+
]
|
|
183
|
+
})
|
|
153
184
|
})
|
|
154
|
-
|
|
185
|
+
]
|
|
155
186
|
});
|
|
156
187
|
}
|
|
157
188
|
//#endregion
|
|
158
|
-
export {
|
|
189
|
+
export { b as PomodoroPage };
|
|
159
190
|
|
|
160
191
|
//# sourceMappingURL=PomodoroPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PomodoroPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Play, Pause, SkipForward, RotateCcw } 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 useGetActivePomodoroSessionQuery,\n useGetPomodoroStatsQuery,\n useStartPomodoroSessionMutation,\n useCompletePomodoroSessionMutation,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetPomodoroStatsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const {\n data: activeData,\n loading: activeLoading,\n error: activeError,\n } = useGetActivePomodoroSessionQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const [startSession] = useStartPomodoroSessionMutation();\n const [completeSession] = useCompletePomodoroSessionMutation();\n\n const stats = statsData?.pomodoroStats;\n const activeSession = activeData?.activePomodoroSession;\n\n const [timerSeconds, setTimerSeconds] = useState(25 * 60);\n const [isRunning, setIsRunning] = useState(false);\n\n useEffect(() => {\n if (activeSession && !activeSession.completed) {\n const elapsed = Math.floor(\n (Date.now() - new Date(activeSession.startTime).getTime()) / 1000,\n );\n const duration = activeSession.duration ?? 25 * 60;\n const remaining = Math.max(0, duration - elapsed);\n setTimerSeconds(remaining);\n setIsRunning(remaining > 0);\n }\n }, [activeSession]);\n\n useEffect(() => {\n if (!isRunning || timerSeconds <= 0) return;\n const interval = setInterval(() => {\n setTimerSeconds((prev) => {\n if (prev <= 1) {\n setIsRunning(false);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n return () => clearInterval(interval);\n }, [isRunning, timerSeconds]);\n\n const formatTimer = (seconds: number) => {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return `${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n };\n\n const handleStart = useCallback(async () => {\n if (!workspaceId) return;\n if (activeSession && !activeSession.completed) {\n setIsRunning(true);\n return;\n }\n await startSession({\n variables: { input: { workspaceId, type: \"FOCUS\" as never } },\n refetchQueries: [\"GetActivePomodoroSession\", \"GetPomodoroStats\"],\n });\n setTimerSeconds(25 * 60);\n setIsRunning(true);\n }, [workspaceId, activeSession, startSession]);\n\n const handleComplete = useCallback(async () => {\n if (!activeSession || !workspaceId) return;\n await completeSession({\n variables: { id: activeSession.id, workspaceId },\n refetchQueries: [\"GetActivePomodoroSession\", \"GetPomodoroStats\"],\n });\n setIsRunning(false);\n setTimerSeconds(25 * 60);\n }, [activeSession, workspaceId, completeSession]);\n\n const handleReset = () => {\n setIsRunning(false);\n setTimerSeconds(25 * 60);\n };\n\n if (statsLoading || activeLoading) {\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\n >\n <LoadingSkeleton variant=\"card\" count={3} />\n </PageLayout>\n );\n }\n\n if (statsError || activeError) {\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\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 pomodoro data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalFocusH = Math.floor((stats?.totalFocusMinutes ?? 0) / 60);\n const totalFocusM = (stats?.totalFocusMinutes ?? 0) % 60;\n\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <StatCard\n title=\"Sessions Today\"\n value={String(stats?.completedSessions ?? 0)}\n description={`Total: ${stats?.totalSessions ?? 0} sessions`}\n />\n <StatCard\n title=\"Focus Time\"\n value={`${totalFocusH}h ${totalFocusM}m`}\n trend={{\n value: stats?.completionRate ?? 0,\n label: \"completion rate\",\n }}\n />\n <StatCard\n title=\"Current Streak\"\n value={`${stats?.streakDays ?? 0} days`}\n description={`Avg: ${stats?.averageSessionMinutes ?? 0}m per session`}\n />\n </div>\n\n <div className=\"mx-auto max-w-md\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-8 text-center\">\n <div className=\"mb-2\">\n <span className=\"inline-flex rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\">\n {activeSession ? \"Focus Session\" : \"Ready\"}\n </span>\n </div>\n <p className=\"text-7xl font-mono font-bold text-text-primary\">\n {formatTimer(timerSeconds)}\n </p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {stats\n ? `${stats.completedSessions} of ${stats.totalSessions} sessions`\n : \"No sessions yet\"}\n </p>\n <div className=\"mt-6 flex items-center justify-center gap-3\">\n {!isRunning ? (\n <button\n onClick={handleStart}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Play className=\"h-4 w-4\" />\n Start\n </button>\n ) : (\n <button\n onClick={() => setIsRunning(false)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Pause className=\"h-4 w-4\" />\n Pause\n </button>\n )}\n <button\n onClick={handleComplete}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <SkipForward className=\"h-4 w-4\" />\n Skip\n </button>\n <button\n onClick={handleReset}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </button>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PomodoroPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Play, Pause, SkipForward, RotateCcw } from \"lucide-react\";\nimport { GlassCard, NextSteps } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n useTimeCampus,\n useTimeCampusNavigate,\n} from \"../../providers/TimeCampusProvider\";\nimport {\n useGetActivePomodoroSessionQuery,\n useGetPomodoroStatsQuery,\n useStartPomodoroSessionMutation,\n useCompletePomodoroSessionMutation,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const navigate = useTimeCampusNavigate();\n\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetPomodoroStatsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const {\n data: activeData,\n loading: activeLoading,\n error: activeError,\n } = useGetActivePomodoroSessionQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const [startSession] = useStartPomodoroSessionMutation();\n const [completeSession] = useCompletePomodoroSessionMutation();\n\n const stats = statsData?.pomodoroStats;\n const activeSession = activeData?.activePomodoroSession;\n\n const [timerSeconds, setTimerSeconds] = useState(25 * 60);\n const [isRunning, setIsRunning] = useState(false);\n\n useEffect(() => {\n if (activeSession && !activeSession.completed) {\n const elapsed = Math.floor(\n (Date.now() - new Date(activeSession.startTime).getTime()) / 1000,\n );\n const duration = activeSession.duration ?? 25 * 60;\n const remaining = Math.max(0, duration - elapsed);\n setTimerSeconds(remaining);\n setIsRunning(remaining > 0);\n }\n }, [activeSession]);\n\n useEffect(() => {\n if (!isRunning || timerSeconds <= 0) return;\n const interval = setInterval(() => {\n setTimerSeconds((prev) => {\n if (prev <= 1) {\n setIsRunning(false);\n return 0;\n }\n return prev - 1;\n });\n }, 1000);\n return () => clearInterval(interval);\n }, [isRunning, timerSeconds]);\n\n const formatTimer = (seconds: number) => {\n const m = Math.floor(seconds / 60);\n const s = seconds % 60;\n return `${String(m).padStart(2, \"0\")}:${String(s).padStart(2, \"0\")}`;\n };\n\n const handleStart = useCallback(async () => {\n if (!workspaceId) return;\n if (activeSession && !activeSession.completed) {\n setIsRunning(true);\n return;\n }\n await startSession({\n variables: { input: { workspaceId, type: \"FOCUS\" as never } },\n refetchQueries: [\"GetActivePomodoroSession\", \"GetPomodoroStats\"],\n });\n setTimerSeconds(25 * 60);\n setIsRunning(true);\n }, [workspaceId, activeSession, startSession]);\n\n const handleComplete = useCallback(async () => {\n if (!activeSession || !workspaceId) return;\n await completeSession({\n variables: { id: activeSession.id, workspaceId },\n refetchQueries: [\"GetActivePomodoroSession\", \"GetPomodoroStats\"],\n });\n setIsRunning(false);\n setTimerSeconds(25 * 60);\n }, [activeSession, workspaceId, completeSession]);\n\n const handleReset = () => {\n setIsRunning(false);\n setTimerSeconds(25 * 60);\n };\n\n if (statsLoading || activeLoading) {\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\n >\n <LoadingSkeleton variant=\"card\" count={3} />\n </PageLayout>\n );\n }\n\n if (statsError || activeError) {\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\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 pomodoro data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n const totalFocusH = Math.floor((stats?.totalFocusMinutes ?? 0) / 60);\n const totalFocusM = (stats?.totalFocusMinutes ?? 0) % 60;\n\n return (\n <PageLayout\n title=\"Pomodoro Timer\"\n description=\"Focus with the Pomodoro Technique\"\n purpose=\"Work in focused 25-minute sprints with short breaks — the Pomodoro technique helps you beat procrastination and build a streak of deep-work sessions you can actually measure.\"\n >\n <NextSteps\n storageKey=\"timecampus-pomodoro\"\n className=\"mb-6\"\n steps={[\n {\n id: \"start\",\n label: \"Start a focus session\",\n description: \"Begin a 25-minute sprint on one task.\",\n onClick: () => handleStart(),\n },\n {\n id: \"analytics\",\n label: \"Review your pomodoro stats\",\n description: \"See streaks, completion rate and focus time.\",\n onClick: () => navigate(\"/pomodoro/analytics\"),\n },\n {\n id: \"settings\",\n label: \"Tune your intervals\",\n description: \"Adjust focus and break lengths to fit you.\",\n onClick: () => navigate(\"/pomodoro/settings\"),\n },\n ]}\n />\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <StatCard\n title=\"Sessions Today\"\n value={String(stats?.completedSessions ?? 0)}\n description={`Total: ${stats?.totalSessions ?? 0} sessions`}\n />\n <StatCard\n title=\"Focus Time\"\n value={`${totalFocusH}h ${totalFocusM}m`}\n trend={{\n value: stats?.completionRate ?? 0,\n label: \"completion rate\",\n }}\n />\n <StatCard\n title=\"Current Streak\"\n value={`${stats?.streakDays ?? 0} days`}\n description={`Avg: ${stats?.averageSessionMinutes ?? 0}m per session`}\n />\n </div>\n\n <div className=\"mx-auto max-w-md\">\n <GlassCard treatment=\"glass\" glow className=\"p-8 text-center\">\n <div className=\"mb-2\">\n <span className=\"inline-flex rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary\">\n {activeSession ? \"Focus Session\" : \"Ready\"}\n </span>\n </div>\n <p className=\"text-7xl font-mono font-bold text-text-primary\">\n {formatTimer(timerSeconds)}\n </p>\n <p className=\"mt-2 text-sm text-text-secondary\">\n {stats\n ? `${stats.completedSessions} of ${stats.totalSessions} sessions`\n : \"No sessions yet\"}\n </p>\n <div className=\"mt-6 flex items-center justify-center gap-3\">\n {!isRunning ? (\n <button\n onClick={handleStart}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Play className=\"h-4 w-4\" />\n Start\n </button>\n ) : (\n <button\n onClick={() => setIsRunning(false)}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-6 py-3 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Pause className=\"h-4 w-4\" />\n Pause\n </button>\n )}\n <button\n onClick={handleComplete}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <SkipForward className=\"h-4 w-4\" />\n Skip\n </button>\n <button\n onClick={handleReset}\n className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-3 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </button>\n </div>\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -5,43 +5,44 @@ import { PageLayout as i } from "../../components/PageLayout.js";
|
|
|
5
5
|
import { useCallback as a, useEffect as o, useState as s } from "react";
|
|
6
6
|
import { Settings as c } from "lucide-react";
|
|
7
7
|
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
import { GlassCard as d } from "@burdenoff/fe-libs/ui";
|
|
8
9
|
//#region src/timecampus/pages/pomodoro/PomodoroSettingsPage.tsx
|
|
9
|
-
function
|
|
10
|
-
let { workspaceId:
|
|
11
|
-
variables: { workspaceId:
|
|
12
|
-
skip: !
|
|
13
|
-
}), [
|
|
10
|
+
function f() {
|
|
11
|
+
let { workspaceId: f = "" } = e(), { data: p, loading: m, error: h } = n({
|
|
12
|
+
variables: { workspaceId: f },
|
|
13
|
+
skip: !f
|
|
14
|
+
}), [g, { loading: _ }] = r(), v = p?.pomodoroSettings, [y, b] = s(25), [x, S] = s(5), [C, w] = s(15), [T, E] = s(!0), [D, O] = s(!0), [k, A] = s(!1);
|
|
14
15
|
o(() => {
|
|
15
|
-
|
|
16
|
-
}, [
|
|
17
|
-
let
|
|
18
|
-
|
|
16
|
+
v && (b(v.focusDuration), S(v.shortBreakDuration), w(v.longBreakDuration), E(v.soundEnabled), O(v.notificationsEnabled), A(v.autoStartBreaks));
|
|
17
|
+
}, [v]);
|
|
18
|
+
let j = a(async () => {
|
|
19
|
+
f && await g({
|
|
19
20
|
variables: { input: {
|
|
20
|
-
workspaceId:
|
|
21
|
-
focusDuration:
|
|
22
|
-
shortBreakDuration:
|
|
23
|
-
longBreakDuration:
|
|
24
|
-
soundEnabled:
|
|
25
|
-
notificationsEnabled:
|
|
26
|
-
autoStartBreaks:
|
|
21
|
+
workspaceId: f,
|
|
22
|
+
focusDuration: y,
|
|
23
|
+
shortBreakDuration: x,
|
|
24
|
+
longBreakDuration: C,
|
|
25
|
+
soundEnabled: T,
|
|
26
|
+
notificationsEnabled: D,
|
|
27
|
+
autoStartBreaks: k
|
|
27
28
|
} },
|
|
28
29
|
refetchQueries: ["GetPomodoroSettings"]
|
|
29
30
|
});
|
|
30
31
|
}, [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
f,
|
|
33
|
+
y,
|
|
34
|
+
x,
|
|
35
|
+
C,
|
|
36
|
+
T,
|
|
37
|
+
D,
|
|
38
|
+
k,
|
|
39
|
+
g
|
|
39
40
|
]);
|
|
40
|
-
return
|
|
41
|
+
return m ? /* @__PURE__ */ l(i, {
|
|
41
42
|
title: "Pomodoro Settings",
|
|
42
43
|
description: "Configure your Pomodoro timer preferences",
|
|
43
44
|
children: /* @__PURE__ */ l(t, { variant: "detail" })
|
|
44
|
-
}) :
|
|
45
|
+
}) : h ? /* @__PURE__ */ l(i, {
|
|
45
46
|
title: "Pomodoro Settings",
|
|
46
47
|
description: "Configure your Pomodoro timer preferences",
|
|
47
48
|
children: /* @__PURE__ */ l("div", {
|
|
@@ -51,11 +52,14 @@ function d() {
|
|
|
51
52
|
}) : /* @__PURE__ */ l(i, {
|
|
52
53
|
title: "Pomodoro Settings",
|
|
53
54
|
description: "Configure your Pomodoro timer preferences",
|
|
55
|
+
purpose: "Shape the Pomodoro technique around how you actually work — set focus and break lengths and decide how you're nudged — so the timer fits your rhythm instead of fighting it.",
|
|
54
56
|
children: /* @__PURE__ */ u("div", {
|
|
55
57
|
className: "mx-auto max-w-2xl space-y-6",
|
|
56
58
|
children: [
|
|
57
|
-
/* @__PURE__ */ u(
|
|
58
|
-
|
|
59
|
+
/* @__PURE__ */ u(d, {
|
|
60
|
+
treatment: "glass",
|
|
61
|
+
glow: !0,
|
|
62
|
+
className: "p-6",
|
|
59
63
|
children: [/* @__PURE__ */ u("h3", {
|
|
60
64
|
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
61
65
|
children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Timer Durations"]
|
|
@@ -72,8 +76,8 @@ function d() {
|
|
|
72
76
|
children: "Length of each focus session"
|
|
73
77
|
})] }), /* @__PURE__ */ l("input", {
|
|
74
78
|
type: "number",
|
|
75
|
-
value:
|
|
76
|
-
onChange: (e) =>
|
|
79
|
+
value: y,
|
|
80
|
+
onChange: (e) => b(Number(e.target.value)),
|
|
77
81
|
className: "w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right"
|
|
78
82
|
})]
|
|
79
83
|
}),
|
|
@@ -87,8 +91,8 @@ function d() {
|
|
|
87
91
|
children: "Break between focus sessions"
|
|
88
92
|
})] }), /* @__PURE__ */ l("input", {
|
|
89
93
|
type: "number",
|
|
90
|
-
value:
|
|
91
|
-
onChange: (e) =>
|
|
94
|
+
value: x,
|
|
95
|
+
onChange: (e) => S(Number(e.target.value)),
|
|
92
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"
|
|
93
97
|
})]
|
|
94
98
|
}),
|
|
@@ -102,8 +106,8 @@ function d() {
|
|
|
102
106
|
children: "After every 4 focus sessions"
|
|
103
107
|
})] }), /* @__PURE__ */ l("input", {
|
|
104
108
|
type: "number",
|
|
105
|
-
value:
|
|
106
|
-
onChange: (e) =>
|
|
109
|
+
value: C,
|
|
110
|
+
onChange: (e) => w(Number(e.target.value)),
|
|
107
111
|
className: "w-20 rounded-md border border-border-subtle bg-bg-surface px-3 py-1.5 text-sm text-text-primary text-right"
|
|
108
112
|
})]
|
|
109
113
|
})
|
|
@@ -111,7 +115,7 @@ function d() {
|
|
|
111
115
|
})]
|
|
112
116
|
}),
|
|
113
117
|
/* @__PURE__ */ u("div", {
|
|
114
|
-
className: "rounded-xl border border-border-seam bg-
|
|
118
|
+
className: "rounded-xl border border-border-seam bg-bg-surface shadow-elevation-1 p-6",
|
|
115
119
|
children: [/* @__PURE__ */ l("h3", {
|
|
116
120
|
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
117
121
|
children: "Notifications"
|
|
@@ -125,8 +129,8 @@ function d() {
|
|
|
125
129
|
children: "Sound alerts"
|
|
126
130
|
}), /* @__PURE__ */ l("input", {
|
|
127
131
|
type: "checkbox",
|
|
128
|
-
checked:
|
|
129
|
-
onChange: (e) =>
|
|
132
|
+
checked: T,
|
|
133
|
+
onChange: (e) => E(e.target.checked),
|
|
130
134
|
className: "h-4 w-4 rounded border-border-subtle"
|
|
131
135
|
})]
|
|
132
136
|
}),
|
|
@@ -137,8 +141,8 @@ function d() {
|
|
|
137
141
|
children: "Desktop notifications"
|
|
138
142
|
}), /* @__PURE__ */ l("input", {
|
|
139
143
|
type: "checkbox",
|
|
140
|
-
checked:
|
|
141
|
-
onChange: (e) =>
|
|
144
|
+
checked: D,
|
|
145
|
+
onChange: (e) => O(e.target.checked),
|
|
142
146
|
className: "h-4 w-4 rounded border-border-subtle"
|
|
143
147
|
})]
|
|
144
148
|
}),
|
|
@@ -149,8 +153,8 @@ function d() {
|
|
|
149
153
|
children: "Auto-start breaks"
|
|
150
154
|
}), /* @__PURE__ */ l("input", {
|
|
151
155
|
type: "checkbox",
|
|
152
|
-
checked:
|
|
153
|
-
onChange: (e) =>
|
|
156
|
+
checked: k,
|
|
157
|
+
onChange: (e) => A(e.target.checked),
|
|
154
158
|
className: "h-4 w-4 rounded border-border-subtle"
|
|
155
159
|
})]
|
|
156
160
|
})
|
|
@@ -160,10 +164,10 @@ function d() {
|
|
|
160
164
|
/* @__PURE__ */ l("div", {
|
|
161
165
|
className: "flex justify-end",
|
|
162
166
|
children: /* @__PURE__ */ l("button", {
|
|
163
|
-
onClick:
|
|
164
|
-
disabled:
|
|
167
|
+
onClick: j,
|
|
168
|
+
disabled: _,
|
|
165
169
|
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",
|
|
166
|
-
children:
|
|
170
|
+
children: _ ? "Saving..." : "Save Settings"
|
|
167
171
|
})
|
|
168
172
|
})
|
|
169
173
|
]
|
|
@@ -171,6 +175,6 @@ function d() {
|
|
|
171
175
|
});
|
|
172
176
|
}
|
|
173
177
|
//#endregion
|
|
174
|
-
export {
|
|
178
|
+
export { f as PomodoroSettingsPage };
|
|
175
179
|
|
|
176
180
|
//# sourceMappingURL=PomodoroSettingsPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PomodoroSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroSettingsPage.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 useGetPomodoroSettingsQuery,\n useUpdatePomodoroSettingsMutation,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetPomodoroSettingsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const [updateSettings, { loading: saving }] =\n useUpdatePomodoroSettingsMutation();\n\n const settings = data?.pomodoroSettings;\n\n const [focusDuration, setFocusDuration] = useState(25);\n const [shortBreak, setShortBreak] = useState(5);\n const [longBreak, setLongBreak] = useState(15);\n const [soundEnabled, setSoundEnabled] = useState(true);\n const [notificationsEnabled, setNotificationsEnabled] = useState(true);\n const [autoStartBreaks, setAutoStartBreaks] = useState(false);\n\n useEffect(() => {\n if (settings) {\n setFocusDuration(settings.focusDuration);\n setShortBreak(settings.shortBreakDuration);\n setLongBreak(settings.longBreakDuration);\n setSoundEnabled(settings.soundEnabled);\n setNotificationsEnabled(settings.notificationsEnabled);\n setAutoStartBreaks(settings.autoStartBreaks);\n }\n }, [settings]);\n\n const handleSave = useCallback(async () => {\n if (!workspaceId) return;\n await updateSettings({\n variables: {\n input: {\n workspaceId,\n focusDuration,\n shortBreakDuration: shortBreak,\n longBreakDuration: longBreak,\n soundEnabled,\n notificationsEnabled,\n autoStartBreaks,\n },\n },\n refetchQueries: [\"GetPomodoroSettings\"],\n });\n }, [\n workspaceId,\n focusDuration,\n shortBreak,\n longBreak,\n soundEnabled,\n notificationsEnabled,\n autoStartBreaks,\n updateSettings,\n ]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer 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 settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer 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 Timer Durations\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 Focus Duration\n </p>\n <p className=\"text-xs text-text-secondary\">\n Length of each focus session\n </p>\n </div>\n <input\n type=\"number\"\n value={focusDuration}\n onChange={(e) => setFocusDuration(Number(e.target.value))}\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 Short Break\n </p>\n <p className=\"text-xs text-text-secondary\">\n Break between focus sessions\n </p>\n </div>\n <input\n type=\"number\"\n value={shortBreak}\n onChange={(e) => setShortBreak(Number(e.target.value))}\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 Long Break\n </p>\n <p className=\"text-xs text-text-secondary\">\n After every 4 focus sessions\n </p>\n </div>\n <input\n type=\"number\"\n value={longBreak}\n onChange={(e) => setLongBreak(Number(e.target.value))}\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\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 Notifications\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">Sound alerts</span>\n <input\n type=\"checkbox\"\n checked={soundEnabled}\n onChange={(e) => setSoundEnabled(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 Desktop notifications\n </span>\n <input\n type=\"checkbox\"\n checked={notificationsEnabled}\n onChange={(e) => setNotificationsEnabled(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-start breaks\n </span>\n <input\n type=\"checkbox\"\n checked={autoStartBreaks}\n onChange={(e) => setAutoStartBreaks(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PomodoroSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useGetPomodoroSettingsQuery,\n useUpdatePomodoroSettingsMutation,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetPomodoroSettingsQuery({\n variables: { workspaceId },\n skip: !workspaceId,\n });\n\n const [updateSettings, { loading: saving }] =\n useUpdatePomodoroSettingsMutation();\n\n const settings = data?.pomodoroSettings;\n\n const [focusDuration, setFocusDuration] = useState(25);\n const [shortBreak, setShortBreak] = useState(5);\n const [longBreak, setLongBreak] = useState(15);\n const [soundEnabled, setSoundEnabled] = useState(true);\n const [notificationsEnabled, setNotificationsEnabled] = useState(true);\n const [autoStartBreaks, setAutoStartBreaks] = useState(false);\n\n useEffect(() => {\n if (settings) {\n setFocusDuration(settings.focusDuration);\n setShortBreak(settings.shortBreakDuration);\n setLongBreak(settings.longBreakDuration);\n setSoundEnabled(settings.soundEnabled);\n setNotificationsEnabled(settings.notificationsEnabled);\n setAutoStartBreaks(settings.autoStartBreaks);\n }\n }, [settings]);\n\n const handleSave = useCallback(async () => {\n if (!workspaceId) return;\n await updateSettings({\n variables: {\n input: {\n workspaceId,\n focusDuration,\n shortBreakDuration: shortBreak,\n longBreakDuration: longBreak,\n soundEnabled,\n notificationsEnabled,\n autoStartBreaks,\n },\n },\n refetchQueries: [\"GetPomodoroSettings\"],\n });\n }, [\n workspaceId,\n focusDuration,\n shortBreak,\n longBreak,\n soundEnabled,\n notificationsEnabled,\n autoStartBreaks,\n updateSettings,\n ]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer preferences\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer 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 settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Pomodoro Settings\"\n description=\"Configure your Pomodoro timer preferences\"\n purpose=\"Shape the Pomodoro technique around how you actually work — set focus and break lengths and decide how you're nudged — so the timer fits your rhythm instead of fighting it.\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <GlassCard treatment=\"glass\" glow className=\"p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Timer Durations\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 Focus Duration\n </p>\n <p className=\"text-xs text-text-secondary\">\n Length of each focus session\n </p>\n </div>\n <input\n type=\"number\"\n value={focusDuration}\n onChange={(e) => setFocusDuration(Number(e.target.value))}\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 Short Break\n </p>\n <p className=\"text-xs text-text-secondary\">\n Break between focus sessions\n </p>\n </div>\n <input\n type=\"number\"\n value={shortBreak}\n onChange={(e) => setShortBreak(Number(e.target.value))}\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 Long Break\n </p>\n <p className=\"text-xs text-text-secondary\">\n After every 4 focus sessions\n </p>\n </div>\n <input\n type=\"number\"\n value={longBreak}\n onChange={(e) => setLongBreak(Number(e.target.value))}\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 </GlassCard>\n\n <div className=\"rounded-xl border border-border-seam bg-bg-surface shadow-elevation-1 p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Notifications\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">Sound alerts</span>\n <input\n type=\"checkbox\"\n checked={soundEnabled}\n onChange={(e) => setSoundEnabled(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 Desktop notifications\n </span>\n <input\n type=\"checkbox\"\n checked={notificationsEnabled}\n onChange={(e) => setNotificationsEnabled(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-start breaks\n </span>\n <input\n type=\"checkbox\"\n checked={autoStartBreaks}\n onChange={(e) => setAutoStartBreaks(e.target.checked)}\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|