@burdenoff/microfe-timecampus 2026.608.1 → 2026.624.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/timecampus/components/ErrorBoundary.js +2 -2
- package/dist/timecampus/components/ErrorBoundary.js.map +1 -1
- package/dist/timecampus/components/LoadingSkeleton.js +8 -8
- package/dist/timecampus/components/LoadingSkeleton.js.map +1 -1
- package/dist/timecampus/components/PageLayout.js +2 -2
- package/dist/timecampus/components/PageLayout.js.map +1 -1
- package/dist/timecampus/components/StatCard.js +6 -6
- package/dist/timecampus/components/StatCard.js.map +1 -1
- package/dist/timecampus/pages/HomePage.js +31 -31
- package/dist/timecampus/pages/HomePage.js.map +1 -1
- package/dist/timecampus/pages/applets/AppletStorePage.js +7 -7
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -1
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +8 -8
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +10 -10
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -1
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +10 -10
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/channels/ChannelsPage.js +6 -6
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -1
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +8 -8
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +11 -11
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/dashboard/ReportsPage.js +10 -10
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +5 -5
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +13 -13
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +8 -8
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +8 -8
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +7 -7
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -1
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +10 -10
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +7 -7
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -1
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +9 -9
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +7 -7
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +12 -12
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +8 -8
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +4 -4
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +12 -12
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +15 -15
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -1
- package/dist/timecampus/pages/meetings/MeetingsPage.js +11 -11
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +8 -8
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +8 -8
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -1
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +20 -20
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +14 -14
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +8 -8
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -1
- package/dist/timecampus/pages/projects/ProjectsPage.js +11 -11
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -1
- package/dist/timecampus/pages/projects/TasksPage.js +7 -7
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -1
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +8 -8
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +10 -10
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamMembersPage.js +10 -10
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -1
- package/dist/timecampus/pages/team/TeamPage.js +4 -4
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +6 -6
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -1
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +11 -11
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +6 -6
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +10 -10
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -1
- package/dist/timecampus/pages/templates/TemplatesPage.js +6 -6
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeEntriesPage.js +16 -16
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimeTrackingPage.js +9 -9
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -1
- package/dist/timecampus/pages/time/TimerPage.js +12 -12
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -1
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +8 -8
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +10 -10
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -1
- package/dist/timecampus/pages/widgets/WidgetsPage.js +7 -7
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +9 -9
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -1
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +10 -10
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -1
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +8 -8
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimeApprovalPage.js","names":[],"sources":["../../../../src/timecampus/pages/time-approval/TimeApprovalPage.tsx"],"sourcesContent":["import { CheckCircle, XCircle, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n getStatusColor,\n getInitials,\n formatHours,\n formatDate,\n} from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListApprovalRequestsQuery,\n useGetApprovalStatsQuery,\n useApproveRequestMutation,\n useRejectRequestMutation,\n type ApprovalRequestFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function TimeApprovalPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: requestsData,\n loading: requestsLoading,\n error: requestsError,\n } = useListApprovalRequestsQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetApprovalStatsQuery();\n const [approveRequest, { loading: approving }] = useApproveRequestMutation();\n const [rejectRequest, { loading: rejecting }] = useRejectRequestMutation();\n\n const requests = requestsData?.approvalRequests?.items ?? [];\n const stats = statsData?.approvalStats;\n const mutating = approving || rejecting;\n\n const handleApprove = async (id: string) => {\n await approveRequest({ variables: { id } });\n };\n\n const handleReject = async (id: string) => {\n await rejectRequest({ variables: { id, reason: \"Rejected by reviewer\" } });\n };\n\n if (requestsLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (requestsError && statsError) {\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\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 approval data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Pending Approvals\"\n value={String(stats?.pendingCount ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n iconBgColor=\"bg-amber-100 text-amber-600 dark:bg-amber-900/30 dark:text-amber-400\"\n />\n <StatCard\n title=\"Approved This Week\"\n value={String(stats?.approvedCount ?? 0)}\n icon={<CheckCircle className=\"h-5 w-5\" />}\n iconBgColor=\"bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\n />\n <StatCard\n title=\"Rejected\"\n value={String(stats?.rejectedCount ?? 0)}\n icon={<XCircle className=\"h-5 w-5\" />}\n iconBgColor=\"bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\"\n />\n <StatCard\n title=\"Avg. Review Time\"\n value={\n stats?.averageReviewTime\n ? `${Math.round(stats.averageReviewTime)}h`\n : \"N/A\"\n }\n description=\"Target: 24h\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border bg-
|
|
1
|
+
{"version":3,"file":"TimeApprovalPage.js","names":[],"sources":["../../../../src/timecampus/pages/time-approval/TimeApprovalPage.tsx"],"sourcesContent":["import { CheckCircle, XCircle, Clock } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport {\n getStatusColor,\n getInitials,\n formatHours,\n formatDate,\n} from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListApprovalRequestsQuery,\n useGetApprovalStatsQuery,\n useApproveRequestMutation,\n useRejectRequestMutation,\n type ApprovalRequestFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function TimeApprovalPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: requestsData,\n loading: requestsLoading,\n error: requestsError,\n } = useListApprovalRequestsQuery();\n const {\n data: statsData,\n loading: statsLoading,\n error: statsError,\n } = useGetApprovalStatsQuery();\n const [approveRequest, { loading: approving }] = useApproveRequestMutation();\n const [rejectRequest, { loading: rejecting }] = useRejectRequestMutation();\n\n const requests = requestsData?.approvalRequests?.items ?? [];\n const stats = statsData?.approvalStats;\n const mutating = approving || rejecting;\n\n const handleApprove = async (id: string) => {\n await approveRequest({ variables: { id } });\n };\n\n const handleReject = async (id: string) => {\n await rejectRequest({ variables: { id, reason: \"Rejected by reviewer\" } });\n };\n\n if (requestsLoading && statsLoading) {\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\n >\n <LoadingSkeleton variant=\"list\" count={4} />\n </PageLayout>\n );\n }\n\n if (requestsError && statsError) {\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\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 approval data. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Time Approval\"\n description=\"Review and approve team timesheets\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Pending Approvals\"\n value={String(stats?.pendingCount ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n iconBgColor=\"bg-amber-100 text-amber-600 dark:bg-amber-900/30 dark:text-amber-400\"\n />\n <StatCard\n title=\"Approved This Week\"\n value={String(stats?.approvedCount ?? 0)}\n icon={<CheckCircle className=\"h-5 w-5\" />}\n iconBgColor=\"bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400\"\n />\n <StatCard\n title=\"Rejected\"\n value={String(stats?.rejectedCount ?? 0)}\n icon={<XCircle className=\"h-5 w-5\" />}\n iconBgColor=\"bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400\"\n />\n <StatCard\n title=\"Avg. Review Time\"\n value={\n stats?.averageReviewTime\n ? `${Math.round(stats.averageReviewTime)}h`\n : \"N/A\"\n }\n description=\"Target: 24h\"\n />\n </div>\n\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface\">\n <div className=\"divide-y divide-border\">\n {requests.length === 0 && !requestsLoading && (\n <div className=\"p-4 text-center text-sm text-text-secondary\">\n No approval requests found.\n </div>\n )}\n {requests.map((request: ApprovalRequestFieldsFragment) => (\n <div\n key={request.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-full bg-action-primary-bg/10 text-sm font-medium text-primary\">\n {getInitials(request.userId)}\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {request.userId}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {request.period} · Submitted{\" \"}\n {formatDate(request.submittedAt)}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">\n {formatHours(request.totalHours)}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {formatHours(request.billableHours)} billable\n </p>\n </div>\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(request.status)}`}\n >\n {request.status}\n </span>\n {request.status === \"PENDING\" && (\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => handleApprove(request.id)}\n disabled={mutating}\n className=\"rounded-md p-1.5 text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-900/20 disabled:opacity-50\"\n >\n <CheckCircle className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => handleReject(request.id)}\n disabled={mutating}\n className=\"rounded-md p-1.5 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 disabled:opacity-50\"\n >\n <XCircle className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAmBA,SAAgB,IAAmB;CACjC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA8B,EAC5B,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,GAA0B,EACxB,CAAC,GAAgB,EAAE,SAAS,OAAe,GAA2B,EACtE,CAAC,GAAe,EAAE,SAAS,OAAe,GAA0B,EAEpE,IAAW,GAAc,kBAAkB,SAAS,EAAE,EACtD,IAAQ,GAAW,eACnB,IAAW,KAAa,GAExB,IAAgB,OAAO,MAAe;AAC1C,QAAM,EAAe,EAAE,WAAW,EAAE,OAAI,EAAE,CAAC;IAGvC,IAAe,OAAO,MAAe;AACzC,QAAM,EAAc,EAAE,WAAW;GAAE;GAAI,QAAQ;GAAwB,EAAE,CAAC;;AA2B5E,QAxBI,KAAmB,IAEnB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,KAAiB,IAEjB,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,gBAAgB,EAAE;KACvC,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,iBAAiB,EAAE;KACxC,MAAM,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;KACzC,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,OAAO,GAAO,iBAAiB,EAAE;KACxC,MAAM,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;KACrC,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OACE,GAAO,oBACH,GAAG,KAAK,MAAM,EAAM,kBAAkB,CAAC,KACvC;KAEN,aAAY;KACZ,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,EAAS,WAAW,KAAK,CAAC,KACzB,kBAAC,OAAD;KAAK,WAAU;eAA8C;KAEvD,CAAA,EAEP,EAAS,KAAK,MACb,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAY,EAAQ,OAAO;OACxB,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAQ;OACP,CAAA,EACJ,kBAAC,KAAD;OAAG,WAAU;iBAAb;QACG,EAAQ;QAAO;QAAoB;QACnC,EAAW,EAAQ,YAAY;QAC9B;SACA,EAAA,CAAA,CACF;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAY,EAAQ,WAAW;SAC9B,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,EAAY,EAAQ,cAAc,EAAC,YAClC;WACA;;OACN,kBAAC,QAAD;QACE,WAAW,4DAA4D,EAAe,EAAQ,OAAO;kBAEpG,EAAQ;QACJ,CAAA;OACN,EAAQ,WAAW,aAClB,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,UAAD;SACE,eAAe,EAAc,EAAQ,GAAG;SACxC,UAAU;SACV,WAAU;mBAEV,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA;SAC5B,CAAA,EACT,kBAAC,UAAD;SACE,eAAe,EAAa,EAAQ,GAAG;SACvC,UAAU;SACV,WAAU;mBAEV,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;SACxB,CAAA,CACL;;OAEJ;QACF;OAlDC,EAAQ,GAkDT,CACN,CACE;;GACF,CAAA,CACK"}
|
|
@@ -19,7 +19,7 @@ function d() {
|
|
|
19
19
|
title: "Widget Details",
|
|
20
20
|
description: `Widget ID: ${d}`,
|
|
21
21
|
actions: /* @__PURE__ */ u("button", {
|
|
22
|
-
className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-
|
|
22
|
+
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",
|
|
23
23
|
children: [/* @__PURE__ */ l(i, { className: "h-4 w-4" }), "Back to Widgets"]
|
|
24
24
|
}),
|
|
25
25
|
children: /* @__PURE__ */ l("div", {
|
|
@@ -30,32 +30,32 @@ function d() {
|
|
|
30
30
|
title: "Widget Details",
|
|
31
31
|
description: `Widget ID: ${d}`,
|
|
32
32
|
actions: /* @__PURE__ */ u("button", {
|
|
33
|
-
className: "inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-2 text-sm font-medium text-
|
|
33
|
+
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",
|
|
34
34
|
children: [/* @__PURE__ */ l(i, { className: "h-4 w-4" }), "Back to Widgets"]
|
|
35
35
|
}),
|
|
36
36
|
children: /* @__PURE__ */ l("div", {
|
|
37
37
|
className: "mx-auto max-w-2xl",
|
|
38
38
|
children: /* @__PURE__ */ u("div", {
|
|
39
|
-
className: "rounded-xl border border-border bg-
|
|
39
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
40
40
|
children: [
|
|
41
41
|
/* @__PURE__ */ u("div", {
|
|
42
42
|
className: "flex items-start gap-4",
|
|
43
43
|
children: [/* @__PURE__ */ l("div", {
|
|
44
|
-
className: "flex h-16 w-16 items-center justify-center rounded-xl bg-primary/10",
|
|
44
|
+
className: "flex h-16 w-16 items-center justify-center rounded-xl bg-action-primary-bg/10",
|
|
45
45
|
children: /* @__PURE__ */ l(o, { className: "h-8 w-8 text-primary" })
|
|
46
46
|
}), /* @__PURE__ */ u("div", {
|
|
47
47
|
className: "flex-1",
|
|
48
48
|
children: [
|
|
49
49
|
/* @__PURE__ */ l("h2", {
|
|
50
|
-
className: "text-lg font-semibold text-
|
|
50
|
+
className: "text-lg font-semibold text-text-primary",
|
|
51
51
|
children: v
|
|
52
52
|
}),
|
|
53
53
|
/* @__PURE__ */ l("p", {
|
|
54
|
-
className: "text-sm text-
|
|
54
|
+
className: "text-sm text-text-secondary",
|
|
55
55
|
children: y
|
|
56
56
|
}),
|
|
57
57
|
/* @__PURE__ */ u("div", {
|
|
58
|
-
className: "mt-2 flex items-center gap-3 text-sm text-
|
|
58
|
+
className: "mt-2 flex items-center gap-3 text-sm text-text-secondary",
|
|
59
59
|
children: [
|
|
60
60
|
/* @__PURE__ */ u("div", {
|
|
61
61
|
className: "flex items-center gap-1",
|
|
@@ -72,16 +72,16 @@ function d() {
|
|
|
72
72
|
})]
|
|
73
73
|
}),
|
|
74
74
|
/* @__PURE__ */ l("div", {
|
|
75
|
-
className: "mt-6 flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
75
|
+
className: "mt-6 flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
|
|
76
76
|
children: /* @__PURE__ */ l("p", {
|
|
77
|
-
className: "text-sm text-
|
|
77
|
+
className: "text-sm text-text-secondary",
|
|
78
78
|
children: "Widget preview will render here"
|
|
79
79
|
})
|
|
80
80
|
}),
|
|
81
81
|
/* @__PURE__ */ l("div", {
|
|
82
82
|
className: "mt-4 flex justify-end",
|
|
83
83
|
children: /* @__PURE__ */ l("button", {
|
|
84
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
84
|
+
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",
|
|
85
85
|
children: "Install Widget"
|
|
86
86
|
})
|
|
87
87
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/widgets/WidgetDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { LayoutGrid, ArrowLeft, Star, Download } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetConfigurationQuery } from \"@/generated/wspace-operations\";\n\nexport function WidgetDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationQuery({\n variables: { id: id ?? \"\" },\n skip: !id,\n });\n\n const config = data?.configuration;\n const val = (config?.value as Record<string, unknown>) ?? {};\n const name =\n (val.name as string) ?? config?.key?.replace(\"widget.\", \"\") ?? \"Widget\";\n const description =\n config?.description ??\n (val.description as string) ??\n \"A configurable dashboard widget for time tracking.\";\n const rating = (val.rating as number) ?? 0;\n const installs = (val.downloads as number) ?? 0;\n\n if (loading) {\n return (\n <PageLayout title=\"Widget Details\" description=\"Loading...\">\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error || !config) {\n return (\n <PageLayout\n title=\"Widget Details\"\n description={`Widget ID: ${id}`}\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":"WidgetDetailPage.js","names":[],"sources":["../../../../src/timecampus/pages/widgets/WidgetDetailPage.tsx"],"sourcesContent":["import { useParams } from \"react-router-dom\";\nimport { LayoutGrid, ArrowLeft, Star, Download } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport { useGetConfigurationQuery } from \"@/generated/wspace-operations\";\n\nexport function WidgetDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useGetConfigurationQuery({\n variables: { id: id ?? \"\" },\n skip: !id,\n });\n\n const config = data?.configuration;\n const val = (config?.value as Record<string, unknown>) ?? {};\n const name =\n (val.name as string) ?? config?.key?.replace(\"widget.\", \"\") ?? \"Widget\";\n const description =\n config?.description ??\n (val.description as string) ??\n \"A configurable dashboard widget for time tracking.\";\n const rating = (val.rating as number) ?? 0;\n const installs = (val.downloads as number) ?? 0;\n\n if (loading) {\n return (\n <PageLayout title=\"Widget Details\" description=\"Loading...\">\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error || !config) {\n return (\n <PageLayout\n title=\"Widget Details\"\n description={`Widget ID: ${id}`}\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 Widgets\n </button>\n }\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n {error\n ? \"Failed to load widget details. Please try again later.\"\n : \"Widget configuration not found.\"}\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Widget Details\"\n description={`Widget ID: ${id}`}\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 Widgets\n </button>\n }\n >\n <div className=\"mx-auto max-w-2xl\">\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-xl bg-action-primary-bg/10\">\n <LayoutGrid className=\"h-8 w-8 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">{name}</h2>\n <p className=\"text-sm text-text-secondary\">{description}</p>\n <div className=\"mt-2 flex items-center gap-3 text-sm text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-4 w-4 fill-amber-400 text-amber-400\" />\n <span>{rating}</span>\n </div>\n <span>·</span>\n <div className=\"flex items-center gap-1\">\n <Download className=\"h-4 w-4\" />\n <span>{installs.toLocaleString()} installs</span>\n </div>\n </div>\n </div>\n </div>\n <div className=\"mt-6 flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle\">\n <p className=\"text-sm text-text-secondary\">\n Widget preview will render here\n </p>\n </div>\n <div className=\"mt-4 flex justify-end\">\n <button 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\">\n Install Widget\n </button>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,IAAmB;CACjC,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAAyB;EACxD,WAAW,EAAE,IAAI,KAAM,IAAI;EAC3B,MAAM,CAAC;EACR,CAAC,EAEI,IAAS,GAAM,eACf,IAAO,GAAQ,SAAqC,EAAE,EACtD,IACH,EAAI,QAAmB,GAAQ,KAAK,QAAQ,WAAW,GAAG,IAAI,UAC3D,IACJ,GAAQ,eACP,EAAI,eACL,sDACI,IAAU,EAAI,UAAqB,GACnC,IAAY,EAAI,aAAwB;AA+B9C,QA7BI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAiB,aAAY;YAC7C,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,KAAS,CAAC,IAEV,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,cAAc;EAC3B,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,kBAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACZ,IACG,2DACA;GACA,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAa,cAAc;EAC3B,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,kBAE1B;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAY,WAAU,wBAAyB,CAAA;OAC3C,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,MAAD;SAAI,WAAU;mBAA2C;SAAU,CAAA;QACnE,kBAAC,KAAD;SAAG,WAAU;mBAA+B;SAAgB,CAAA;QAC5D,kBAAC,OAAD;SAAK,WAAU;mBAAf;UACE,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,yCAA0C,CAAA,EAC1D,kBAAC,QAAD,EAAA,UAAO,GAAc,CAAA,CACjB;;UACN,kBAAC,QAAD,EAAA,UAAM,KAAe,CAAA;UACrB,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAChC,kBAAC,QAAD,EAAA,UAAA,CAAO,EAAS,gBAAgB,EAAC,YAAgB,EAAA,CAAA,CAC7C;;UACF;;QACF;SACF;;KACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,KAAD;OAAG,WAAU;iBAA8B;OAEvC,CAAA;MACA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,UAAD;OAAQ,WAAU;iBAAuH;OAEhI,CAAA;MACL,CAAA;KACF;;GACF,CAAA;EACK,CAAA"}
|
|
@@ -25,30 +25,30 @@ function l() {
|
|
|
25
25
|
title: "Widgets",
|
|
26
26
|
description: "Customize your dashboard with widgets",
|
|
27
27
|
actions: /* @__PURE__ */ c("button", {
|
|
28
|
-
className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
28
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
29
29
|
children: [/* @__PURE__ */ s(a, { className: "h-4 w-4" }), "Create Widget"]
|
|
30
30
|
}),
|
|
31
31
|
children: /* @__PURE__ */ s("div", {
|
|
32
32
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
33
33
|
children: p.length === 0 ? /* @__PURE__ */ s("div", {
|
|
34
|
-
className: "col-span-full p-8 text-center text-sm text-
|
|
34
|
+
className: "col-span-full p-8 text-center text-sm text-text-secondary",
|
|
35
35
|
children: "No widgets configured yet. Widgets are stored as workspace configurations with the \"widget.\" key prefix."
|
|
36
36
|
}) : p.map((e) => {
|
|
37
37
|
let t = e.value, n = t.name ?? e.key.replace("widget.", ""), r = t.category ?? "General", a = t.size ?? "medium", l = t.isInstalled ?? !1, u = t.rating ?? 0, d = t.downloads ?? 0;
|
|
38
38
|
return /* @__PURE__ */ c("div", {
|
|
39
|
-
className: "rounded-xl border border-border bg-
|
|
39
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer",
|
|
40
40
|
children: [/* @__PURE__ */ c("div", {
|
|
41
41
|
className: "flex items-start justify-between",
|
|
42
42
|
children: [/* @__PURE__ */ c("div", {
|
|
43
43
|
className: "flex items-center gap-3",
|
|
44
44
|
children: [/* @__PURE__ */ s("div", {
|
|
45
|
-
className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10",
|
|
45
|
+
className: "flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10",
|
|
46
46
|
children: /* @__PURE__ */ s(i, { className: "h-5 w-5 text-primary" })
|
|
47
47
|
}), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
48
|
-
className: "text-sm font-semibold text-
|
|
48
|
+
className: "text-sm font-semibold text-text-primary",
|
|
49
49
|
children: n
|
|
50
50
|
}), /* @__PURE__ */ c("p", {
|
|
51
|
-
className: "text-xs text-
|
|
51
|
+
className: "text-xs text-text-secondary",
|
|
52
52
|
children: [
|
|
53
53
|
r,
|
|
54
54
|
" · ",
|
|
@@ -60,7 +60,7 @@ function l() {
|
|
|
60
60
|
children: "Installed"
|
|
61
61
|
})]
|
|
62
62
|
}), /* @__PURE__ */ c("div", {
|
|
63
|
-
className: "mt-3 flex items-center justify-between text-xs text-
|
|
63
|
+
className: "mt-3 flex items-center justify-between text-xs text-text-secondary",
|
|
64
64
|
children: [/* @__PURE__ */ c("div", {
|
|
65
65
|
className: "flex items-center gap-1",
|
|
66
66
|
children: [/* @__PURE__ */ s(o, { className: "h-3 w-3 fill-amber-400 text-amber-400" }), /* @__PURE__ */ s("span", { children: u })]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WidgetsPage.js","names":[],"sources":["../../../../src/timecampus/pages/widgets/WidgetsPage.tsx"],"sourcesContent":["import { LayoutGrid, Plus, Star } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function WidgetsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent widgets (key starts with 'widget.')\n const widgets = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"widget.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load widget configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
1
|
+
{"version":3,"file":"WidgetsPage.js","names":[],"sources":["../../../../src/timecampus/pages/widgets/WidgetsPage.tsx"],"sourcesContent":["import { LayoutGrid, Plus, Star } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function WidgetsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent widgets (key starts with 'widget.')\n const widgets = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"widget.\"),\n );\n\n if (loading) {\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n >\n <LoadingSkeleton variant=\"card\" count={6} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n >\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load widget configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Widgets\"\n description=\"Customize your dashboard with widgets\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Create Widget\n </button>\n }\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {widgets.length === 0 ? (\n <div className=\"col-span-full p-8 text-center text-sm text-text-secondary\">\n No widgets configured yet. Widgets are stored as workspace\n configurations with the \"widget.\" key prefix.\n </div>\n ) : (\n widgets.map((widget: ConfigurationFieldsFragment) => {\n const val = widget.value as Record<string, unknown>;\n const name =\n (val.name as string) ?? widget.key.replace(\"widget.\", \"\");\n const category = (val.category as string) ?? \"General\";\n const size = (val.size as string) ?? \"medium\";\n const isInstalled = (val.isInstalled as boolean) ?? false;\n const rating = (val.rating as number) ?? 0;\n const downloads = (val.downloads as number) ?? 0;\n\n return (\n <div\n key={widget.id}\n className=\"rounded-xl border border-border-subtle bg-bg-surface p-5 transition-colors hover:bg-bg-sunken/50 cursor-pointer\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <LayoutGrid className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">\n {name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {category} · {size}\n </p>\n </div>\n </div>\n {isInstalled && (\n <span className=\"inline-flex rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400\">\n Installed\n </span>\n )}\n </div>\n <div className=\"mt-3 flex items-center justify-between text-xs text-text-secondary\">\n <div className=\"flex items-center gap-1\">\n <Star className=\"h-3 w-3 fill-amber-400 text-amber-400\" />\n <span>{rating}</span>\n </div>\n <span>{downloads} downloads</span>\n </div>\n </div>\n );\n })\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;AASA,SAAgB,IAAc;CAC5B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGlB,QAAQ,MACrC,EAAE,IAAI,WAAW,UAAU,CAC5B;AA0BD,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,gBAErB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAQ,WAAW,IAClB,kBAAC,OAAD;IAAK,WAAU;cAA4D;IAGrE,CAAA,GAEN,EAAQ,KAAK,MAAwC;IACnD,IAAM,IAAM,EAAO,OACb,IACH,EAAI,QAAmB,EAAO,IAAI,QAAQ,WAAW,GAAG,EACrD,IAAY,EAAI,YAAuB,WACvC,IAAQ,EAAI,QAAmB,UAC/B,IAAe,EAAI,eAA2B,IAC9C,IAAU,EAAI,UAAqB,GACnC,IAAa,EAAI,aAAwB;AAE/C,WACE,kBAAC,OAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAY,WAAU,wBAAyB,CAAA;QAC3C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV;QACC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACG;SAAS;SAAW;SACnB;UACA,EAAA,CAAA,CACF;UACL,KACC,kBAAC,QAAD;OAAM,WAAU;iBAAwI;OAEjJ,CAAA,CAEL;SACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD,EAAM,WAAU,yCAA0C,CAAA,EAC1D,kBAAC,QAAD,EAAA,UAAO,GAAc,CAAA,CACjB;UACN,kBAAC,QAAD,EAAA,UAAA,CAAO,GAAU,aAAiB,EAAA,CAAA,CAC9B;QACF;OA9BC,EAAO,GA8BR;KAER;GAEA,CAAA;EACK,CAAA"}
|
|
@@ -22,7 +22,7 @@ function f() {
|
|
|
22
22
|
title: "Work Patterns",
|
|
23
23
|
description: "Analyze your work habits and productivity patterns",
|
|
24
24
|
children: /* @__PURE__ */ u("div", {
|
|
25
|
-
className: "rounded-xl border border-
|
|
25
|
+
className: "rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text",
|
|
26
26
|
children: "Failed to load work patterns. Please try again later."
|
|
27
27
|
})
|
|
28
28
|
}) : /* @__PURE__ */ d(t, {
|
|
@@ -62,26 +62,26 @@ function f() {
|
|
|
62
62
|
}), /* @__PURE__ */ d("div", {
|
|
63
63
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
64
64
|
children: [/* @__PURE__ */ d("div", {
|
|
65
|
-
className: "rounded-xl border border-border bg-
|
|
65
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
66
66
|
children: [/* @__PURE__ */ u("h3", {
|
|
67
|
-
className: "mb-4 text-sm font-semibold text-
|
|
67
|
+
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
68
68
|
children: "Daily Work Pattern"
|
|
69
69
|
}), /* @__PURE__ */ u("div", {
|
|
70
|
-
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
70
|
+
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
|
|
71
71
|
children: /* @__PURE__ */ u("p", {
|
|
72
|
-
className: "text-sm text-
|
|
72
|
+
className: "text-sm text-text-secondary",
|
|
73
73
|
children: "Heatmap will render here"
|
|
74
74
|
})
|
|
75
75
|
})]
|
|
76
76
|
}), /* @__PURE__ */ d("div", {
|
|
77
|
-
className: "rounded-xl border border-border bg-
|
|
77
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
78
78
|
children: [/* @__PURE__ */ u("h3", {
|
|
79
|
-
className: "mb-4 text-sm font-semibold text-
|
|
79
|
+
className: "mb-4 text-sm font-semibold text-text-primary",
|
|
80
80
|
children: "Energy Levels"
|
|
81
81
|
}), /* @__PURE__ */ u("div", {
|
|
82
|
-
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
82
|
+
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border-subtle",
|
|
83
83
|
children: /* @__PURE__ */ u("p", {
|
|
84
|
-
className: "text-sm text-
|
|
84
|
+
className: "text-sm text-text-secondary",
|
|
85
85
|
children: "Energy chart will render here"
|
|
86
86
|
})
|
|
87
87
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkPatternsPage.js","names":[],"sources":["../../../../src/timecampus/pages/work-patterns/WorkPatternsPage.tsx"],"sourcesContent":["import { TrendingUp, Clock, Zap, Brain } 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 useListWorkPatternsQuery,\n useGetWorkPatternSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function WorkPatternsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: patternsData,\n loading: patternsLoading,\n error: patternsError,\n } = useListWorkPatternsQuery({\n variables: { limit: 30 },\n skip: !workspaceId,\n });\n\n const {\n data: summaryData,\n loading: summaryLoading,\n error: summaryError,\n } = useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const loading = patternsLoading || summaryLoading;\n const error = patternsError || summaryError;\n const summary = summaryData?.workPatternSummary;\n const patterns = patternsData?.workPatterns ?? [];\n\n // Derive stats from the latest pattern entry\n const latestPattern = patterns[0];\n const productivityScore =\n summary?.averageProductivity != null\n ? `${Math.round(summary.averageProductivity)}%`\n : \"--\";\n const focusHours =\n latestPattern?.focusHours != null\n ? `${latestPattern.focusHours.toFixed(1)}h`\n : \"--\";\n const totalHours = latestPattern\n ? (\n latestPattern.focusHours +\n latestPattern.meetingHours +\n latestPattern.breakHours\n ).toFixed(0)\n : \"8\";\n const deepWorkSessions =\n latestPattern?.deepWorkSessions != null\n ? String(latestPattern.deepWorkSessions)\n : \"--\";\n const mostProductiveDay = summary?.mostProductiveDay ?? \"--\";\n\n if (loading) {\n return (\n <PageLayout\n title=\"Work Patterns\"\n description=\"Analyze your work habits and productivity patterns\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Work Patterns\"\n description=\"Analyze your work habits and productivity patterns\"\n >\n <div className=\"rounded-xl border border-
|
|
1
|
+
{"version":3,"file":"WorkPatternsPage.js","names":[],"sources":["../../../../src/timecampus/pages/work-patterns/WorkPatternsPage.tsx"],"sourcesContent":["import { TrendingUp, Clock, Zap, Brain } 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 useListWorkPatternsQuery,\n useGetWorkPatternSummaryQuery,\n} from \"@/generated/wspace-operations\";\n\nexport function WorkPatternsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const {\n data: patternsData,\n loading: patternsLoading,\n error: patternsError,\n } = useListWorkPatternsQuery({\n variables: { limit: 30 },\n skip: !workspaceId,\n });\n\n const {\n data: summaryData,\n loading: summaryLoading,\n error: summaryError,\n } = useGetWorkPatternSummaryQuery({\n skip: !workspaceId,\n });\n\n const loading = patternsLoading || summaryLoading;\n const error = patternsError || summaryError;\n const summary = summaryData?.workPatternSummary;\n const patterns = patternsData?.workPatterns ?? [];\n\n // Derive stats from the latest pattern entry\n const latestPattern = patterns[0];\n const productivityScore =\n summary?.averageProductivity != null\n ? `${Math.round(summary.averageProductivity)}%`\n : \"--\";\n const focusHours =\n latestPattern?.focusHours != null\n ? `${latestPattern.focusHours.toFixed(1)}h`\n : \"--\";\n const totalHours = latestPattern\n ? (\n latestPattern.focusHours +\n latestPattern.meetingHours +\n latestPattern.breakHours\n ).toFixed(0)\n : \"8\";\n const deepWorkSessions =\n latestPattern?.deepWorkSessions != null\n ? String(latestPattern.deepWorkSessions)\n : \"--\";\n const mostProductiveDay = summary?.mostProductiveDay ?? \"--\";\n\n if (loading) {\n return (\n <PageLayout\n title=\"Work Patterns\"\n description=\"Analyze your work habits and productivity patterns\"\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Work Patterns\"\n description=\"Analyze your work habits and productivity patterns\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load work patterns. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Work Patterns\"\n description=\"Analyze your work habits and productivity patterns\"\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title=\"Productivity Score\"\n value={productivityScore}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n trend={\n summary?.averageProductivity != null\n ? { value: 5, label: \"vs last week\" }\n : undefined\n }\n />\n <StatCard\n title=\"Focus Hours\"\n value={focusHours}\n icon={<Brain className=\"h-5 w-5\" />}\n description={`Out of ${totalHours}h total`}\n />\n <StatCard\n title=\"Peak Day\"\n value={mostProductiveDay}\n icon={<Zap className=\"h-5 w-5\" />}\n description=\"Most productive day\"\n />\n <StatCard\n title=\"Deep Work\"\n value={`${deepWorkSessions} sessions`}\n icon={<Clock className=\"h-5 w-5\" />}\n description=\"90+ min uninterrupted\"\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-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Daily Work Pattern\n </h3>\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 Heatmap will render here\n </p>\n </div>\n </div>\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-text-primary\">\n Energy Levels\n </h3>\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 Energy chart will render here\n </p>\n </div>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,IAAmB;CACjC,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAAyB;EAC3B,WAAW,EAAE,OAAO,IAAI;EACxB,MAAM,CAAC;EACR,CAAC,EAEI,EACJ,MAAM,GACN,SAAS,GACT,OAAO,MACL,EAA8B,EAChC,MAAM,CAAC,GACR,CAAC,EAEI,IAAU,KAAmB,GAC7B,IAAQ,KAAiB,GACzB,IAAU,GAAa,oBAIvB,KAHW,GAAc,gBAAgB,EAAE,EAGlB,IACzB,IACJ,GAAS,uBAAuB,OAE5B,OADA,GAAG,KAAK,MAAM,EAAQ,oBAAoB,CAAC,IAE3C,IACJ,GAAe,cAAc,OAEzB,OADA,GAAG,EAAc,WAAW,QAAQ,EAAE,CAAC,IAEvC,IAAa,KAEb,EAAc,aACd,EAAc,eACd,EAAc,YACd,QAAQ,EAAE,GACZ,KACE,IACJ,GAAe,oBAAoB,OAE/B,OADA,OAAO,EAAc,iBAAiB,EAEtC,IAAoB,GAAS,qBAAqB;AA0BxD,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAFd,CAIE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;KACxC,OACE,GAAS,uBAAuB,OAE5B,KAAA,IADA;MAAE,OAAO;MAAG,OAAO;MAAgB;KAGzC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAa,UAAU,EAAW;KAClC,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO;KACP,MAAM,kBAAC,GAAD,EAAK,WAAU,WAAY,CAAA;KACjC,aAAY;KACZ,CAAA;IACF,kBAAC,GAAD;KACE,OAAM;KACN,OAAO,GAAG,EAAiB;KAC3B,MAAM,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;KACnC,aAAY;KACZ,CAAA;IACE;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA+C;KAExD,CAAA,EACL,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAEvC,CAAA;KACA,CAAA,CACF;OACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA+C;KAExD,CAAA,EACL,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,KAAD;MAAG,WAAU;gBAA8B;MAEvC,CAAA;KACA,CAAA,CACF;MACF;KACK"}
|
|
@@ -48,7 +48,7 @@ function p() {
|
|
|
48
48
|
title: "Work Patterns Settings",
|
|
49
49
|
description: "Configure work pattern tracking",
|
|
50
50
|
children: /* @__PURE__ */ l("div", {
|
|
51
|
-
className: "rounded-xl border border-
|
|
51
|
+
className: "rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text",
|
|
52
52
|
children: "Failed to load settings. Please try again later."
|
|
53
53
|
})
|
|
54
54
|
}) : /* @__PURE__ */ l(t, {
|
|
@@ -57,9 +57,9 @@ function p() {
|
|
|
57
57
|
children: /* @__PURE__ */ u("div", {
|
|
58
58
|
className: "mx-auto max-w-2xl space-y-6",
|
|
59
59
|
children: [/* @__PURE__ */ u("div", {
|
|
60
|
-
className: "rounded-xl border border-border bg-
|
|
60
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface p-6",
|
|
61
61
|
children: [/* @__PURE__ */ u("h3", {
|
|
62
|
-
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-
|
|
62
|
+
className: "mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary",
|
|
63
63
|
children: [/* @__PURE__ */ l(c, { className: "h-4 w-4" }), "Tracking Preferences"]
|
|
64
64
|
}), /* @__PURE__ */ u("div", {
|
|
65
65
|
className: "space-y-3",
|
|
@@ -67,7 +67,7 @@ function p() {
|
|
|
67
67
|
/* @__PURE__ */ u("label", {
|
|
68
68
|
className: "flex items-center justify-between",
|
|
69
69
|
children: [/* @__PURE__ */ l("span", {
|
|
70
|
-
className: "text-sm text-
|
|
70
|
+
className: "text-sm text-text-primary",
|
|
71
71
|
children: "Track energy levels"
|
|
72
72
|
}), /* @__PURE__ */ l("input", {
|
|
73
73
|
type: "checkbox",
|
|
@@ -76,13 +76,13 @@ function p() {
|
|
|
76
76
|
...t,
|
|
77
77
|
trackEnergyLevels: e.target.checked
|
|
78
78
|
})),
|
|
79
|
-
className: "h-4 w-4 rounded border-border"
|
|
79
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
80
80
|
})]
|
|
81
81
|
}),
|
|
82
82
|
/* @__PURE__ */ u("label", {
|
|
83
83
|
className: "flex items-center justify-between",
|
|
84
84
|
children: [/* @__PURE__ */ l("span", {
|
|
85
|
-
className: "text-sm text-
|
|
85
|
+
className: "text-sm text-text-primary",
|
|
86
86
|
children: "Track mood"
|
|
87
87
|
}), /* @__PURE__ */ l("input", {
|
|
88
88
|
type: "checkbox",
|
|
@@ -91,13 +91,13 @@ function p() {
|
|
|
91
91
|
...t,
|
|
92
92
|
trackMood: e.target.checked
|
|
93
93
|
})),
|
|
94
|
-
className: "h-4 w-4 rounded border-border"
|
|
94
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
95
95
|
})]
|
|
96
96
|
}),
|
|
97
97
|
/* @__PURE__ */ u("label", {
|
|
98
98
|
className: "flex items-center justify-between",
|
|
99
99
|
children: [/* @__PURE__ */ l("span", {
|
|
100
|
-
className: "text-sm text-
|
|
100
|
+
className: "text-sm text-text-primary",
|
|
101
101
|
children: "Interruption tracking"
|
|
102
102
|
}), /* @__PURE__ */ l("input", {
|
|
103
103
|
type: "checkbox",
|
|
@@ -106,7 +106,7 @@ function p() {
|
|
|
106
106
|
...t,
|
|
107
107
|
interruptionTracking: e.target.checked
|
|
108
108
|
})),
|
|
109
|
-
className: "h-4 w-4 rounded border-border"
|
|
109
|
+
className: "h-4 w-4 rounded border-border-subtle"
|
|
110
110
|
})]
|
|
111
111
|
})
|
|
112
112
|
]
|
|
@@ -116,7 +116,7 @@ function p() {
|
|
|
116
116
|
children: /* @__PURE__ */ l("button", {
|
|
117
117
|
onClick: x,
|
|
118
118
|
disabled: v,
|
|
119
|
-
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-
|
|
119
|
+
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",
|
|
120
120
|
children: v ? "Saving..." : "Save Settings"
|
|
121
121
|
})
|
|
122
122
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkPatternsSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/work-patterns/WorkPatternsSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst WORK_PATTERNS_SETTINGS_KEY = \"timecampus.workpatterns.settings\";\n\ninterface WorkPatternsSettings {\n trackEnergyLevels: boolean;\n trackMood: boolean;\n interruptionTracking: boolean;\n}\n\nconst DEFAULT_SETTINGS: WorkPatternsSettings = {\n trackEnergyLevels: true,\n trackMood: true,\n interruptionTracking: true,\n};\n\nexport function WorkPatternsSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] =\n useState<WorkPatternsSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const config = data.configurations.find(\n (c: ConfigurationFieldsFragment) =>\n c.key === WORK_PATTERNS_SETTINGS_KEY,\n );\n if (config?.value) {\n const val = config.value as Partial<WorkPatternsSettings>;\n setSettings({\n trackEnergyLevels:\n val.trackEnergyLevels ?? DEFAULT_SETTINGS.trackEnergyLevels,\n trackMood: val.trackMood ?? DEFAULT_SETTINGS.trackMood,\n interruptionTracking:\n val.interruptionTracking ?? DEFAULT_SETTINGS.interruptionTracking,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: WORK_PATTERNS_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Work patterns tracking settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Work Patterns Settings\"\n description=\"Configure work pattern tracking\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Work Patterns Settings\"\n description=\"Configure work pattern tracking\"\n >\n <div className=\"rounded-xl border border-
|
|
1
|
+
{"version":3,"file":"WorkPatternsSettingsPage.js","names":[],"sources":["../../../../src/timecampus/pages/work-patterns/WorkPatternsSettingsPage.tsx"],"sourcesContent":["import { useState, useEffect, useCallback } from \"react\";\nimport { Settings } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n useSetConfigurationMutation,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nconst WORK_PATTERNS_SETTINGS_KEY = \"timecampus.workpatterns.settings\";\n\ninterface WorkPatternsSettings {\n trackEnergyLevels: boolean;\n trackMood: boolean;\n interruptionTracking: boolean;\n}\n\nconst DEFAULT_SETTINGS: WorkPatternsSettings = {\n trackEnergyLevels: true,\n trackMood: true,\n interruptionTracking: true,\n};\n\nexport function WorkPatternsSettingsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as never, limit: 100 },\n skip: !workspaceId,\n });\n\n const [setConfiguration, { loading: saving }] = useSetConfigurationMutation();\n const [settings, setSettings] =\n useState<WorkPatternsSettings>(DEFAULT_SETTINGS);\n\n useEffect(() => {\n if (data?.configurations) {\n const config = data.configurations.find(\n (c: ConfigurationFieldsFragment) =>\n c.key === WORK_PATTERNS_SETTINGS_KEY,\n );\n if (config?.value) {\n const val = config.value as Partial<WorkPatternsSettings>;\n setSettings({\n trackEnergyLevels:\n val.trackEnergyLevels ?? DEFAULT_SETTINGS.trackEnergyLevels,\n trackMood: val.trackMood ?? DEFAULT_SETTINGS.trackMood,\n interruptionTracking:\n val.interruptionTracking ?? DEFAULT_SETTINGS.interruptionTracking,\n });\n }\n }\n }, [data]);\n\n const handleSave = useCallback(async () => {\n await setConfiguration({\n variables: {\n input: {\n key: WORK_PATTERNS_SETTINGS_KEY,\n value: settings as unknown as Record<string, unknown>,\n description: \"Work patterns tracking settings\",\n scope: \"WORKSPACE\" as never,\n },\n },\n });\n }, [setConfiguration, settings]);\n\n if (loading) {\n return (\n <PageLayout\n title=\"Work Patterns Settings\"\n description=\"Configure work pattern tracking\"\n >\n <LoadingSkeleton variant=\"detail\" />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout\n title=\"Work Patterns Settings\"\n description=\"Configure work pattern tracking\"\n >\n <div className=\"rounded-xl border border-status-error-border/50 bg-status-error-bg/10 p-4 text-sm text-status-error-text\">\n Failed to load settings. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Work Patterns Settings\"\n description=\"Configure work pattern tracking\"\n >\n <div className=\"mx-auto max-w-2xl space-y-6\">\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface p-6\">\n <h3 className=\"mb-4 flex items-center gap-2 text-sm font-semibold text-text-primary\">\n <Settings className=\"h-4 w-4\" />\n Tracking Preferences\n </h3>\n <div className=\"space-y-3\">\n <label className=\"flex items-center justify-between\">\n <span className=\"text-sm text-text-primary\">\n Track energy levels\n </span>\n <input\n type=\"checkbox\"\n checked={settings.trackEnergyLevels}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n trackEnergyLevels: e.target.checked,\n }))\n }\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\">Track mood</span>\n <input\n type=\"checkbox\"\n checked={settings.trackMood}\n onChange={(e) =>\n setSettings((s) => ({ ...s, trackMood: e.target.checked }))\n }\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 Interruption tracking\n </span>\n <input\n type=\"checkbox\"\n checked={settings.interruptionTracking}\n onChange={(e) =>\n setSettings((s) => ({\n ...s,\n interruptionTracking: e.target.checked,\n }))\n }\n className=\"h-4 w-4 rounded border-border-subtle\"\n />\n </label>\n </div>\n </div>\n <div className=\"flex justify-end\">\n <button\n onClick={handleSave}\n disabled={saving}\n className=\"rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {saving ? \"Saving...\" : \"Save Settings\"}\n </button>\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAWA,IAAM,IAA6B,oCAQ7B,IAAyC;CAC7C,mBAAmB;CACnB,WAAW;CACX,sBAAsB;CACvB;AAED,SAAgB,IAA2B;CACzC,IAAM,EAAE,iBAAc,OAAO,GAAe,EACtC,EAAE,SAAM,YAAS,aAAU,EAA2B;EAC1D,WAAW;GAAE,OAAO;GAAsB,OAAO;GAAK;EACtD,MAAM,CAAC;EACR,CAAC,EAEI,CAAC,GAAkB,EAAE,SAAS,OAAY,GAA6B,EACvE,CAAC,GAAU,KACf,EAA+B,EAAiB;AAElD,SAAgB;AACd,MAAI,GAAM,gBAAgB;GACxB,IAAM,IAAS,EAAK,eAAe,MAChC,MACC,EAAE,QAAQ,EACb;AACD,OAAI,GAAQ,OAAO;IACjB,IAAM,IAAM,EAAO;AACnB,MAAY;KACV,mBACE,EAAI,qBAAqB,EAAiB;KAC5C,WAAW,EAAI,aAAa,EAAiB;KAC7C,sBACE,EAAI,wBAAwB,EAAiB;KAChD,CAAC;;;IAGL,CAAC,EAAK,CAAC;CAEV,IAAM,IAAa,EAAY,YAAY;AACzC,QAAM,EAAiB,EACrB,WAAW,EACT,OAAO;GACL,KAAK;GACL,OAAO;GACP,aAAa;GACb,OAAO;GACR,EACF,EACF,CAAC;IACD,CAAC,GAAkB,EAAS,CAAC;AA0BhC,QAxBI,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,GAAD,EAAiB,SAAQ,UAAW,CAAA;EACzB,CAAA,GAIb,IAEA,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAA2G;GAEpH,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;YAEZ,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd,CACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,uBAE7B;QACL,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAErC,CAAA,EACP,kBAAC,SAAD;QACE,MAAK;QACL,SAAS,EAAS;QAClB,WAAW,MACT,GAAa,OAAO;SAClB,GAAG;SACH,mBAAmB,EAAE,OAAO;SAC7B,EAAE;QAEL,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAAiB,CAAA,EAC7D,kBAAC,SAAD;QACE,MAAK;QACL,SAAS,EAAS;QAClB,WAAW,MACT,GAAa,OAAO;SAAE,GAAG;SAAG,WAAW,EAAE,OAAO;SAAS,EAAE;QAE7D,WAAU;QACV,CAAA,CACI;;MACR,kBAAC,SAAD;OAAO,WAAU;iBAAjB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAA4B;QAErC,CAAA,EACP,kBAAC,SAAD;QACE,MAAK;QACL,SAAS,EAAS;QAClB,WAAW,MACT,GAAa,OAAO;SAClB,GAAG;SACH,sBAAsB,EAAE,OAAO;SAChC,EAAE;QAEL,WAAU;QACV,CAAA,CACI;;MACJ;OACF;OACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,UAAD;KACE,SAAS;KACT,UAAU;KACV,WAAU;eAET,IAAS,cAAc;KACjB,CAAA;IACL,CAAA,CACF;;EACK,CAAA"}
|
|
@@ -26,30 +26,30 @@ function u() {
|
|
|
26
26
|
title: "Workflows",
|
|
27
27
|
description: "Automate repetitive tasks",
|
|
28
28
|
actions: /* @__PURE__ */ l("button", {
|
|
29
|
-
className: "inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
29
|
+
className: "inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90",
|
|
30
30
|
children: [/* @__PURE__ */ c(o, { className: "h-4 w-4" }), "Create Workflow"]
|
|
31
31
|
}),
|
|
32
32
|
children: /* @__PURE__ */ c("div", {
|
|
33
|
-
className: "rounded-xl border border-border bg-
|
|
33
|
+
className: "rounded-xl border border-border-subtle bg-bg-surface",
|
|
34
34
|
children: /* @__PURE__ */ c("div", {
|
|
35
35
|
className: "divide-y divide-border",
|
|
36
36
|
children: m.length === 0 ? /* @__PURE__ */ c("div", {
|
|
37
|
-
className: "p-8 text-center text-sm text-
|
|
37
|
+
className: "p-8 text-center text-sm text-text-secondary",
|
|
38
38
|
children: "No workflows configured yet. Workflows are stored as workspace configurations with the \"workflow.\" key prefix."
|
|
39
39
|
}) : m.map((e) => {
|
|
40
40
|
let n = e.value, r = n.name ?? e.key.replace("workflow.", ""), i = n.status ?? "inactive", o = n.trigger ?? "Manual", u = n.lastRun ?? "Never", d = n.runCount ?? 0, f = n.successRate ?? 0;
|
|
41
41
|
return /* @__PURE__ */ l("div", {
|
|
42
|
-
className: "flex items-center justify-between p-4 hover:bg-
|
|
42
|
+
className: "flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors cursor-pointer",
|
|
43
43
|
children: [/* @__PURE__ */ l("div", {
|
|
44
44
|
className: "flex items-center gap-3",
|
|
45
45
|
children: [/* @__PURE__ */ c("div", {
|
|
46
|
-
className: "flex h-9 w-9 items-center justify-center rounded-lg bg-primary/10",
|
|
46
|
+
className: "flex h-9 w-9 items-center justify-center rounded-lg bg-action-primary-bg/10",
|
|
47
47
|
children: /* @__PURE__ */ c(a, { className: "h-4 w-4 text-primary" })
|
|
48
48
|
}), /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
|
|
49
|
-
className: "text-sm font-medium text-
|
|
49
|
+
className: "text-sm font-medium text-text-primary",
|
|
50
50
|
children: r
|
|
51
51
|
}), /* @__PURE__ */ l("p", {
|
|
52
|
-
className: "text-xs text-
|
|
52
|
+
className: "text-xs text-text-secondary",
|
|
53
53
|
children: [
|
|
54
54
|
/* @__PURE__ */ c(s, { className: "inline h-3 w-3" }),
|
|
55
55
|
" ",
|
|
@@ -61,7 +61,7 @@ function u() {
|
|
|
61
61
|
}), /* @__PURE__ */ l("div", {
|
|
62
62
|
className: "flex items-center gap-4",
|
|
63
63
|
children: [/* @__PURE__ */ l("div", {
|
|
64
|
-
className: "text-right text-xs text-
|
|
64
|
+
className: "text-right text-xs text-text-secondary",
|
|
65
65
|
children: [/* @__PURE__ */ l("p", { children: [d, " runs"] }), /* @__PURE__ */ l("p", { children: [f, "% success"] })]
|
|
66
66
|
}), /* @__PURE__ */ c("span", {
|
|
67
67
|
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${t(i)}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../../src/timecampus/pages/workflows/WorkflowsPage.tsx"],"sourcesContent":["import { GitBranch, Plus, Zap } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function WorkflowsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent workflows (key starts with 'workflow.')\n const workflows = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"workflow.\"),\n );\n\n if (loading) {\n return (\n <PageLayout title=\"Workflows\" description=\"Automate repetitive tasks\">\n <LoadingSkeleton variant=\"list\" count={5} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout title=\"Workflows\" description=\"Automate repetitive tasks\">\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load workflow configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Workflows\"\n description=\"Automate repetitive tasks\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-2 text-sm font-medium text-primary-
|
|
1
|
+
{"version":3,"file":"WorkflowsPage.js","names":[],"sources":["../../../../src/timecampus/pages/workflows/WorkflowsPage.tsx"],"sourcesContent":["import { GitBranch, Plus, Zap } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { getStatusColor } from \"../../utils/helpers\";\nimport { useTimeCampus } from \"../../providers/TimeCampusProvider\";\nimport {\n useListConfigurationsQuery,\n type ConfigurationFieldsFragment,\n} from \"@/generated/wspace-operations\";\n\nexport function WorkflowsPage() {\n const { workspaceId = \"\" } = useTimeCampus();\n\n const { data, loading, error } = useListConfigurationsQuery({\n variables: { scope: \"WORKSPACE\" as any },\n });\n\n const configurations = data?.configurations ?? [];\n\n // Filter configurations that represent workflows (key starts with 'workflow.')\n const workflows = configurations.filter((c: ConfigurationFieldsFragment) =>\n c.key.startsWith(\"workflow.\"),\n );\n\n if (loading) {\n return (\n <PageLayout title=\"Workflows\" description=\"Automate repetitive tasks\">\n <LoadingSkeleton variant=\"list\" count={5} />\n </PageLayout>\n );\n }\n\n if (error) {\n return (\n <PageLayout title=\"Workflows\" description=\"Automate repetitive tasks\">\n <div className=\"rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700 dark:border-red-800 dark:bg-red-900/20 dark:text-red-400\">\n Failed to load workflow configurations. Please try again later.\n </div>\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Workflows\"\n description=\"Automate repetitive tasks\"\n actions={\n <button className=\"inline-flex items-center gap-1.5 rounded-md bg-action-primary-bg px-3 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\">\n <Plus className=\"h-4 w-4\" />\n Create Workflow\n </button>\n }\n >\n <div className=\"rounded-xl border border-border-subtle bg-bg-surface\">\n <div className=\"divide-y divide-border\">\n {workflows.length === 0 ? (\n <div className=\"p-8 text-center text-sm text-text-secondary\">\n No workflows configured yet. Workflows are stored as workspace\n configurations with the \"workflow.\" key prefix.\n </div>\n ) : (\n workflows.map((wf: ConfigurationFieldsFragment) => {\n const val = wf.value as Record<string, unknown>;\n const name =\n (val.name as string) ?? wf.key.replace(\"workflow.\", \"\");\n const status = (val.status as string) ?? \"inactive\";\n const trigger = (val.trigger as string) ?? \"Manual\";\n const lastRun = (val.lastRun as string) ?? \"Never\";\n const runCount = (val.runCount as number) ?? 0;\n const successRate = (val.successRate as number) ?? 0;\n\n return (\n <div\n key={wf.id}\n className=\"flex items-center justify-between p-4 hover:bg-bg-sunken/50 transition-colors cursor-pointer\"\n >\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-lg bg-action-primary-bg/10\">\n <GitBranch className=\"h-4 w-4 text-primary\" />\n </div>\n <div>\n <p className=\"text-sm font-medium text-text-primary\">\n {name}\n </p>\n <p className=\"text-xs text-text-secondary\">\n <Zap className=\"inline h-3 w-3\" /> {trigger} ·\n Last run: {lastRun}\n </p>\n </div>\n </div>\n <div className=\"flex items-center gap-4\">\n <div className=\"text-right text-xs text-text-secondary\">\n <p>{runCount} runs</p>\n <p>{successRate}% success</p>\n </div>\n <span\n className={`inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${getStatusColor(status)}`}\n >\n {status}\n </span>\n </div>\n </div>\n );\n })\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,iBAAc,OAAO,GAAe,EAEtC,EAAE,SAAM,YAAS,aAAU,EAA2B,EAC1D,WAAW,EAAE,OAAO,aAAoB,EACzC,CAAC,EAKI,KAHiB,GAAM,kBAAkB,EAAE,EAGhB,QAAQ,MACvC,EAAE,IAAI,WAAW,YAAY,CAC9B;AAoBD,QAlBI,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAY,aAAY;YACxC,kBAAC,GAAD;GAAiB,SAAQ;GAAO,OAAO;GAAK,CAAA;EACjC,CAAA,GAIb,IAEA,kBAAC,GAAD;EAAY,OAAM;EAAY,aAAY;YACxC,kBAAC,OAAD;GAAK,WAAU;aAA+H;GAExI,CAAA;EACK,CAAA,GAKf,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GAAQ,WAAU;aAAlB,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBAErB;;YAGX,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAU,WAAW,IACpB,kBAAC,OAAD;KAAK,WAAU;eAA8C;KAGvD,CAAA,GAEN,EAAU,KAAK,MAAoC;KACjD,IAAM,IAAM,EAAG,OACT,IACH,EAAI,QAAmB,EAAG,IAAI,QAAQ,aAAa,GAAG,EACnD,IAAU,EAAI,UAAqB,YACnC,IAAW,EAAI,WAAsB,UACrC,IAAW,EAAI,WAAsB,SACrC,IAAY,EAAI,YAAuB,GACvC,IAAe,EAAI,eAA0B;AAEnD,YACE,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD,EAAW,WAAU,wBAAyB,CAAA;QAC1C,CAAA,EACN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV;QACC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBAAb;SACE,kBAAC,GAAD,EAAK,WAAU,kBAAmB,CAAA;;SAAE;SAAQ;SACjC;SACT;UACA,EAAA,CAAA,CACF;UACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD,EAAA,UAAA,CAAI,GAAS,QAAS,EAAA,CAAA,EACtB,kBAAC,KAAD,EAAA,UAAA,CAAI,GAAY,YAAa,EAAA,CAAA,CACzB;WACN,kBAAC,QAAD;QACE,WAAW,4DAA4D,EAAe,EAAO;kBAE5F;QACI,CAAA,CACH;SACF;QA5BC,EAAG,GA4BJ;MAER;IAEA,CAAA;GACF,CAAA;EACK,CAAA"}
|
package/package.json
CHANGED