@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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PomodoroAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, Target } 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 useGetPomodoroStatsQuery,\n useListPomodoroSessionsQuery,\n type PomodoroSessionFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroAnalyticsPage() {\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 { data: sessionsData, loading: sessionsLoading } =\n useListPomodoroSessionsQuery({\n variables: { workspaceId, limit: 50 },\n skip: !workspaceId,\n });\n\n const stats = statsData?.pomodoroStats;\n const sessions = sessionsData?.pomodoroSessions ?? [];\n\n if (statsLoading || sessionsLoading) {\n return (\n <PageLayout\n title=\"Pomodoro Analytics\"\n description=\"Track your focus sessions and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Pomodoro Analytics\"\n description=\"Track your focus sessions and productivity\"\n >\n <div className=\"rounded-lg border border-
|
|
1
|
+
{"version":3,"file":"PomodoroAnalyticsPage.js","names":[],"sources":["../../../../src/timecampus/pages/pomodoro/PomodoroAnalyticsPage.tsx"],"sourcesContent":["import { BarChart3, Target } 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 useGetPomodoroStatsQuery,\n useListPomodoroSessionsQuery,\n type PomodoroSessionFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function PomodoroAnalyticsPage() {\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 { data: sessionsData, loading: sessionsLoading } =\n useListPomodoroSessionsQuery({\n variables: { workspaceId, limit: 50 },\n skip: !workspaceId,\n });\n\n const stats = statsData?.pomodoroStats;\n const sessions = sessionsData?.pomodoroSessions ?? [];\n\n if (statsLoading || sessionsLoading) {\n return (\n <PageLayout\n title=\"Pomodoro Analytics\"\n description=\"Track your focus sessions and productivity\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (statsError) {\n return (\n <PageLayout\n title=\"Pomodoro Analytics\"\n description=\"Track your focus sessions and productivity\"\n >\n <div className=\"rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text\">\n Failed to load pomodoro analytics. 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 const avgSessions = stats?.totalSessions\n ? (stats.totalSessions / 30).toFixed(1)\n : \"0\";\n const completedCount = sessions.filter(\n (s: PomodoroSessionFieldsFragment) => s.completed,\n ).length;\n\n return (\n <PageLayout\n title=\"Pomodoro Analytics\"\n description=\"Track your focus sessions and productivity\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Total Sessions\"\n value={String(stats?.totalSessions ?? 0)}\n trend={{\n value: stats?.completionRate ?? 0,\n label: \"completion rate\",\n }}\n />\n <StatCard\n title=\"Total Focus Time\"\n value={`${totalFocusH}h ${totalFocusM}m`}\n trend={{\n value: stats?.averageSessionMinutes ?? 0,\n label: \"avg min/session\",\n }}\n />\n <StatCard\n title=\"Avg. Sessions/Day\"\n value={avgSessions}\n description={`Target: ${stats?.totalSessions ?? 0} total`}\n />\n <StatCard\n title=\"Completion Rate\"\n value={`${stats?.completionRate ?? 0}%`}\n icon={<Target className=\"h-5 w-5\" />}\n trend={{ value: stats?.streakDays ?? 0, label: \"day streak\" }}\n />\n </div>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-2\">\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Sessions per Day\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <p className=\"text-sm text-text-secondary\">\n {sessions.length > 0\n ? `${completedCount} completed out of ${sessions.length} sessions`\n : \"No session data available\"}\n </p>\n </div>\n </div>\n <div className=\"rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n <div className=\"mb-4 flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5 text-primary\" />\n <h3 className=\"text-sm font-semibold text-text-primary\">\n Focus Distribution\n </h3>\n </div>\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <p className=\"text-sm text-text-secondary\">\n {stats\n ? `${stats.streakDays} day streak · ${stats.averageSessionMinutes}m avg session`\n : \"No data available\"}\n </p>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAWA,SAAgB,IAAwB;CACtC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAAyB;EAC3B,WAAW,EAAE,gBAAa;EAC1B,MAAM,CAAC;EACR,CAAC,EAEI,EAAE,MAAM,GAAc,SAAS,MACnC,EAA6B;EAC3B,WAAW;GAAE;GAAa,OAAO;GAAI;EACrC,MAAM,CAAC;EACR,CAAC,EAEE,IAAQ,GAAW,eACnB,IAAW,GAAc,oBAAoB,EAAE;AAErD,KAAI,KAAgB,EAClB,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA;AAIjB,KAAI,EACF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAoG;GAE7G,CAAA;EACK,CAAA;CAIjB,IAAM,IAAc,KAAK,OAAO,GAAO,qBAAqB,KAAK,GAAG,EAC9D,KAAe,GAAO,qBAAqB,KAAK,IAChD,IAAc,GAAO,iBACtB,EAAM,gBAAgB,IAAI,QAAQ,EAAE,GACrC,KACE,IAAiB,EAAS,QAC7B,MAAqC,EAAE,UACzC,CAAC;AAEF,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,iBAAiB,EAAE;KACxC,OAAO;MACL,OAAO,GAAO,kBAAkB;MAChC,OAAO;MACR;KACD,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAY,IAAI,EAAY;KACtC,OAAO;MACL,OAAO,GAAO,yBAAyB;MACvC,OAAO;MACR;KACD,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,aAAa,WAAW,GAAO,iBAAiB,EAAE;KAClD,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,GAAO,kBAAkB,EAAE;KACrC,MAAM,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;KACpC,OAAO;MAAE,OAAO,GAAO,cAAc;MAAG,OAAO;MAAc;KAC7D,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAS,SAAS,IACf,GAAG,EAAe,oBAAoB,EAAS,OAAO,aACtD;MACF,CAAA;KACA,CAAA,CACF;OACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA,EAC9C,kBAAC,MAAD;MAAI,WAAU;gBAA0C;MAEnD,CAAA,CACD;QACN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBACV,IACG,GAAG,EAAM,WAAW,gBAAgB,EAAM,sBAAsB,iBAChE;MACF,CAAA;KACA,CAAA,CACF;MACF;KACK"}
|
|
@@ -1,20 +1,20 @@
|
|
|
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 { useCompletePomodoroSessionMutation as r, useGetActivePomodoroSessionQuery as i, useGetPomodoroStatsQuery as a, useStartPomodoroSessionMutation as o } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { PageLayout as s } from "../../components/PageLayout.js";
|
|
6
6
|
import { useCallback as c, useEffect as l, useState as u } from "react";
|
|
7
7
|
import { Pause as d, Play as f, RotateCcw as p, SkipForward as m } from "lucide-react";
|
|
8
8
|
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
9
9
|
//#region src/timecampus/pages/pomodoro/PomodoroPage.tsx
|
|
10
10
|
function _() {
|
|
11
|
-
let { workspaceId: _ = "" } = e(), { data: v, loading: y, error: b } =
|
|
11
|
+
let { workspaceId: _ = "" } = e(), { data: v, loading: y, error: b } = a({
|
|
12
12
|
variables: { workspaceId: _ },
|
|
13
13
|
skip: !_
|
|
14
|
-
}), { data: x, loading: S, error: C } =
|
|
14
|
+
}), { data: x, loading: S, error: C } = i({
|
|
15
15
|
variables: { workspaceId: _ },
|
|
16
16
|
skip: !_
|
|
17
|
-
}), [w] =
|
|
17
|
+
}), [w] = o(), [T] = r(), E = v?.pomodoroStats, D = x?.activePomodoroSession, [O, k] = u(1500), [A, j] = u(!1);
|
|
18
18
|
l(() => {
|
|
19
19
|
if (D && !D.completed) {
|
|
20
20
|
let e = Math.floor((Date.now() - new Date(D.startTime).getTime()) / 1e3), t = D.duration ?? 1500, n = Math.max(0, t - e);
|
|
@@ -63,35 +63,35 @@ function _() {
|
|
|
63
63
|
]), F = () => {
|
|
64
64
|
j(!1), k(1500);
|
|
65
65
|
};
|
|
66
|
-
if (y || S) return /* @__PURE__ */ h(
|
|
66
|
+
if (y || S) return /* @__PURE__ */ h(s, {
|
|
67
67
|
title: "Pomodoro Timer",
|
|
68
68
|
description: "Focus with the Pomodoro Technique",
|
|
69
|
-
children: /* @__PURE__ */ h(
|
|
69
|
+
children: /* @__PURE__ */ h(n, {
|
|
70
70
|
variant: "card",
|
|
71
71
|
count: 3
|
|
72
72
|
})
|
|
73
73
|
});
|
|
74
|
-
if (b || C) return /* @__PURE__ */ h(
|
|
74
|
+
if (b || C) return /* @__PURE__ */ h(s, {
|
|
75
75
|
title: "Pomodoro Timer",
|
|
76
76
|
description: "Focus with the Pomodoro Technique",
|
|
77
77
|
children: /* @__PURE__ */ h("div", {
|
|
78
|
-
className: "rounded-lg border border-
|
|
78
|
+
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
79
79
|
children: "Failed to load pomodoro data. Please try again later."
|
|
80
80
|
})
|
|
81
81
|
});
|
|
82
82
|
let I = Math.floor((E?.totalFocusMinutes ?? 0) / 60), L = (E?.totalFocusMinutes ?? 0) % 60;
|
|
83
|
-
return /* @__PURE__ */ g(
|
|
83
|
+
return /* @__PURE__ */ g(s, {
|
|
84
84
|
title: "Pomodoro Timer",
|
|
85
85
|
description: "Focus with the Pomodoro Technique",
|
|
86
86
|
children: [/* @__PURE__ */ g("div", {
|
|
87
87
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
|
|
88
88
|
children: [
|
|
89
|
-
/* @__PURE__ */ h(
|
|
89
|
+
/* @__PURE__ */ h(t, {
|
|
90
90
|
title: "Sessions Today",
|
|
91
91
|
value: String(E?.completedSessions ?? 0),
|
|
92
92
|
description: `Total: ${E?.totalSessions ?? 0} sessions`
|
|
93
93
|
}),
|
|
94
|
-
/* @__PURE__ */ h(
|
|
94
|
+
/* @__PURE__ */ h(t, {
|
|
95
95
|
title: "Focus Time",
|
|
96
96
|
value: `${I}h ${L}m`,
|
|
97
97
|
trend: {
|
|
@@ -99,7 +99,7 @@ function _() {
|
|
|
99
99
|
label: "completion rate"
|
|
100
100
|
}
|
|
101
101
|
}),
|
|
102
|
-
/* @__PURE__ */ h(
|
|
102
|
+
/* @__PURE__ */ h(t, {
|
|
103
103
|
title: "Current Streak",
|
|
104
104
|
value: `${E?.streakDays ?? 0} days`,
|
|
105
105
|
description: `Avg: ${E?.averageSessionMinutes ?? 0}m per session`
|
|
@@ -108,21 +108,21 @@ function _() {
|
|
|
108
108
|
}), /* @__PURE__ */ h("div", {
|
|
109
109
|
className: "mx-auto max-w-md",
|
|
110
110
|
children: /* @__PURE__ */ g("div", {
|
|
111
|
-
className: "rounded-xl border border-border bg-card p-8 text-center",
|
|
111
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-8 text-center",
|
|
112
112
|
children: [
|
|
113
113
|
/* @__PURE__ */ h("div", {
|
|
114
114
|
className: "mb-2",
|
|
115
115
|
children: /* @__PURE__ */ h("span", {
|
|
116
|
-
className: "inline-flex rounded-full bg-primary/10 px-3 py-1 text-xs font-medium text-primary",
|
|
116
|
+
className: "inline-flex rounded-full bg-action-primary-bg/10 px-3 py-1 text-xs font-medium text-primary",
|
|
117
117
|
children: D ? "Focus Session" : "Ready"
|
|
118
118
|
})
|
|
119
119
|
}),
|
|
120
120
|
/* @__PURE__ */ h("p", {
|
|
121
|
-
className: "text-7xl font-mono font-bold text-
|
|
121
|
+
className: "text-7xl font-mono font-bold text-text-primary",
|
|
122
122
|
children: M(O)
|
|
123
123
|
}),
|
|
124
124
|
/* @__PURE__ */ h("p", {
|
|
125
|
-
className: "mt-2 text-sm text-
|
|
125
|
+
className: "mt-2 text-sm text-text-secondary",
|
|
126
126
|
children: E ? `${E.completedSessions} of ${E.totalSessions} sessions` : "No sessions yet"
|
|
127
127
|
}),
|
|
128
128
|
/* @__PURE__ */ g("div", {
|
|
@@ -130,21 +130,21 @@ function _() {
|
|
|
130
130
|
children: [
|
|
131
131
|
A ? /* @__PURE__ */ g("button", {
|
|
132
132
|
onClick: () => j(!1),
|
|
133
|
-
className: "inline-flex items-center gap-2 rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-
|
|
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
134
|
children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), "Pause"]
|
|
135
135
|
}) : /* @__PURE__ */ g("button", {
|
|
136
136
|
onClick: N,
|
|
137
|
-
className: "inline-flex items-center gap-2 rounded-md bg-primary px-6 py-3 text-sm font-medium text-primary-
|
|
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
138
|
children: [/* @__PURE__ */ h(f, { className: "h-4 w-4" }), "Start"]
|
|
139
139
|
}),
|
|
140
140
|
/* @__PURE__ */ g("button", {
|
|
141
141
|
onClick: P,
|
|
142
|
-
className: "inline-flex items-center gap-2 rounded-md border border-border px-4 py-3 text-sm font-medium text-
|
|
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
143
|
children: [/* @__PURE__ */ h(m, { className: "h-4 w-4" }), "Skip"]
|
|
144
144
|
}),
|
|
145
145
|
/* @__PURE__ */ g("button", {
|
|
146
146
|
onClick: F,
|
|
147
|
-
className: "inline-flex items-center gap-2 rounded-md border border-border px-4 py-3 text-sm font-medium text-
|
|
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
148
|
children: [/* @__PURE__ */ h(p, { className: "h-4 w-4" }), "Reset"]
|
|
149
149
|
})
|
|
150
150
|
]
|
|
@@ -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-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load 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 bg-card p-8 text-center\">\n <div className=\"mb-2\">\n <span className=\"inline-flex rounded-full bg-primary/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-foreground\">\n {formatTimer(timerSeconds)}\n </p>\n <p className=\"mt-2 text-sm text-muted-foreground\">\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-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/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-primary px-6 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/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 px-4 py-3 text-sm font-medium text-foreground hover:bg-muted/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 px-4 py-3 text-sm font-medium text-foreground hover:bg-muted/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 { 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,16 +1,16 @@
|
|
|
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 { useGetPomodoroSettingsQuery as n, useUpdatePomodoroSettingsMutation 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";
|
|
8
8
|
//#region src/timecampus/pages/pomodoro/PomodoroSettingsPage.tsx
|
|
9
9
|
function d() {
|
|
10
|
-
let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } =
|
|
10
|
+
let { workspaceId: d = "" } = e(), { data: f, loading: p, error: m } = n({
|
|
11
11
|
variables: { workspaceId: d },
|
|
12
12
|
skip: !d
|
|
13
|
-
}), [h, { loading: g }] =
|
|
13
|
+
}), [h, { loading: g }] = r(), _ = f?.pomodoroSettings, [v, y] = s(25), [b, x] = s(5), [S, C] = s(15), [w, T] = s(!0), [E, D] = s(!0), [O, k] = s(!1);
|
|
14
14
|
o(() => {
|
|
15
15
|
_ && (y(_.focusDuration), x(_.shortBreakDuration), C(_.longBreakDuration), T(_.soundEnabled), D(_.notificationsEnabled), k(_.autoStartBreaks));
|
|
16
16
|
}, [_]);
|
|
@@ -37,27 +37,27 @@ function d() {
|
|
|
37
37
|
O,
|
|
38
38
|
h
|
|
39
39
|
]);
|
|
40
|
-
return p ? /* @__PURE__ */ l(
|
|
40
|
+
return p ? /* @__PURE__ */ l(i, {
|
|
41
41
|
title: "Pomodoro Settings",
|
|
42
42
|
description: "Configure your Pomodoro timer preferences",
|
|
43
|
-
children: /* @__PURE__ */ l(
|
|
44
|
-
}) : m ? /* @__PURE__ */ l(
|
|
43
|
+
children: /* @__PURE__ */ l(t, { variant: "detail" })
|
|
44
|
+
}) : m ? /* @__PURE__ */ l(i, {
|
|
45
45
|
title: "Pomodoro Settings",
|
|
46
46
|
description: "Configure your Pomodoro timer preferences",
|
|
47
47
|
children: /* @__PURE__ */ l("div", {
|
|
48
|
-
className: "rounded-lg border border-
|
|
48
|
+
className: "rounded-lg border border-status-error-bg/40 bg-status-error-bg p-4 text-sm text-status-error-text",
|
|
49
49
|
children: "Failed to load settings. Please try again later."
|
|
50
50
|
})
|
|
51
|
-
}) : /* @__PURE__ */ l(
|
|
51
|
+
}) : /* @__PURE__ */ l(i, {
|
|
52
52
|
title: "Pomodoro Settings",
|
|
53
53
|
description: "Configure your Pomodoro timer preferences",
|
|
54
54
|
children: /* @__PURE__ */ u("div", {
|
|
55
55
|
className: "mx-auto max-w-2xl space-y-6",
|
|
56
56
|
children: [
|
|
57
57
|
/* @__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" }), "Timer Durations"]
|
|
62
62
|
}), /* @__PURE__ */ u("div", {
|
|
63
63
|
className: "space-y-4",
|
|
@@ -65,55 +65,55 @@ function d() {
|
|
|
65
65
|
/* @__PURE__ */ u("div", {
|
|
66
66
|
className: "flex items-center justify-between",
|
|
67
67
|
children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
68
|
-
className: "text-sm font-medium text-
|
|
68
|
+
className: "text-sm font-medium text-text-primary",
|
|
69
69
|
children: "Focus Duration"
|
|
70
70
|
}), /* @__PURE__ */ l("p", {
|
|
71
|
-
className: "text-xs text-
|
|
71
|
+
className: "text-xs text-text-secondary",
|
|
72
72
|
children: "Length of each focus session"
|
|
73
73
|
})] }), /* @__PURE__ */ l("input", {
|
|
74
74
|
type: "number",
|
|
75
75
|
value: v,
|
|
76
76
|
onChange: (e) => y(Number(e.target.value)),
|
|
77
|
-
className: "w-20 rounded-md border border-border bg-
|
|
77
|
+
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
78
|
})]
|
|
79
79
|
}),
|
|
80
80
|
/* @__PURE__ */ u("div", {
|
|
81
81
|
className: "flex items-center justify-between",
|
|
82
82
|
children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
83
|
-
className: "text-sm font-medium text-
|
|
83
|
+
className: "text-sm font-medium text-text-primary",
|
|
84
84
|
children: "Short Break"
|
|
85
85
|
}), /* @__PURE__ */ l("p", {
|
|
86
|
-
className: "text-xs text-
|
|
86
|
+
className: "text-xs text-text-secondary",
|
|
87
87
|
children: "Break between focus sessions"
|
|
88
88
|
})] }), /* @__PURE__ */ l("input", {
|
|
89
89
|
type: "number",
|
|
90
90
|
value: b,
|
|
91
91
|
onChange: (e) => x(Number(e.target.value)),
|
|
92
|
-
className: "w-20 rounded-md border border-border bg-
|
|
92
|
+
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
93
|
})]
|
|
94
94
|
}),
|
|
95
95
|
/* @__PURE__ */ u("div", {
|
|
96
96
|
className: "flex items-center justify-between",
|
|
97
97
|
children: [/* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("p", {
|
|
98
|
-
className: "text-sm font-medium text-
|
|
98
|
+
className: "text-sm font-medium text-text-primary",
|
|
99
99
|
children: "Long Break"
|
|
100
100
|
}), /* @__PURE__ */ l("p", {
|
|
101
|
-
className: "text-xs text-
|
|
101
|
+
className: "text-xs text-text-secondary",
|
|
102
102
|
children: "After every 4 focus sessions"
|
|
103
103
|
})] }), /* @__PURE__ */ l("input", {
|
|
104
104
|
type: "number",
|
|
105
105
|
value: S,
|
|
106
106
|
onChange: (e) => C(Number(e.target.value)),
|
|
107
|
-
className: "w-20 rounded-md border border-border bg-
|
|
107
|
+
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
108
|
})]
|
|
109
109
|
})
|
|
110
110
|
]
|
|
111
111
|
})]
|
|
112
112
|
}),
|
|
113
113
|
/* @__PURE__ */ u("div", {
|
|
114
|
-
className: "rounded-xl border border-border bg-card p-6",
|
|
114
|
+
className: "rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
|
|
115
115
|
children: [/* @__PURE__ */ l("h3", {
|
|
116
|
-
className: "mb-4 text-sm font-semibold text-
|
|
116
|
+
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
117
117
|
children: "Notifications"
|
|
118
118
|
}), /* @__PURE__ */ u("div", {
|
|
119
119
|
className: "space-y-3",
|
|
@@ -121,37 +121,37 @@ function d() {
|
|
|
121
121
|
/* @__PURE__ */ u("label", {
|
|
122
122
|
className: "flex items-center justify-between",
|
|
123
123
|
children: [/* @__PURE__ */ l("span", {
|
|
124
|
-
className: "text-sm text-
|
|
124
|
+
className: "text-sm text-text-primary",
|
|
125
125
|
children: "Sound alerts"
|
|
126
126
|
}), /* @__PURE__ */ l("input", {
|
|
127
127
|
type: "checkbox",
|
|
128
128
|
checked: w,
|
|
129
129
|
onChange: (e) => T(e.target.checked),
|
|
130
|
-
className: "h-4 w-4 rounded border-border"
|
|
130
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
131
131
|
})]
|
|
132
132
|
}),
|
|
133
133
|
/* @__PURE__ */ u("label", {
|
|
134
134
|
className: "flex items-center justify-between",
|
|
135
135
|
children: [/* @__PURE__ */ l("span", {
|
|
136
|
-
className: "text-sm text-
|
|
136
|
+
className: "text-sm text-text-primary",
|
|
137
137
|
children: "Desktop notifications"
|
|
138
138
|
}), /* @__PURE__ */ l("input", {
|
|
139
139
|
type: "checkbox",
|
|
140
140
|
checked: E,
|
|
141
141
|
onChange: (e) => D(e.target.checked),
|
|
142
|
-
className: "h-4 w-4 rounded border-border"
|
|
142
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
143
143
|
})]
|
|
144
144
|
}),
|
|
145
145
|
/* @__PURE__ */ u("label", {
|
|
146
146
|
className: "flex items-center justify-between",
|
|
147
147
|
children: [/* @__PURE__ */ l("span", {
|
|
148
|
-
className: "text-sm text-
|
|
148
|
+
className: "text-sm text-text-primary",
|
|
149
149
|
children: "Auto-start breaks"
|
|
150
150
|
}), /* @__PURE__ */ l("input", {
|
|
151
151
|
type: "checkbox",
|
|
152
152
|
checked: O,
|
|
153
153
|
onChange: (e) => k(e.target.checked),
|
|
154
|
-
className: "h-4 w-4 rounded border-border"
|
|
154
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
155
155
|
})]
|
|
156
156
|
})
|
|
157
157
|
]
|
|
@@ -162,7 +162,7 @@ function d() {
|
|
|
162
162
|
children: /* @__PURE__ */ l("button", {
|
|
163
163
|
onClick: A,
|
|
164
164
|
disabled: g,
|
|
165
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
165
|
+
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
166
|
children: g ? "Saving..." : "Save Settings"
|
|
167
167
|
})
|
|
168
168
|
})
|
|
@@ -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-red-200 bg-red-50 p-4 text-sm text-red-600 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load 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 bg-card p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-foreground\">\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-foreground\">\n Focus Duration\n </p>\n <p className=\"text-xs text-muted-foreground\">\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 bg-background px-3 py-1.5 text-sm text-foreground text-right\"\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n Short Break\n </p>\n <p className=\"text-xs text-muted-foreground\">\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 bg-background px-3 py-1.5 text-sm text-foreground text-right\"\n />\n </div>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n Long Break\n </p>\n <p className=\"text-xs text-muted-foreground\">\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 bg-background px-3 py-1.5 text-sm text-foreground text-right\"\n />\n </div>\n </div>\n </div>\n\n <div className=\"rounded-xl border border-border bg-card p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-foreground\">\n Notifications\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground\">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\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground\">\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\"\n />\n </label>\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-foreground\">Auto-start breaks</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\"\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-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/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 { 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,82 +1,82 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { useCreateProjectMutation as e } from "../../../generated/wspace-operations.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
3
|
import { useState as n } from "react";
|
|
4
4
|
import { ArrowLeft as r } from "lucide-react";
|
|
5
5
|
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
6
|
//#region src/timecampus/pages/projects/ProjectCreatePage.tsx
|
|
7
7
|
function o() {
|
|
8
|
-
let [o, s] = n(""), [c, l] = n(""), [u, d] = n(""), [f, p] = n(""), [m, h] = n(""), [g, { loading: _, error: v }] =
|
|
9
|
-
return /* @__PURE__ */ i(
|
|
8
|
+
let [o, s] = n(""), [c, l] = n(""), [u, d] = n(""), [f, p] = n(""), [m, h] = n(""), [g, { loading: _, error: v }] = e();
|
|
9
|
+
return /* @__PURE__ */ i(t, {
|
|
10
10
|
title: "Create Project",
|
|
11
11
|
description: "Set up a new project for time tracking",
|
|
12
12
|
actions: /* @__PURE__ */ a("button", {
|
|
13
|
-
className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-
|
|
13
|
+
className: "inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
14
14
|
children: [/* @__PURE__ */ i(r, { className: "h-4 w-4" }), "Back to Projects"]
|
|
15
15
|
}),
|
|
16
16
|
children: /* @__PURE__ */ a("div", {
|
|
17
|
-
className: "mx-auto max-w-2xl rounded-xl border border-border bg-card p-6",
|
|
17
|
+
className: "mx-auto max-w-2xl rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6",
|
|
18
18
|
children: [v && /* @__PURE__ */ i("div", {
|
|
19
|
-
className: "mb-4 rounded-lg border border-
|
|
19
|
+
className: "mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text",
|
|
20
20
|
children: "Failed to create project. Please try again."
|
|
21
21
|
}), /* @__PURE__ */ a("div", {
|
|
22
22
|
className: "space-y-4",
|
|
23
23
|
children: [
|
|
24
24
|
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
25
|
-
className: "block text-sm font-medium text-
|
|
25
|
+
className: "block text-sm font-medium text-text-primary",
|
|
26
26
|
children: "Project Name"
|
|
27
27
|
}), /* @__PURE__ */ i("input", {
|
|
28
28
|
type: "text",
|
|
29
29
|
placeholder: "Enter project name",
|
|
30
30
|
value: o,
|
|
31
31
|
onChange: (e) => s(e.target.value),
|
|
32
|
-
className: "mt-1 w-full rounded-md border border-border bg-
|
|
32
|
+
className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary"
|
|
33
33
|
})] }),
|
|
34
34
|
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
35
|
-
className: "block text-sm font-medium text-
|
|
35
|
+
className: "block text-sm font-medium text-text-primary",
|
|
36
36
|
children: "Client"
|
|
37
37
|
}), /* @__PURE__ */ i("input", {
|
|
38
38
|
type: "text",
|
|
39
39
|
placeholder: "Client name",
|
|
40
40
|
value: c,
|
|
41
41
|
onChange: (e) => l(e.target.value),
|
|
42
|
-
className: "mt-1 w-full rounded-md border border-border bg-
|
|
42
|
+
className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary"
|
|
43
43
|
})] }),
|
|
44
44
|
/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
45
|
-
className: "block text-sm font-medium text-
|
|
45
|
+
className: "block text-sm font-medium text-text-primary",
|
|
46
46
|
children: "Description"
|
|
47
47
|
}), /* @__PURE__ */ i("textarea", {
|
|
48
48
|
placeholder: "Project description",
|
|
49
49
|
rows: 3,
|
|
50
50
|
value: u,
|
|
51
51
|
onChange: (e) => d(e.target.value),
|
|
52
|
-
className: "mt-1 w-full rounded-md border border-border bg-
|
|
52
|
+
className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary"
|
|
53
53
|
})] }),
|
|
54
54
|
/* @__PURE__ */ a("div", {
|
|
55
55
|
className: "grid grid-cols-2 gap-4",
|
|
56
56
|
children: [/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
57
|
-
className: "block text-sm font-medium text-
|
|
57
|
+
className: "block text-sm font-medium text-text-primary",
|
|
58
58
|
children: "Estimated Hours"
|
|
59
59
|
}), /* @__PURE__ */ i("input", {
|
|
60
60
|
type: "number",
|
|
61
61
|
placeholder: "0",
|
|
62
62
|
value: f,
|
|
63
63
|
onChange: (e) => p(e.target.value),
|
|
64
|
-
className: "mt-1 w-full rounded-md border border-border bg-
|
|
64
|
+
className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
|
|
65
65
|
})] }), /* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("label", {
|
|
66
|
-
className: "block text-sm font-medium text-
|
|
66
|
+
className: "block text-sm font-medium text-text-primary",
|
|
67
67
|
children: "Hourly Rate"
|
|
68
68
|
}), /* @__PURE__ */ i("input", {
|
|
69
69
|
type: "number",
|
|
70
70
|
placeholder: "0.00",
|
|
71
71
|
value: m,
|
|
72
72
|
onChange: (e) => h(e.target.value),
|
|
73
|
-
className: "mt-1 w-full rounded-md border border-border bg-
|
|
73
|
+
className: "mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary"
|
|
74
74
|
})] })]
|
|
75
75
|
}),
|
|
76
76
|
/* @__PURE__ */ a("div", {
|
|
77
77
|
className: "flex justify-end gap-2 pt-4",
|
|
78
78
|
children: [/* @__PURE__ */ i("button", {
|
|
79
|
-
className: "rounded-md border border-border px-4 py-2 text-sm font-medium text-
|
|
79
|
+
className: "rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50",
|
|
80
80
|
children: "Cancel"
|
|
81
81
|
}), /* @__PURE__ */ i("button", {
|
|
82
82
|
onClick: async () => {
|
|
@@ -89,7 +89,7 @@ function o() {
|
|
|
89
89
|
} } });
|
|
90
90
|
},
|
|
91
91
|
disabled: _ || !o.trim(),
|
|
92
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
92
|
+
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",
|
|
93
93
|
children: _ ? "Creating..." : "Create Project"
|
|
94
94
|
})]
|
|
95
95
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectCreatePage.js","names":[],"sources":["../../../../src/timecampus/pages/projects/ProjectCreatePage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { useCreateProjectMutation } from \"@/generated/wspace-operations\";\n\nexport function ProjectCreatePage() {\n const [name, setName] = useState(\"\");\n const [clientId, setClientId] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [estimatedHours, setEstimatedHours] = useState(\"\");\n const [hourlyRate, setHourlyRate] = useState(\"\");\n\n const [createProject, { loading: creating, error }] =\n useCreateProjectMutation();\n\n const handleSubmit = async () => {\n if (!name.trim()) return;\n await createProject({\n variables: {\n input: {\n name: name.trim(),\n description: description.trim() || undefined,\n clientId: clientId.trim() || undefined,\n estimatedHours: estimatedHours ? Number(estimatedHours) : undefined,\n hourlyRate: hourlyRate ? Number(hourlyRate) : undefined,\n },\n },\n });\n };\n\n return (\n <PageLayout\n title=\"Create Project\"\n description=\"Set up a new project for time tracking\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-
|
|
1
|
+
{"version":3,"file":"ProjectCreatePage.js","names":[],"sources":["../../../../src/timecampus/pages/projects/ProjectCreatePage.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { useCreateProjectMutation } from \"@/generated/wspace-operations\";\n\nexport function ProjectCreatePage() {\n const [name, setName] = useState(\"\");\n const [clientId, setClientId] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [estimatedHours, setEstimatedHours] = useState(\"\");\n const [hourlyRate, setHourlyRate] = useState(\"\");\n\n const [createProject, { loading: creating, error }] =\n useCreateProjectMutation();\n\n const handleSubmit = async () => {\n if (!name.trim()) return;\n await createProject({\n variables: {\n input: {\n name: name.trim(),\n description: description.trim() || undefined,\n clientId: clientId.trim() || undefined,\n estimatedHours: estimatedHours ? Number(estimatedHours) : undefined,\n hourlyRate: hourlyRate ? Number(hourlyRate) : undefined,\n },\n },\n });\n };\n\n return (\n <PageLayout\n title=\"Create Project\"\n description=\"Set up a new project for time tracking\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Projects\n </button>\n }\n >\n <div className=\"mx-auto max-w-2xl rounded-xl border border-border-seam bg-gloss-card shadow-pop p-6\">\n {error && (\n <div className=\"mb-4 rounded-lg border border-status-error-bg/40 bg-status-error-bg p-3 text-sm text-status-error-text\">\n Failed to create project. Please try again.\n </div>\n )}\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Project Name\n </label>\n <input\n type=\"text\"\n placeholder=\"Enter project name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Client\n </label>\n <input\n type=\"text\"\n placeholder=\"Client name\"\n value={clientId}\n onChange={(e) => setClientId(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Description\n </label>\n <textarea\n placeholder=\"Project description\"\n rows={3}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Estimated Hours\n </label>\n <input\n type=\"number\"\n placeholder=\"0\"\n value={estimatedHours}\n onChange={(e) => setEstimatedHours(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-text-primary\">\n Hourly Rate\n </label>\n <input\n type=\"number\"\n placeholder=\"0.00\"\n value={hourlyRate}\n onChange={(e) => setHourlyRate(e.target.value)}\n className=\"mt-1 w-full rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n />\n </div>\n </div>\n <div className=\"flex justify-end gap-2 pt-4\">\n <button className=\"rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken/50\">\n Cancel\n </button>\n <button\n onClick={handleSubmit}\n disabled={creating || !name.trim()}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {creating ? \"Creating...\" : \"Create Project\"}\n </button>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgB,IAAoB;CAClC,IAAM,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAgB,KAAqB,EAAS,GAAG,EAClD,CAAC,GAAY,KAAiB,EAAS,GAAG,EAE1C,CAAC,GAAe,EAAE,SAAS,GAAU,cACzC,GAA0B;AAiB5B,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,mBAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,KACC,kBAAC,OAAD;IAAK,WAAU;cAAyG;IAElH,CAAA,EAER,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,SAAD;MACE,MAAK;MACL,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;MACxC,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,SAAD;MACE,MAAK;MACL,aAAY;MACZ,OAAO;MACP,WAAW,MAAM,EAAY,EAAE,OAAO,MAAM;MAC5C,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;MAAO,WAAU;gBAA8C;MAEvD,CAAA,EACR,kBAAC,YAAD;MACE,aAAY;MACZ,MAAM;MACN,OAAO;MACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;MAC/C,WAAU;MACV,CAAA,CACE,EAAA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,aAAY;OACZ,OAAO;OACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAM;OAClD,WAAU;OACV,CAAA,CACE,EAAA,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBAA8C;OAEvD,CAAA,EACR,kBAAC,SAAD;OACE,MAAK;OACL,aAAY;OACZ,OAAO;OACP,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;OAC9C,WAAU;OACV,CAAA,CACE,EAAA,CAAA,CACF;;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OAAQ,WAAU;iBAA+G;OAExH,CAAA,EACT,kBAAC,UAAD;OACE,SApGS,YAAY;AAC1B,UAAK,MAAM,IAChB,MAAM,EAAc,EAClB,WAAW,EACT,OAAO;SACL,MAAM,EAAK,MAAM;SACjB,aAAa,EAAY,MAAM,IAAI,KAAA;SACnC,UAAU,EAAS,MAAM,IAAI,KAAA;SAC7B,gBAAgB,IAAiB,OAAO,EAAe,GAAG,KAAA;SAC1D,YAAY,IAAa,OAAO,EAAW,GAAG,KAAA;SAC/C,EACF,EACF,CAAC;;OAyFQ,UAAU,KAAY,CAAC,EAAK,MAAM;OAClC,WAAU;iBAET,IAAW,gBAAgB;OACrB,CAAA,CACL;;KACF;MACF;;EACK,CAAA"}
|