@burdenoff/microfe-timecampus 2026.510.104
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/README.md +12 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +20716 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +8527 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-operations.js +3913 -0
- package/dist/generated/wspace-operations.js.map +1 -0
- package/dist/generated/wspace-types.d.ts +53363 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +24 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/@apollo/client/errors/utils.js +16 -0
- package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/node_modules/clsx/dist/clsx.js +18 -0
- package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1674 -0
- package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
- package/dist/timecampus/TimeCampusRoot.d.ts +5 -0
- package/dist/timecampus/TimeCampusRoot.d.ts.map +1 -0
- package/dist/timecampus/TimeCampusRoot.js +344 -0
- package/dist/timecampus/TimeCampusRoot.js.map +1 -0
- package/dist/timecampus/TimeCampusRoutes.d.ts +7 -0
- package/dist/timecampus/TimeCampusRoutes.d.ts.map +1 -0
- package/dist/timecampus/TimeCampusRoutes.js +227 -0
- package/dist/timecampus/TimeCampusRoutes.js.map +1 -0
- package/dist/timecampus/components/ChartCard.d.ts +19 -0
- package/dist/timecampus/components/ChartCard.d.ts.map +1 -0
- package/dist/timecampus/components/DataTable.d.ts +26 -0
- package/dist/timecampus/components/DataTable.d.ts.map +1 -0
- package/dist/timecampus/components/EmptyState.d.ts +12 -0
- package/dist/timecampus/components/EmptyState.d.ts.map +1 -0
- package/dist/timecampus/components/ErrorBoundary.d.ts +19 -0
- package/dist/timecampus/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/timecampus/components/ErrorBoundary.js +52 -0
- package/dist/timecampus/components/ErrorBoundary.js.map +1 -0
- package/dist/timecampus/components/FilterBar.d.ts +26 -0
- package/dist/timecampus/components/FilterBar.d.ts.map +1 -0
- package/dist/timecampus/components/LoadingSkeleton.d.ts +10 -0
- package/dist/timecampus/components/LoadingSkeleton.d.ts.map +1 -0
- package/dist/timecampus/components/LoadingSkeleton.js +76 -0
- package/dist/timecampus/components/LoadingSkeleton.js.map +1 -0
- package/dist/timecampus/components/Modal.d.ts +14 -0
- package/dist/timecampus/components/Modal.d.ts.map +1 -0
- package/dist/timecampus/components/PageLayout.d.ts +12 -0
- package/dist/timecampus/components/PageLayout.d.ts.map +1 -0
- package/dist/timecampus/components/PageLayout.js +23 -0
- package/dist/timecampus/components/PageLayout.js.map +1 -0
- package/dist/timecampus/components/StatCard.d.ts +17 -0
- package/dist/timecampus/components/StatCard.d.ts.map +1 -0
- package/dist/timecampus/components/StatCard.js +48 -0
- package/dist/timecampus/components/StatCard.js.map +1 -0
- package/dist/timecampus/components/StatusBadge.d.ts +16 -0
- package/dist/timecampus/components/StatusBadge.d.ts.map +1 -0
- package/dist/timecampus/components/Toast.d.ts +28 -0
- package/dist/timecampus/components/Toast.d.ts.map +1 -0
- package/dist/timecampus/components/index.d.ts +14 -0
- package/dist/timecampus/components/index.d.ts.map +1 -0
- package/dist/timecampus/hooks/index.d.ts +7 -0
- package/dist/timecampus/hooks/index.d.ts.map +1 -0
- package/dist/timecampus/hooks/useToast.d.ts +17 -0
- package/dist/timecampus/hooks/useToast.d.ts.map +1 -0
- package/dist/timecampus/index.d.ts +10 -0
- package/dist/timecampus/index.d.ts.map +1 -0
- package/dist/timecampus/index.js +4 -0
- package/dist/timecampus/pages/HomePage.d.ts +4 -0
- package/dist/timecampus/pages/HomePage.d.ts.map +1 -0
- package/dist/timecampus/pages/HomePage.js +239 -0
- package/dist/timecampus/pages/HomePage.js.map +1 -0
- package/dist/timecampus/pages/applets/AppletStorePage.d.ts +2 -0
- package/dist/timecampus/pages/applets/AppletStorePage.d.ts.map +1 -0
- package/dist/timecampus/pages/applets/AppletStorePage.js +77 -0
- package/dist/timecampus/pages/applets/AppletStorePage.js.map +1 -0
- package/dist/timecampus/pages/applets/InstalledAppletsPage.d.ts +2 -0
- package/dist/timecampus/pages/applets/InstalledAppletsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js +83 -0
- package/dist/timecampus/pages/applets/InstalledAppletsPage.js.map +1 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.d.ts +2 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.d.ts.map +1 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js +118 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsagePage.js.map +1 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js +129 -0
- package/dist/timecampus/pages/application-usage/ApplicationUsageSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/channels/ChannelsPage.d.ts +2 -0
- package/dist/timecampus/pages/channels/ChannelsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/channels/ChannelsPage.js +64 -0
- package/dist/timecampus/pages/channels/ChannelsPage.js.map +1 -0
- package/dist/timecampus/pages/client-portal/ClientPortalPage.d.ts +2 -0
- package/dist/timecampus/pages/client-portal/ClientPortalPage.d.ts.map +1 -0
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js +108 -0
- package/dist/timecampus/pages/client-portal/ClientPortalPage.js.map +1 -0
- package/dist/timecampus/pages/dashboard/AnalyticsPage.d.ts +2 -0
- package/dist/timecampus/pages/dashboard/AnalyticsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js +91 -0
- package/dist/timecampus/pages/dashboard/AnalyticsPage.js.map +1 -0
- package/dist/timecampus/pages/dashboard/ReportsPage.d.ts +2 -0
- package/dist/timecampus/pages/dashboard/ReportsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/dashboard/ReportsPage.js +102 -0
- package/dist/timecampus/pages/dashboard/ReportsPage.js.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.d.ts +2 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js +73 -0
- package/dist/timecampus/pages/email-tracking/EmailAnalyticsPage.js.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js +138 -0
- package/dist/timecampus/pages/email-tracking/EmailSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.d.ts +2 -0
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.d.ts.map +1 -0
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js +71 -0
- package/dist/timecampus/pages/email-tracking/EmailTrackingPage.js.map +1 -0
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.d.ts +2 -0
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.d.ts.map +1 -0
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js +102 -0
- package/dist/timecampus/pages/expense-tracking/ExpenseTrackingPage.js.map +1 -0
- package/dist/timecampus/pages/focus-score/FocusScorePage.d.ts +2 -0
- package/dist/timecampus/pages/focus-score/FocusScorePage.d.ts.map +1 -0
- package/dist/timecampus/pages/focus-score/FocusScorePage.js +131 -0
- package/dist/timecampus/pages/focus-score/FocusScorePage.js.map +1 -0
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js +115 -0
- package/dist/timecampus/pages/focus-score/FocusScoreSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/geofencing/GeofencingPage.d.ts +2 -0
- package/dist/timecampus/pages/geofencing/GeofencingPage.d.ts.map +1 -0
- package/dist/timecampus/pages/geofencing/GeofencingPage.js +70 -0
- package/dist/timecampus/pages/geofencing/GeofencingPage.js.map +1 -0
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js +106 -0
- package/dist/timecampus/pages/geofencing/GeofencingSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.d.ts +2 -0
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js +77 -0
- package/dist/timecampus/pages/industry-solutions/IndustrySolutionsPage.js.map +1 -0
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js +115 -0
- package/dist/timecampus/pages/location-tracking/LocationPrivacySettingsPage.js.map +1 -0
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.d.ts +2 -0
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.d.ts.map +1 -0
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js +97 -0
- package/dist/timecampus/pages/location-tracking/LocationTrackingPage.js.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.d.ts +2 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js +89 -0
- package/dist/timecampus/pages/meetings/MeetingAnalyticsPage.js.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingCreatePage.d.ts +2 -0
- package/dist/timecampus/pages/meetings/MeetingCreatePage.d.ts.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js +101 -0
- package/dist/timecampus/pages/meetings/MeetingCreatePage.js.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingDetailPage.d.ts +2 -0
- package/dist/timecampus/pages/meetings/MeetingDetailPage.d.ts.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js +123 -0
- package/dist/timecampus/pages/meetings/MeetingDetailPage.js.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingsPage.d.ts +2 -0
- package/dist/timecampus/pages/meetings/MeetingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/meetings/MeetingsPage.js +90 -0
- package/dist/timecampus/pages/meetings/MeetingsPage.js.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.d.ts +2 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js +113 -0
- package/dist/timecampus/pages/pomodoro/PomodoroAnalyticsPage.js.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroPage.d.ts +2 -0
- package/dist/timecampus/pages/pomodoro/PomodoroPage.d.ts.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js +160 -0
- package/dist/timecampus/pages/pomodoro/PomodoroPage.js.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js +176 -0
- package/dist/timecampus/pages/pomodoro/PomodoroSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/projects/ProjectCreatePage.d.ts +2 -0
- package/dist/timecampus/pages/projects/ProjectCreatePage.d.ts.map +1 -0
- package/dist/timecampus/pages/projects/ProjectCreatePage.js +104 -0
- package/dist/timecampus/pages/projects/ProjectCreatePage.js.map +1 -0
- package/dist/timecampus/pages/projects/ProjectDetailPage.d.ts +2 -0
- package/dist/timecampus/pages/projects/ProjectDetailPage.d.ts.map +1 -0
- package/dist/timecampus/pages/projects/ProjectDetailPage.js +91 -0
- package/dist/timecampus/pages/projects/ProjectDetailPage.js.map +1 -0
- package/dist/timecampus/pages/projects/ProjectsPage.d.ts +2 -0
- package/dist/timecampus/pages/projects/ProjectsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/projects/ProjectsPage.js +95 -0
- package/dist/timecampus/pages/projects/ProjectsPage.js.map +1 -0
- package/dist/timecampus/pages/projects/TasksPage.d.ts +2 -0
- package/dist/timecampus/pages/projects/TasksPage.d.ts.map +1 -0
- package/dist/timecampus/pages/projects/TasksPage.js +73 -0
- package/dist/timecampus/pages/projects/TasksPage.js.map +1 -0
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.d.ts +2 -0
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.d.ts.map +1 -0
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js +129 -0
- package/dist/timecampus/pages/resource-planning/ResourcePlanningPage.js.map +1 -0
- package/dist/timecampus/pages/team/TeamAnalyticsPage.d.ts +2 -0
- package/dist/timecampus/pages/team/TeamAnalyticsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js +78 -0
- package/dist/timecampus/pages/team/TeamAnalyticsPage.js.map +1 -0
- package/dist/timecampus/pages/team/TeamMembersPage.d.ts +2 -0
- package/dist/timecampus/pages/team/TeamMembersPage.d.ts.map +1 -0
- package/dist/timecampus/pages/team/TeamMembersPage.js +97 -0
- package/dist/timecampus/pages/team/TeamMembersPage.js.map +1 -0
- package/dist/timecampus/pages/team/TeamPage.d.ts +2 -0
- package/dist/timecampus/pages/team/TeamPage.d.ts.map +1 -0
- package/dist/timecampus/pages/team/TeamPage.js +82 -0
- package/dist/timecampus/pages/team/TeamPage.js.map +1 -0
- package/dist/timecampus/pages/team-activity/TeamActivityPage.d.ts +2 -0
- package/dist/timecampus/pages/team-activity/TeamActivityPage.d.ts.map +1 -0
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js +107 -0
- package/dist/timecampus/pages/team-activity/TeamActivityPage.js.map +1 -0
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js +120 -0
- package/dist/timecampus/pages/team-activity/TeamActivitySettingsPage.js.map +1 -0
- package/dist/timecampus/pages/templates/TemplateApplicationPage.d.ts +2 -0
- package/dist/timecampus/pages/templates/TemplateApplicationPage.d.ts.map +1 -0
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js +84 -0
- package/dist/timecampus/pages/templates/TemplateApplicationPage.js.map +1 -0
- package/dist/timecampus/pages/templates/TemplateDetailPage.d.ts +2 -0
- package/dist/timecampus/pages/templates/TemplateDetailPage.d.ts.map +1 -0
- package/dist/timecampus/pages/templates/TemplateDetailPage.js +98 -0
- package/dist/timecampus/pages/templates/TemplateDetailPage.js.map +1 -0
- package/dist/timecampus/pages/templates/TemplatesPage.d.ts +2 -0
- package/dist/timecampus/pages/templates/TemplatesPage.d.ts.map +1 -0
- package/dist/timecampus/pages/templates/TemplatesPage.js +76 -0
- package/dist/timecampus/pages/templates/TemplatesPage.js.map +1 -0
- package/dist/timecampus/pages/time/TimeEntriesPage.d.ts +2 -0
- package/dist/timecampus/pages/time/TimeEntriesPage.d.ts.map +1 -0
- package/dist/timecampus/pages/time/TimeEntriesPage.js +117 -0
- package/dist/timecampus/pages/time/TimeEntriesPage.js.map +1 -0
- package/dist/timecampus/pages/time/TimeTrackingPage.d.ts +2 -0
- package/dist/timecampus/pages/time/TimeTrackingPage.d.ts.map +1 -0
- package/dist/timecampus/pages/time/TimeTrackingPage.js +112 -0
- package/dist/timecampus/pages/time/TimeTrackingPage.js.map +1 -0
- package/dist/timecampus/pages/time/TimerPage.d.ts +2 -0
- package/dist/timecampus/pages/time/TimerPage.d.ts.map +1 -0
- package/dist/timecampus/pages/time/TimerPage.js +80 -0
- package/dist/timecampus/pages/time/TimerPage.js.map +1 -0
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.d.ts +2 -0
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.d.ts.map +1 -0
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js +130 -0
- package/dist/timecampus/pages/time-approval/TimeApprovalPage.js.map +1 -0
- package/dist/timecampus/pages/widgets/WidgetDetailPage.d.ts +2 -0
- package/dist/timecampus/pages/widgets/WidgetDetailPage.d.ts.map +1 -0
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js +96 -0
- package/dist/timecampus/pages/widgets/WidgetDetailPage.js.map +1 -0
- package/dist/timecampus/pages/widgets/WidgetsPage.d.ts +2 -0
- package/dist/timecampus/pages/widgets/WidgetsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/widgets/WidgetsPage.js +77 -0
- package/dist/timecampus/pages/widgets/WidgetsPage.js.map +1 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.d.ts +2 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js +95 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsPage.js.map +1 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.d.ts +2 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js +129 -0
- package/dist/timecampus/pages/work-patterns/WorkPatternsSettingsPage.js.map +1 -0
- package/dist/timecampus/pages/workflows/WorkflowsPage.d.ts +2 -0
- package/dist/timecampus/pages/workflows/WorkflowsPage.d.ts.map +1 -0
- package/dist/timecampus/pages/workflows/WorkflowsPage.js +80 -0
- package/dist/timecampus/pages/workflows/WorkflowsPage.js.map +1 -0
- package/dist/timecampus/providers/TimeCampusProvider.d.ts +29 -0
- package/dist/timecampus/providers/TimeCampusProvider.d.ts.map +1 -0
- package/dist/timecampus/providers/TimeCampusProvider.js +92 -0
- package/dist/timecampus/providers/TimeCampusProvider.js.map +1 -0
- package/dist/timecampus/store/timecampusStore.d.ts +71 -0
- package/dist/timecampus/store/timecampusStore.d.ts.map +1 -0
- package/dist/timecampus/store/timecampusStore.js +33 -0
- package/dist/timecampus/store/timecampusStore.js.map +1 -0
- package/dist/timecampus/types/index.d.ts +615 -0
- package/dist/timecampus/types/index.d.ts.map +1 -0
- package/dist/timecampus/utils/helpers.d.ts +19 -0
- package/dist/timecampus/utils/helpers.d.ts.map +1 -0
- package/dist/timecampus/utils/helpers.js +73 -0
- package/dist/timecampus/utils/helpers.js.map +1 -0
- package/dist/timecampus/utils/index.d.ts +2 -0
- package/dist/timecampus/utils/index.d.ts.map +1 -0
- package/package.json +110 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeTrackingPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimeTrackingPage.tsx"],"sourcesContent":["import { Clock, Play, Pause, Square } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { StatCard } from \"../../components/StatCard\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatHours, formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useGetTimeEntryStatsQuery,\n useListTimeEntriesQuery,\n type TimeEntryFieldsFragment,\n} from \"@/generated/wspace-operations\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\n\nexport function TimeTrackingPage() {\n const { t: translate } = useI18n();\n const t = (key: string, fallback: string): string => {\n const value = translate(key);\n return value === key ? fallback : value;\n };\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: statsData, loading: statsLoading } =\n useGetTimeEntryStatsQuery();\n const { data: entriesData, loading: entriesLoading } =\n useListTimeEntriesQuery({\n variables: { limit: 10 },\n });\n\n const stats = statsData?.timeEntryStats;\n const todayEntries = entriesData?.timeEntries?.items ?? [];\n\n if (statsLoading) {\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n >\n <LoadingSkeleton variant=\"card\" count={4} />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={t(\"timecampus.timeTracking.title\", \"Time Tracking\")}\n description={t(\n \"timecampus.timeTracking.description\",\n \"Track and manage your work hours\",\n )}\n actions={\n <button\n onClick={() => (activeTimer ? stopTimer() : startTimer())}\n className={`inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-medium ${activeTimer ? \"bg-red-500 text-white hover:bg-red-600\" : \"bg-primary text-primary-foreground hover:bg-primary/90\"}`}\n >\n {activeTimer ? (\n <>\n <Square className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.stop\", \"Stop\")} (\n {formatTimerDuration(activeTimer.seconds)})\n </>\n ) : (\n <>\n <Play className=\"h-4 w-4\" />\n {t(\"timecampus.timeTracking.actions.startTimer\", \"Start Timer\")}\n </>\n )}\n </button>\n }\n >\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n title={t(\"timecampus.timeTracking.stats.today\", \"Today\")}\n value={formatHours(stats?.totalHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n trend={{\n value: 15,\n label: t(\n \"timecampus.timeTracking.stats.vsYesterday\",\n \"vs yesterday\",\n ),\n }}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.billable\", \"Billable\")}\n value={formatHours(stats?.billableHours ?? 0)}\n icon={<Clock className=\"h-5 w-5\" />}\n description={`${stats?.totalEntries ?? 0} ${t(\"timecampus.timeTracking.stats.entries\", \"entries\")}`}\n />\n <StatCard\n title={t(\n \"timecampus.timeTracking.stats.activeTimers\",\n \"Active Timers\",\n )}\n value={stats?.activeTimers ?? 0}\n icon={<Clock className=\"h-5 w-5\" />}\n description={t(\n \"timecampus.timeTracking.stats.currentlyRunning\",\n \"Currently running\",\n )}\n />\n <StatCard\n title={t(\"timecampus.timeTracking.stats.activeTimer\", \"Active Timer\")}\n value={\n activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : t(\"timecampus.timeTracking.stats.stopped\", \"Stopped\")\n }\n icon={\n activeTimer ? (\n <Pause className=\"h-5 w-5\" />\n ) : (\n <Play className=\"h-5 w-5\" />\n )\n }\n />\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 {t(\"timecampus.timeTracking.entries.title\", \"Today's Entries\")}\n </h3>\n {entriesLoading ? (\n <LoadingSkeleton variant=\"list\" count={4} />\n ) : todayEntries.length === 0 ? (\n <div className=\"flex h-48 items-center justify-center rounded-lg border border-dashed border-border\">\n <p className=\"text-sm text-muted-foreground\">\n {t(\n \"timecampus.timeTracking.entries.empty\",\n \"No time entries yet. Start a timer to begin tracking.\",\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {todayEntries.map((entry: TimeEntryFieldsFragment) => (\n <div\n key={entry.id}\n className=\"flex items-center justify-between rounded-lg border border-border p-3 transition-colors hover:bg-muted/50\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-foreground\">\n {entry.project?.name ??\n t(\n \"timecampus.timeTracking.entries.noProject\",\n \"No Project\",\n )}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {entry.description ??\n t(\n \"timecampus.timeTracking.entries.noDescription\",\n \"No description\",\n )}\n </p>\n </div>\n <div className=\"ml-4 text-right\">\n <p className=\"text-sm font-mono font-medium text-foreground\">\n {formatHours((entry.duration ?? 0) / 3600)}\n </p>\n <span className=\"inline-flex items-center 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 {entry.isRunning\n ? t(\n \"timecampus.timeTracking.entries.status.running\",\n \"running\",\n )\n : t(\n \"timecampus.timeTracking.entries.status.completed\",\n \"completed\",\n )}\n </span>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimerPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/time/TimerPage.tsx"],"names":[],"mappings":"AAYA,wBAAgB,SAAS,4CAoFxB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { formatTimerDuration as e } from "../../utils/helpers.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useTimeCampusStore as r } from "../../store/timecampusStore.js";
|
|
5
|
+
import { useListRunningTimersQuery as i } from "../../../generated/wspace-operations.js";
|
|
6
|
+
import { Play as a, RotateCcw as o, Square as s } from "lucide-react";
|
|
7
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
8
|
+
//#region src/timecampus/pages/time/TimerPage.tsx
|
|
9
|
+
function u() {
|
|
10
|
+
let { activeTimer: u, startTimer: d, stopTimer: f } = r(), { data: p, loading: m } = i(), h = p?.runningTimers ?? [];
|
|
11
|
+
return /* @__PURE__ */ c(t, {
|
|
12
|
+
title: "Timer",
|
|
13
|
+
description: "Focus timer for deep work sessions",
|
|
14
|
+
children: /* @__PURE__ */ l("div", {
|
|
15
|
+
className: "mx-auto max-w-lg",
|
|
16
|
+
children: [/* @__PURE__ */ l("div", {
|
|
17
|
+
className: "rounded-xl border border-border bg-card p-8 text-center",
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ c("p", {
|
|
20
|
+
className: "text-6xl font-mono font-bold text-foreground",
|
|
21
|
+
children: u ? e(u.seconds) : "00:00:00"
|
|
22
|
+
}),
|
|
23
|
+
u?.description && /* @__PURE__ */ c("p", {
|
|
24
|
+
className: "mt-2 text-sm text-muted-foreground",
|
|
25
|
+
children: u.description
|
|
26
|
+
}),
|
|
27
|
+
/* @__PURE__ */ l("div", {
|
|
28
|
+
className: "mt-6 flex items-center justify-center gap-3",
|
|
29
|
+
children: [u ? /* @__PURE__ */ l("button", {
|
|
30
|
+
onClick: f,
|
|
31
|
+
className: "inline-flex items-center gap-2 rounded-md bg-red-500 px-6 py-3 text-sm font-medium text-white hover:bg-red-600",
|
|
32
|
+
children: [/* @__PURE__ */ c(s, { className: "h-4 w-4" }), "Stop"]
|
|
33
|
+
}) : /* @__PURE__ */ l("button", {
|
|
34
|
+
onClick: () => d(),
|
|
35
|
+
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",
|
|
36
|
+
children: [/* @__PURE__ */ c(a, { className: "h-4 w-4" }), "Start"]
|
|
37
|
+
}), /* @__PURE__ */ l("button", {
|
|
38
|
+
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",
|
|
39
|
+
children: [/* @__PURE__ */ c(o, { className: "h-4 w-4" }), "Reset"]
|
|
40
|
+
})]
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
}), /* @__PURE__ */ l("div", {
|
|
44
|
+
className: "mt-6 rounded-xl border border-border bg-card p-6",
|
|
45
|
+
children: [/* @__PURE__ */ c("h3", {
|
|
46
|
+
className: "mb-4 text-sm font-semibold text-foreground",
|
|
47
|
+
children: "Running Timers"
|
|
48
|
+
}), m ? /* @__PURE__ */ c(n, {
|
|
49
|
+
variant: "list",
|
|
50
|
+
count: 2
|
|
51
|
+
}) : h.length === 0 ? /* @__PURE__ */ c("p", {
|
|
52
|
+
className: "text-center text-sm text-muted-foreground py-4",
|
|
53
|
+
children: "No active timers on the server"
|
|
54
|
+
}) : /* @__PURE__ */ c("div", {
|
|
55
|
+
className: "flex flex-col gap-2",
|
|
56
|
+
children: h.map((t) => /* @__PURE__ */ l("div", {
|
|
57
|
+
className: "flex items-center justify-between rounded-lg border border-border p-3",
|
|
58
|
+
children: [/* @__PURE__ */ l("div", {
|
|
59
|
+
className: "min-w-0 flex-1",
|
|
60
|
+
children: [/* @__PURE__ */ c("p", {
|
|
61
|
+
className: "text-sm font-medium text-foreground",
|
|
62
|
+
children: t.timeEntry.project?.name ?? "No Project"
|
|
63
|
+
}), /* @__PURE__ */ c("p", {
|
|
64
|
+
className: "text-xs text-muted-foreground",
|
|
65
|
+
children: t.timeEntry.description ?? "No description"
|
|
66
|
+
})]
|
|
67
|
+
}), /* @__PURE__ */ c("p", {
|
|
68
|
+
className: "ml-4 text-sm font-mono font-medium text-foreground",
|
|
69
|
+
children: e(t.elapsedSeconds)
|
|
70
|
+
})]
|
|
71
|
+
}, t.timeEntry.id))
|
|
72
|
+
})]
|
|
73
|
+
})]
|
|
74
|
+
})
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//#endregion
|
|
78
|
+
export { u as TimerPage };
|
|
79
|
+
|
|
80
|
+
//# sourceMappingURL=TimerPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimerPage.js","names":[],"sources":["../../../../src/timecampus/pages/time/TimerPage.tsx"],"sourcesContent":["import { Play, Square, RotateCcw } from \"lucide-react\";\nimport { PageLayout } from \"../../components/PageLayout\";\nimport { LoadingSkeleton } from \"../../components/LoadingSkeleton\";\nimport { formatTimerDuration } from \"../../utils/helpers\";\nimport { useTimeCampusStore } from \"../../store/timecampusStore\";\nimport {\n useListRunningTimersQuery,\n type ListRunningTimersQuery,\n} from \"@/generated/wspace-operations\";\n\ntype RunningTimerItem = ListRunningTimersQuery[\"runningTimers\"][number];\n\nexport function TimerPage() {\n const { activeTimer, startTimer, stopTimer } = useTimeCampusStore();\n\n const { data: runningData, loading: runningLoading } =\n useListRunningTimersQuery();\n\n const runningTimers = runningData?.runningTimers ?? [];\n\n return (\n <PageLayout title=\"Timer\" description=\"Focus timer for deep work sessions\">\n <div className=\"mx-auto max-w-lg\">\n <div className=\"rounded-xl border border-border bg-card p-8 text-center\">\n <p className=\"text-6xl font-mono font-bold text-foreground\">\n {activeTimer\n ? formatTimerDuration(activeTimer.seconds)\n : \"00:00:00\"}\n </p>\n {activeTimer?.description && (\n <p className=\"mt-2 text-sm text-muted-foreground\">\n {activeTimer.description}\n </p>\n )}\n <div className=\"mt-6 flex items-center justify-center gap-3\">\n {activeTimer ? (\n <button\n onClick={stopTimer}\n className=\"inline-flex items-center gap-2 rounded-md bg-red-500 px-6 py-3 text-sm font-medium text-white hover:bg-red-600\"\n >\n <Square className=\"h-4 w-4\" />\n Stop\n </button>\n ) : (\n <button\n onClick={() => startTimer()}\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 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 <RotateCcw className=\"h-4 w-4\" />\n Reset\n </button>\n </div>\n </div>\n\n {/* Server-side running timers */}\n <div className=\"mt-6 rounded-xl border border-border bg-card p-6\">\n <h3 className=\"mb-4 text-sm font-semibold text-foreground\">\n Running Timers\n </h3>\n {runningLoading ? (\n <LoadingSkeleton variant=\"list\" count={2} />\n ) : runningTimers.length === 0 ? (\n <p className=\"text-center text-sm text-muted-foreground py-4\">\n No active timers on the server\n </p>\n ) : (\n <div className=\"flex flex-col gap-2\">\n {runningTimers.map((timer: RunningTimerItem) => (\n <div\n key={timer.timeEntry.id}\n className=\"flex items-center justify-between rounded-lg border border-border p-3\"\n >\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-foreground\">\n {timer.timeEntry.project?.name ?? \"No Project\"}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n {timer.timeEntry.description ?? \"No description\"}\n </p>\n </div>\n <p className=\"ml-4 text-sm font-mono font-medium text-foreground\">\n {formatTimerDuration(timer.elapsedSeconds)}\n </p>\n </div>\n ))}\n </div>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;AAYA,SAAgB,IAAY;CAC1B,IAAM,EAAE,gBAAa,eAAY,iBAAc,GAAoB,EAE7D,EAAE,MAAM,GAAa,SAAS,MAClC,GAA2B,EAEvB,IAAgB,GAAa,iBAAiB,EAAE;AAEtD,QACE,kBAAC,GAAD;EAAY,OAAM;EAAQ,aAAY;YACpC,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV,IACG,EAAoB,EAAY,QAAQ,GACxC;MACF,CAAA;KACH,GAAa,eACZ,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY;MACX,CAAA;KAEN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACG,IACC,kBAAC,UAAD;OACE,SAAS;OACT,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA,EAAA,OAEvB;WAET,kBAAC,UAAD;OACE,eAAe,GAAY;OAC3B,WAAU;iBAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,QAErB;UAEX,kBAAC,UAAD;OAAQ,WAAU;iBAAlB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,QAE1B;SACL;;KACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA6C;KAEtD,CAAA,EACJ,IACC,kBAAC,GAAD;KAAiB,SAAQ;KAAO,OAAO;KAAK,CAAA,GAC1C,EAAc,WAAW,IAC3B,kBAAC,KAAD;KAAG,WAAU;eAAiD;KAE1D,CAAA,GAEJ,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAc,KAAK,MAClB,kBAAC,OAAD;MAEE,WAAU;gBAFZ,CAIE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,SAAS,QAAQ;QAChC,CAAA,EACJ,kBAAC,KAAD;QAAG,WAAU;kBACV,EAAM,UAAU,eAAe;QAC9B,CAAA,CACA;UACN,kBAAC,KAAD;OAAG,WAAU;iBACV,EAAoB,EAAM,eAAe;OACxC,CAAA,CACA;QAdC,EAAM,UAAU,GAcjB,CACN;KACE,CAAA,CAEJ;MACF;;EACK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TimeApprovalPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/time-approval/TimeApprovalPage.tsx"],"names":[],"mappings":"AAmBA,wBAAgB,gBAAgB,4CAwJ/B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { formatDate as t, formatHours as n, getInitials as r, getStatusColor as i } from "../../utils/helpers.js";
|
|
3
|
+
import { PageLayout as a } from "../../components/PageLayout.js";
|
|
4
|
+
import { StatCard as o } from "../../components/StatCard.js";
|
|
5
|
+
import { LoadingSkeleton as s } from "../../components/LoadingSkeleton.js";
|
|
6
|
+
import { useApproveRequestMutation as c, useGetApprovalStatsQuery as l, useListApprovalRequestsQuery as u, useRejectRequestMutation as d } from "../../../generated/wspace-operations.js";
|
|
7
|
+
import { CheckCircle as f, Clock as p, XCircle as m } from "lucide-react";
|
|
8
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
9
|
+
//#region src/timecampus/pages/time-approval/TimeApprovalPage.tsx
|
|
10
|
+
function _() {
|
|
11
|
+
let { workspaceId: _ = "" } = e(), { data: v, loading: y, error: b } = u(), { data: x, loading: S, error: C } = l(), [w, { loading: T }] = c(), [E, { loading: D }] = d(), O = v?.approvalRequests?.items ?? [], k = x?.approvalStats, A = T || D, j = async (e) => {
|
|
12
|
+
await w({ variables: { id: e } });
|
|
13
|
+
}, M = async (e) => {
|
|
14
|
+
await E({ variables: {
|
|
15
|
+
id: e,
|
|
16
|
+
reason: "Rejected by reviewer"
|
|
17
|
+
} });
|
|
18
|
+
};
|
|
19
|
+
return y && S ? /* @__PURE__ */ h(a, {
|
|
20
|
+
title: "Time Approval",
|
|
21
|
+
description: "Review and approve team timesheets",
|
|
22
|
+
children: /* @__PURE__ */ h(s, {
|
|
23
|
+
variant: "list",
|
|
24
|
+
count: 4
|
|
25
|
+
})
|
|
26
|
+
}) : b && C ? /* @__PURE__ */ h(a, {
|
|
27
|
+
title: "Time Approval",
|
|
28
|
+
description: "Review and approve team timesheets",
|
|
29
|
+
children: /* @__PURE__ */ h("div", {
|
|
30
|
+
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",
|
|
31
|
+
children: "Failed to load approval data. Please try again later."
|
|
32
|
+
})
|
|
33
|
+
}) : /* @__PURE__ */ g(a, {
|
|
34
|
+
title: "Time Approval",
|
|
35
|
+
description: "Review and approve team timesheets",
|
|
36
|
+
children: [/* @__PURE__ */ g("div", {
|
|
37
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
38
|
+
children: [
|
|
39
|
+
/* @__PURE__ */ h(o, {
|
|
40
|
+
title: "Pending Approvals",
|
|
41
|
+
value: String(k?.pendingCount ?? 0),
|
|
42
|
+
icon: /* @__PURE__ */ h(p, { className: "h-5 w-5" }),
|
|
43
|
+
iconBgColor: "bg-amber-100 text-amber-600 dark:bg-amber-900/30 dark:text-amber-400"
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ h(o, {
|
|
46
|
+
title: "Approved This Week",
|
|
47
|
+
value: String(k?.approvedCount ?? 0),
|
|
48
|
+
icon: /* @__PURE__ */ h(f, { className: "h-5 w-5" }),
|
|
49
|
+
iconBgColor: "bg-emerald-100 text-emerald-600 dark:bg-emerald-900/30 dark:text-emerald-400"
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ h(o, {
|
|
52
|
+
title: "Rejected",
|
|
53
|
+
value: String(k?.rejectedCount ?? 0),
|
|
54
|
+
icon: /* @__PURE__ */ h(m, { className: "h-5 w-5" }),
|
|
55
|
+
iconBgColor: "bg-red-100 text-red-600 dark:bg-red-900/30 dark:text-red-400"
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ h(o, {
|
|
58
|
+
title: "Avg. Review Time",
|
|
59
|
+
value: k?.averageReviewTime ? `${Math.round(k.averageReviewTime)}h` : "N/A",
|
|
60
|
+
description: "Target: 24h"
|
|
61
|
+
})
|
|
62
|
+
]
|
|
63
|
+
}), /* @__PURE__ */ h("div", {
|
|
64
|
+
className: "rounded-xl border border-border bg-card",
|
|
65
|
+
children: /* @__PURE__ */ g("div", {
|
|
66
|
+
className: "divide-y divide-border",
|
|
67
|
+
children: [O.length === 0 && !y && /* @__PURE__ */ h("div", {
|
|
68
|
+
className: "p-4 text-center text-sm text-muted-foreground",
|
|
69
|
+
children: "No approval requests found."
|
|
70
|
+
}), O.map((e) => /* @__PURE__ */ g("div", {
|
|
71
|
+
className: "flex items-center justify-between p-4 hover:bg-muted/50 transition-colors",
|
|
72
|
+
children: [/* @__PURE__ */ g("div", {
|
|
73
|
+
className: "flex items-center gap-3",
|
|
74
|
+
children: [/* @__PURE__ */ h("div", {
|
|
75
|
+
className: "flex h-9 w-9 items-center justify-center rounded-full bg-primary/10 text-sm font-medium text-primary",
|
|
76
|
+
children: r(e.userId)
|
|
77
|
+
}), /* @__PURE__ */ g("div", { children: [/* @__PURE__ */ h("p", {
|
|
78
|
+
className: "text-sm font-medium text-foreground",
|
|
79
|
+
children: e.userId
|
|
80
|
+
}), /* @__PURE__ */ g("p", {
|
|
81
|
+
className: "text-xs text-muted-foreground",
|
|
82
|
+
children: [
|
|
83
|
+
e.period,
|
|
84
|
+
" · Submitted",
|
|
85
|
+
" ",
|
|
86
|
+
t(e.submittedAt)
|
|
87
|
+
]
|
|
88
|
+
})] })]
|
|
89
|
+
}), /* @__PURE__ */ g("div", {
|
|
90
|
+
className: "flex items-center gap-4",
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ g("div", {
|
|
93
|
+
className: "text-right",
|
|
94
|
+
children: [/* @__PURE__ */ h("p", {
|
|
95
|
+
className: "text-sm font-medium text-foreground",
|
|
96
|
+
children: n(e.totalHours)
|
|
97
|
+
}), /* @__PURE__ */ g("p", {
|
|
98
|
+
className: "text-xs text-muted-foreground",
|
|
99
|
+
children: [n(e.billableHours), " billable"]
|
|
100
|
+
})]
|
|
101
|
+
}),
|
|
102
|
+
/* @__PURE__ */ h("span", {
|
|
103
|
+
className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${i(e.status)}`,
|
|
104
|
+
children: e.status
|
|
105
|
+
}),
|
|
106
|
+
e.status === "PENDING" && /* @__PURE__ */ g("div", {
|
|
107
|
+
className: "flex items-center gap-1",
|
|
108
|
+
children: [/* @__PURE__ */ h("button", {
|
|
109
|
+
onClick: () => j(e.id),
|
|
110
|
+
disabled: A,
|
|
111
|
+
className: "rounded-md p-1.5 text-emerald-600 hover:bg-emerald-50 dark:hover:bg-emerald-900/20 disabled:opacity-50",
|
|
112
|
+
children: /* @__PURE__ */ h(f, { className: "h-4 w-4" })
|
|
113
|
+
}), /* @__PURE__ */ h("button", {
|
|
114
|
+
onClick: () => M(e.id),
|
|
115
|
+
disabled: A,
|
|
116
|
+
className: "rounded-md p-1.5 text-red-600 hover:bg-red-50 dark:hover:bg-red-900/20 disabled:opacity-50",
|
|
117
|
+
children: /* @__PURE__ */ h(m, { className: "h-4 w-4" })
|
|
118
|
+
})]
|
|
119
|
+
})
|
|
120
|
+
]
|
|
121
|
+
})]
|
|
122
|
+
}, e.id))]
|
|
123
|
+
})
|
|
124
|
+
})]
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
//#endregion
|
|
128
|
+
export { _ as TimeApprovalPage };
|
|
129
|
+
|
|
130
|
+
//# sourceMappingURL=TimeApprovalPage.js.map
|
|
@@ -0,0 +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-card\">\n <div className=\"divide-y divide-border\">\n {requests.length === 0 && !requestsLoading && (\n <div className=\"p-4 text-center text-sm text-muted-foreground\">\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-muted/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-primary/10 text-sm font-medium text-primary\">\n {getInitials(request.userId)}\n </div>\n <div>\n <p className=\"text-sm font-medium text-foreground\">\n {request.userId}\n </p>\n <p className=\"text-xs text-muted-foreground\">\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-foreground\">\n {formatHours(request.totalHours)}\n </p>\n <p className=\"text-xs text-muted-foreground\">\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;eAAgD;KAEzD,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/widgets/WidgetDetailPage.tsx"],"names":[],"mappings":"AAOA,wBAAgB,gBAAgB,4CAgG/B"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useGetConfigurationQuery as r } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { ArrowLeft as i, Download as a, LayoutGrid as o, Star as s } from "lucide-react";
|
|
6
|
+
import { useParams as c } from "react-router-dom";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
//#region src/timecampus/pages/widgets/WidgetDetailPage.tsx
|
|
9
|
+
function d() {
|
|
10
|
+
let { id: d } = c(), { workspaceId: f = "" } = e(), { data: p, loading: m, error: h } = r({
|
|
11
|
+
variables: { id: d ?? "" },
|
|
12
|
+
skip: !d
|
|
13
|
+
}), g = p?.configuration, _ = g?.value ?? {}, v = _.name ?? g?.key?.replace("widget.", "") ?? "Widget", y = g?.description ?? _.description ?? "A configurable dashboard widget for time tracking.", b = _.rating ?? 0, x = _.downloads ?? 0;
|
|
14
|
+
return m ? /* @__PURE__ */ l(t, {
|
|
15
|
+
title: "Widget Details",
|
|
16
|
+
description: "Loading...",
|
|
17
|
+
children: /* @__PURE__ */ l(n, { variant: "detail" })
|
|
18
|
+
}) : h || !g ? /* @__PURE__ */ l(t, {
|
|
19
|
+
title: "Widget Details",
|
|
20
|
+
description: `Widget ID: ${d}`,
|
|
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-foreground hover:bg-muted/50",
|
|
23
|
+
children: [/* @__PURE__ */ l(i, { className: "h-4 w-4" }), "Back to Widgets"]
|
|
24
|
+
}),
|
|
25
|
+
children: /* @__PURE__ */ l("div", {
|
|
26
|
+
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",
|
|
27
|
+
children: h ? "Failed to load widget details. Please try again later." : "Widget configuration not found."
|
|
28
|
+
})
|
|
29
|
+
}) : /* @__PURE__ */ l(t, {
|
|
30
|
+
title: "Widget Details",
|
|
31
|
+
description: `Widget ID: ${d}`,
|
|
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-foreground hover:bg-muted/50",
|
|
34
|
+
children: [/* @__PURE__ */ l(i, { className: "h-4 w-4" }), "Back to Widgets"]
|
|
35
|
+
}),
|
|
36
|
+
children: /* @__PURE__ */ l("div", {
|
|
37
|
+
className: "mx-auto max-w-2xl",
|
|
38
|
+
children: /* @__PURE__ */ u("div", {
|
|
39
|
+
className: "rounded-xl border border-border bg-card p-6",
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ u("div", {
|
|
42
|
+
className: "flex items-start gap-4",
|
|
43
|
+
children: [/* @__PURE__ */ l("div", {
|
|
44
|
+
className: "flex h-16 w-16 items-center justify-center rounded-xl bg-primary/10",
|
|
45
|
+
children: /* @__PURE__ */ l(o, { className: "h-8 w-8 text-primary" })
|
|
46
|
+
}), /* @__PURE__ */ u("div", {
|
|
47
|
+
className: "flex-1",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ l("h2", {
|
|
50
|
+
className: "text-lg font-semibold text-foreground",
|
|
51
|
+
children: v
|
|
52
|
+
}),
|
|
53
|
+
/* @__PURE__ */ l("p", {
|
|
54
|
+
className: "text-sm text-muted-foreground",
|
|
55
|
+
children: y
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ u("div", {
|
|
58
|
+
className: "mt-2 flex items-center gap-3 text-sm text-muted-foreground",
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ u("div", {
|
|
61
|
+
className: "flex items-center gap-1",
|
|
62
|
+
children: [/* @__PURE__ */ l(s, { className: "h-4 w-4 fill-amber-400 text-amber-400" }), /* @__PURE__ */ l("span", { children: b })]
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ l("span", { children: "·" }),
|
|
65
|
+
/* @__PURE__ */ u("div", {
|
|
66
|
+
className: "flex items-center gap-1",
|
|
67
|
+
children: [/* @__PURE__ */ l(a, { className: "h-4 w-4" }), /* @__PURE__ */ u("span", { children: [x.toLocaleString(), " installs"] })]
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
})]
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ l("div", {
|
|
75
|
+
className: "mt-6 flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
76
|
+
children: /* @__PURE__ */ l("p", {
|
|
77
|
+
className: "text-sm text-muted-foreground",
|
|
78
|
+
children: "Widget preview will render here"
|
|
79
|
+
})
|
|
80
|
+
}),
|
|
81
|
+
/* @__PURE__ */ l("div", {
|
|
82
|
+
className: "mt-4 flex justify-end",
|
|
83
|
+
children: /* @__PURE__ */ l("button", {
|
|
84
|
+
className: "rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/90",
|
|
85
|
+
children: "Install Widget"
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
]
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
//#endregion
|
|
94
|
+
export { d as WidgetDetailPage };
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=WidgetDetailPage.js.map
|
|
@@ -0,0 +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-foreground hover:bg-muted/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 px-3 py-2 text-sm font-medium text-foreground hover:bg-muted/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 bg-card 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-primary/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-foreground\">{name}</h2>\n <p className=\"text-sm text-muted-foreground\">{description}</p>\n <div className=\"mt-2 flex items-center gap-3 text-sm text-muted-foreground\">\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\">\n <p className=\"text-sm text-muted-foreground\">\n Widget preview will render here\n </p>\n </div>\n <div className=\"mt-4 flex justify-end\">\n <button className=\"rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground hover:bg-primary/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;mBAAyC;SAAU,CAAA;QACjE,kBAAC,KAAD;SAAG,WAAU;mBAAiC;SAAgB,CAAA;QAC9D,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;iBAAgC;OAEzC,CAAA;MACA,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,UAAD;OAAQ,WAAU;iBAAkG;OAE3G,CAAA;MACL,CAAA;KACF;;GACF,CAAA;EACK,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WidgetsPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/widgets/WidgetsPage.tsx"],"names":[],"mappings":"AASA,wBAAgB,WAAW,4CAyG1B"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { LoadingSkeleton as n } from "../../components/LoadingSkeleton.js";
|
|
4
|
+
import { useListConfigurationsQuery as r } from "../../../generated/wspace-operations.js";
|
|
5
|
+
import { LayoutGrid as i, Plus as a, Star as o } from "lucide-react";
|
|
6
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
7
|
+
//#region src/timecampus/pages/widgets/WidgetsPage.tsx
|
|
8
|
+
function l() {
|
|
9
|
+
let { workspaceId: l = "" } = e(), { data: u, loading: d, error: f } = r({ variables: { scope: "WORKSPACE" } }), p = (u?.configurations ?? []).filter((e) => e.key.startsWith("widget."));
|
|
10
|
+
return d ? /* @__PURE__ */ s(t, {
|
|
11
|
+
title: "Widgets",
|
|
12
|
+
description: "Customize your dashboard with widgets",
|
|
13
|
+
children: /* @__PURE__ */ s(n, {
|
|
14
|
+
variant: "card",
|
|
15
|
+
count: 6
|
|
16
|
+
})
|
|
17
|
+
}) : f ? /* @__PURE__ */ s(t, {
|
|
18
|
+
title: "Widgets",
|
|
19
|
+
description: "Customize your dashboard with widgets",
|
|
20
|
+
children: /* @__PURE__ */ s("div", {
|
|
21
|
+
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",
|
|
22
|
+
children: "Failed to load widget configurations. Please try again later."
|
|
23
|
+
})
|
|
24
|
+
}) : /* @__PURE__ */ s(t, {
|
|
25
|
+
title: "Widgets",
|
|
26
|
+
description: "Customize your dashboard with widgets",
|
|
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-foreground hover:bg-primary/90",
|
|
29
|
+
children: [/* @__PURE__ */ s(a, { className: "h-4 w-4" }), "Create Widget"]
|
|
30
|
+
}),
|
|
31
|
+
children: /* @__PURE__ */ s("div", {
|
|
32
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
33
|
+
children: p.length === 0 ? /* @__PURE__ */ s("div", {
|
|
34
|
+
className: "col-span-full p-8 text-center text-sm text-muted-foreground",
|
|
35
|
+
children: "No widgets configured yet. Widgets are stored as workspace configurations with the \"widget.\" key prefix."
|
|
36
|
+
}) : p.map((e) => {
|
|
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
|
+
return /* @__PURE__ */ c("div", {
|
|
39
|
+
className: "rounded-xl border border-border bg-card p-5 transition-colors hover:bg-muted/50 cursor-pointer",
|
|
40
|
+
children: [/* @__PURE__ */ c("div", {
|
|
41
|
+
className: "flex items-start justify-between",
|
|
42
|
+
children: [/* @__PURE__ */ c("div", {
|
|
43
|
+
className: "flex items-center gap-3",
|
|
44
|
+
children: [/* @__PURE__ */ s("div", {
|
|
45
|
+
className: "flex h-10 w-10 items-center justify-center rounded-lg bg-primary/10",
|
|
46
|
+
children: /* @__PURE__ */ s(i, { className: "h-5 w-5 text-primary" })
|
|
47
|
+
}), /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
|
|
48
|
+
className: "text-sm font-semibold text-foreground",
|
|
49
|
+
children: n
|
|
50
|
+
}), /* @__PURE__ */ c("p", {
|
|
51
|
+
className: "text-xs text-muted-foreground",
|
|
52
|
+
children: [
|
|
53
|
+
r,
|
|
54
|
+
" · ",
|
|
55
|
+
a
|
|
56
|
+
]
|
|
57
|
+
})] })]
|
|
58
|
+
}), l && /* @__PURE__ */ s("span", {
|
|
59
|
+
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",
|
|
60
|
+
children: "Installed"
|
|
61
|
+
})]
|
|
62
|
+
}), /* @__PURE__ */ c("div", {
|
|
63
|
+
className: "mt-3 flex items-center justify-between text-xs text-muted-foreground",
|
|
64
|
+
children: [/* @__PURE__ */ c("div", {
|
|
65
|
+
className: "flex items-center gap-1",
|
|
66
|
+
children: [/* @__PURE__ */ s(o, { className: "h-3 w-3 fill-amber-400 text-amber-400" }), /* @__PURE__ */ s("span", { children: u })]
|
|
67
|
+
}), /* @__PURE__ */ c("span", { children: [d, " downloads"] })]
|
|
68
|
+
})]
|
|
69
|
+
}, e.id);
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { l as WidgetsPage };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=WidgetsPage.js.map
|
|
@@ -0,0 +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-foreground hover:bg-primary/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-muted-foreground\">\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 bg-card p-5 transition-colors hover:bg-muted/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-primary/10\">\n <LayoutGrid className=\"h-5 w-5 text-primary\" />\n </div>\n <div>\n <p className=\"text-sm font-semibold text-foreground\">\n {name}\n </p>\n <p className=\"text-xs text-muted-foreground\">\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-muted-foreground\">\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;cAA8D;IAGvE,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkPatternsPage.d.ts","sourceRoot":"","sources":["../../../../src/timecampus/pages/work-patterns/WorkPatternsPage.tsx"],"names":[],"mappings":"AAUA,wBAAgB,gBAAgB,4CAoI/B"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { useTimeCampus as e } from "../../providers/TimeCampusProvider.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { StatCard as n } from "../../components/StatCard.js";
|
|
4
|
+
import { LoadingSkeleton as r } from "../../components/LoadingSkeleton.js";
|
|
5
|
+
import { useGetWorkPatternSummaryQuery as i, useListWorkPatternsQuery as a } from "../../../generated/wspace-operations.js";
|
|
6
|
+
import { Brain as o, Clock as s, TrendingUp as c, Zap as l } from "lucide-react";
|
|
7
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
|
+
//#region src/timecampus/pages/work-patterns/WorkPatternsPage.tsx
|
|
9
|
+
function f() {
|
|
10
|
+
let { workspaceId: f = "" } = e(), { data: p, loading: m, error: h } = a({
|
|
11
|
+
variables: { limit: 30 },
|
|
12
|
+
skip: !f
|
|
13
|
+
}), { data: g, loading: _, error: v } = i({ skip: !f }), y = m || _, b = h || v, x = g?.workPatternSummary, S = (p?.workPatterns ?? [])[0], C = x?.averageProductivity == null ? "--" : `${Math.round(x.averageProductivity)}%`, w = S?.focusHours == null ? "--" : `${S.focusHours.toFixed(1)}h`, T = S ? (S.focusHours + S.meetingHours + S.breakHours).toFixed(0) : "8", E = S?.deepWorkSessions == null ? "--" : String(S.deepWorkSessions), D = x?.mostProductiveDay ?? "--";
|
|
14
|
+
return y ? /* @__PURE__ */ u(t, {
|
|
15
|
+
title: "Work Patterns",
|
|
16
|
+
description: "Analyze your work habits and productivity patterns",
|
|
17
|
+
children: /* @__PURE__ */ u(r, {
|
|
18
|
+
variant: "card",
|
|
19
|
+
count: 4
|
|
20
|
+
})
|
|
21
|
+
}) : b ? /* @__PURE__ */ u(t, {
|
|
22
|
+
title: "Work Patterns",
|
|
23
|
+
description: "Analyze your work habits and productivity patterns",
|
|
24
|
+
children: /* @__PURE__ */ u("div", {
|
|
25
|
+
className: "rounded-xl border border-destructive/50 bg-destructive/10 p-4 text-sm text-destructive",
|
|
26
|
+
children: "Failed to load work patterns. Please try again later."
|
|
27
|
+
})
|
|
28
|
+
}) : /* @__PURE__ */ d(t, {
|
|
29
|
+
title: "Work Patterns",
|
|
30
|
+
description: "Analyze your work habits and productivity patterns",
|
|
31
|
+
children: [/* @__PURE__ */ d("div", {
|
|
32
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
33
|
+
children: [
|
|
34
|
+
/* @__PURE__ */ u(n, {
|
|
35
|
+
title: "Productivity Score",
|
|
36
|
+
value: C,
|
|
37
|
+
icon: /* @__PURE__ */ u(c, { className: "h-5 w-5" }),
|
|
38
|
+
trend: x?.averageProductivity == null ? void 0 : {
|
|
39
|
+
value: 5,
|
|
40
|
+
label: "vs last week"
|
|
41
|
+
}
|
|
42
|
+
}),
|
|
43
|
+
/* @__PURE__ */ u(n, {
|
|
44
|
+
title: "Focus Hours",
|
|
45
|
+
value: w,
|
|
46
|
+
icon: /* @__PURE__ */ u(o, { className: "h-5 w-5" }),
|
|
47
|
+
description: `Out of ${T}h total`
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ u(n, {
|
|
50
|
+
title: "Peak Day",
|
|
51
|
+
value: D,
|
|
52
|
+
icon: /* @__PURE__ */ u(l, { className: "h-5 w-5" }),
|
|
53
|
+
description: "Most productive day"
|
|
54
|
+
}),
|
|
55
|
+
/* @__PURE__ */ u(n, {
|
|
56
|
+
title: "Deep Work",
|
|
57
|
+
value: `${E} sessions`,
|
|
58
|
+
icon: /* @__PURE__ */ u(s, { className: "h-5 w-5" }),
|
|
59
|
+
description: "90+ min uninterrupted"
|
|
60
|
+
})
|
|
61
|
+
]
|
|
62
|
+
}), /* @__PURE__ */ d("div", {
|
|
63
|
+
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
64
|
+
children: [/* @__PURE__ */ d("div", {
|
|
65
|
+
className: "rounded-xl border border-border bg-card p-6",
|
|
66
|
+
children: [/* @__PURE__ */ u("h3", {
|
|
67
|
+
className: "mb-4 text-sm font-semibold text-foreground",
|
|
68
|
+
children: "Daily Work Pattern"
|
|
69
|
+
}), /* @__PURE__ */ u("div", {
|
|
70
|
+
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
71
|
+
children: /* @__PURE__ */ u("p", {
|
|
72
|
+
className: "text-sm text-muted-foreground",
|
|
73
|
+
children: "Heatmap will render here"
|
|
74
|
+
})
|
|
75
|
+
})]
|
|
76
|
+
}), /* @__PURE__ */ d("div", {
|
|
77
|
+
className: "rounded-xl border border-border bg-card p-6",
|
|
78
|
+
children: [/* @__PURE__ */ u("h3", {
|
|
79
|
+
className: "mb-4 text-sm font-semibold text-foreground",
|
|
80
|
+
children: "Energy Levels"
|
|
81
|
+
}), /* @__PURE__ */ u("div", {
|
|
82
|
+
className: "flex h-48 items-center justify-center rounded-lg border border-dashed border-border",
|
|
83
|
+
children: /* @__PURE__ */ u("p", {
|
|
84
|
+
className: "text-sm text-muted-foreground",
|
|
85
|
+
children: "Energy chart will render here"
|
|
86
|
+
})
|
|
87
|
+
})]
|
|
88
|
+
})]
|
|
89
|
+
})]
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { f as WorkPatternsPage };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=WorkPatternsPage.js.map
|