@rebasepro/app 0.17.3 → 0.18.0

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.
Files changed (185) hide show
  1. package/README.md +4 -1
  2. package/dist/components/index.d.ts +0 -3
  3. package/dist/contexts/AuthControllerContext.d.ts +2 -1
  4. package/dist/contexts/CustomizationControllerContext.d.ts +2 -1
  5. package/dist/contexts/DialogsProvider.d.ts +2 -1
  6. package/dist/contexts/RebaseDataContext.d.ts +10 -1
  7. package/dist/contexts/StorageSourceContext.d.ts +11 -1
  8. package/dist/core/RebaseProps.d.ts +2 -12
  9. package/dist/debug/index.d.ts +19 -0
  10. package/dist/debug.js +3631 -0
  11. package/dist/hooks/data/delete.d.ts +16 -7
  12. package/dist/hooks/data/save.d.ts +18 -4
  13. package/dist/hooks/index.d.ts +1 -0
  14. package/dist/hooks/useAdminModeController.d.ts +5 -4
  15. package/dist/hooks/useNavigationGroupLabel.d.ts +17 -0
  16. package/dist/hooks/useStudioBridge.d.ts +33 -0
  17. package/dist/index.es.js +2599 -6980
  18. package/dist/index.es.js.map +1 -1
  19. package/dist/vitePlugin.d.ts +22 -0
  20. package/dist/vitePlugin.js +40 -1
  21. package/package.json +42 -31
  22. package/src/auth/api.ts +0 -134
  23. package/src/auth/index.ts +0 -26
  24. package/src/auth/types.ts +0 -115
  25. package/src/auth/useRebaseAuthController.ts +0 -345
  26. package/src/collections/collection_view_config.ts +0 -76
  27. package/src/collections/entity-display-cache.ts +0 -195
  28. package/src/collections/entity-display.ts +0 -77
  29. package/src/collections/entity_image_preview.ts +0 -61
  30. package/src/collections/filter-operator-resolution.ts +0 -119
  31. package/src/collections/form-layout.ts +0 -394
  32. package/src/collections/index.ts +0 -13
  33. package/src/collections/navigation_from_path.ts +0 -123
  34. package/src/collections/navigation_utils.ts +0 -171
  35. package/src/collections/parent_references_from_path.ts +0 -59
  36. package/src/collections/property-path.ts +0 -30
  37. package/src/collections/property_presentation.ts +0 -264
  38. package/src/collections/summary-property.ts +0 -114
  39. package/src/collections/title-property.ts +0 -312
  40. package/src/components/AIIcon.tsx +0 -47
  41. package/src/components/AuthSimulationMenu.tsx +0 -0
  42. package/src/components/ConfirmationDialog.tsx +0 -48
  43. package/src/components/Debug/UIReferenceView.tsx +0 -1053
  44. package/src/components/Debug/UIStyleGuide.tsx +0 -159
  45. package/src/components/Debug/collection-views/CardViewDemo.tsx +0 -87
  46. package/src/components/Debug/collection-views/CollectionTableDemo.tsx +0 -107
  47. package/src/components/Debug/collection-views/KanbanBoardDemo.tsx +0 -89
  48. package/src/components/Debug/collection-views/index.ts +0 -3
  49. package/src/components/Debug/collection-views/sample_data.ts +0 -44
  50. package/src/components/Debug/crm-dashboard/CalendarWidget.tsx +0 -387
  51. package/src/components/Debug/crm-dashboard/CrmDashboardDemo.tsx +0 -1100
  52. package/src/components/Debug/crm-dashboard/DashboardMetrics.tsx +0 -131
  53. package/src/components/Debug/crm-dashboard/PipelineOverview.tsx +0 -288
  54. package/src/components/Debug/crm-dashboard/RecentActivity.tsx +0 -213
  55. package/src/components/Debug/crm-dashboard/TaskFilters.tsx +0 -182
  56. package/src/components/Debug/crm-dashboard/TaskTable.tsx +0 -425
  57. package/src/components/Debug/crm-dashboard/TasksView.tsx +0 -234
  58. package/src/components/ErrorTooltip.tsx +0 -12
  59. package/src/components/ErrorView.tsx +0 -94
  60. package/src/components/LanguageToggle.tsx +0 -59
  61. package/src/components/LoginView/LoginView.tsx +0 -1235
  62. package/src/components/LoginView/index.ts +0 -2
  63. package/src/components/LoginView/oauth-redirect-flow.ts +0 -184
  64. package/src/components/NotFoundPage.tsx +0 -27
  65. package/src/components/RebaseAuth.tsx +0 -27
  66. package/src/components/RebaseLogo.tsx +0 -88
  67. package/src/components/SchemaDriftBanner.tsx +0 -102
  68. package/src/components/UnsavedChangesDialog.tsx +0 -46
  69. package/src/components/UserDisplay.tsx +0 -54
  70. package/src/components/UserSelectPopover.tsx +0 -399
  71. package/src/components/UserSettingsView.tsx +0 -318
  72. package/src/components/common/index.ts +0 -6
  73. package/src/components/common/table_height.tsx +0 -21
  74. package/src/components/common/types.tsx +0 -66
  75. package/src/components/common/useColumnsIds.tsx +0 -261
  76. package/src/components/common/useDataTableController.tsx +0 -571
  77. package/src/components/common/useDebouncedData.ts +0 -49
  78. package/src/components/common/useScrollRestoration.tsx +0 -68
  79. package/src/components/index.tsx +0 -26
  80. package/src/contexts/AdminModeController.tsx +0 -11
  81. package/src/contexts/AnalyticsContext.tsx +0 -4
  82. package/src/contexts/AuthControllerContext.tsx +0 -4
  83. package/src/contexts/CollectionResolverContext.tsx +0 -24
  84. package/src/contexts/CollectionScopeContext.tsx +0 -68
  85. package/src/contexts/ComponentOverrideContext.tsx +0 -81
  86. package/src/contexts/CustomizationControllerContext.tsx +0 -4
  87. package/src/contexts/DataDriverContext.tsx +0 -4
  88. package/src/contexts/DataSourcesContext.tsx +0 -36
  89. package/src/contexts/DatabaseAdminContext.tsx +0 -4
  90. package/src/contexts/DialogsProvider.tsx +0 -56
  91. package/src/contexts/EffectiveRoleController.tsx +0 -12
  92. package/src/contexts/ModeController.tsx +0 -11
  93. package/src/contexts/RebaseClientInstanceContext.tsx +0 -7
  94. package/src/contexts/RebaseDataContext.tsx +0 -4
  95. package/src/contexts/SnackbarProvider.tsx +0 -15
  96. package/src/contexts/StorageSourceContext.tsx +0 -4
  97. package/src/contexts/StorageSourcesContext.tsx +0 -30
  98. package/src/contexts/UserConfigurationPersistenceContext.tsx +0 -4
  99. package/src/contexts/index.ts +0 -18
  100. package/src/core/PluginLifecycleManager.tsx +0 -96
  101. package/src/core/PluginProviderStack.tsx +0 -40
  102. package/src/core/Rebase.tsx +0 -488
  103. package/src/core/RebaseProps.tsx +0 -333
  104. package/src/core/RebaseRouter.tsx +0 -18
  105. package/src/core/RebaseRoutes.tsx +0 -24
  106. package/src/core/index.tsx +0 -5
  107. package/src/hooks/ApiConfigContext.tsx +0 -83
  108. package/src/hooks/data/collectionQuery.ts +0 -55
  109. package/src/hooks/data/delete.ts +0 -56
  110. package/src/hooks/data/save.ts +0 -78
  111. package/src/hooks/data/useCollection.tsx +0 -183
  112. package/src/hooks/data/useData.tsx +0 -18
  113. package/src/hooks/data/useDataOrder.ts +0 -26
  114. package/src/hooks/data/useFetch.tsx +0 -156
  115. package/src/hooks/data/useRelationSelector.tsx +0 -280
  116. package/src/hooks/index.tsx +0 -45
  117. package/src/hooks/useAdminModeController.tsx +0 -23
  118. package/src/hooks/useAnalyticsController.tsx +0 -8
  119. package/src/hooks/useAuthController.tsx +0 -15
  120. package/src/hooks/useAuthSubscription.ts +0 -130
  121. package/src/hooks/useBackendStorageSource.ts +0 -295
  122. package/src/hooks/useBridgeRegistration.tsx +0 -32
  123. package/src/hooks/useBrowserTitleAndIcon.tsx +0 -23
  124. package/src/hooks/useBuildAdminModeController.tsx +0 -29
  125. package/src/hooks/useBuildEffectiveRoleController.tsx +0 -30
  126. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +0 -83
  127. package/src/hooks/useBuildModeController.tsx +0 -73
  128. package/src/hooks/useClipboard.tsx +0 -158
  129. package/src/hooks/useCollapsedGroups.ts +0 -116
  130. package/src/hooks/useComponentOverride.tsx +0 -59
  131. package/src/hooks/useCustomizationController.tsx +0 -14
  132. package/src/hooks/useDialogsController.tsx +0 -15
  133. package/src/hooks/useEffectiveRoleController.tsx +0 -10
  134. package/src/hooks/useLargeLayout.tsx +0 -65
  135. package/src/hooks/useModeController.tsx +0 -23
  136. package/src/hooks/useNavigationBlocker.tsx +0 -108
  137. package/src/hooks/usePermissions.ts +0 -45
  138. package/src/hooks/useRebaseClient.tsx +0 -10
  139. package/src/hooks/useRebaseContext.tsx +0 -84
  140. package/src/hooks/useRebaseRegistry.tsx +0 -91
  141. package/src/hooks/useResolvedComponent.tsx +0 -195
  142. package/src/hooks/useSlot.tsx +0 -64
  143. package/src/hooks/useSnackbarController.tsx +0 -80
  144. package/src/hooks/useStorageSource.tsx +0 -11
  145. package/src/hooks/useStudioBridge.tsx +0 -258
  146. package/src/hooks/useTranslation.ts +0 -38
  147. package/src/hooks/useUnsavedChangesDialog.tsx +0 -67
  148. package/src/hooks/useUserConfigurationPersistence.tsx +0 -11
  149. package/src/i18n/RebaseI18nProvider.tsx +0 -159
  150. package/src/index.ts +0 -32
  151. package/src/internal/common.tsx +0 -28
  152. package/src/internal/useRestoreScroll.tsx +0 -69
  153. package/src/locales/de.ts +0 -941
  154. package/src/locales/en.ts +0 -1021
  155. package/src/locales/es.ts +0 -962
  156. package/src/locales/fr.ts +0 -941
  157. package/src/locales/hi.ts +0 -941
  158. package/src/locales/it.ts +0 -941
  159. package/src/locales/pt.ts +0 -949
  160. package/src/util/constants.ts +0 -7
  161. package/src/util/createFormexStub.tsx +0 -66
  162. package/src/util/entity_cache.ts +0 -242
  163. package/src/util/enums.ts +0 -34
  164. package/src/util/icon_list.ts +0 -22
  165. package/src/util/icons.tsx +0 -129
  166. package/src/util/index.ts +0 -13
  167. package/src/util/local_storage.ts +0 -66
  168. package/src/util/previews.ts +0 -127
  169. package/src/util/useStorageUploadController.tsx +0 -354
  170. package/src/vitePlugin.ts +0 -215
  171. /package/dist/{components/Debug → debug}/UIReferenceView.d.ts +0 -0
  172. /package/dist/{components/Debug → debug}/UIStyleGuide.d.ts +0 -0
  173. /package/dist/{components/Debug → debug}/collection-views/CardViewDemo.d.ts +0 -0
  174. /package/dist/{components/Debug → debug}/collection-views/CollectionTableDemo.d.ts +0 -0
  175. /package/dist/{components/Debug → debug}/collection-views/KanbanBoardDemo.d.ts +0 -0
  176. /package/dist/{components/Debug → debug}/collection-views/index.d.ts +0 -0
  177. /package/dist/{components/Debug → debug}/collection-views/sample_data.d.ts +0 -0
  178. /package/dist/{components/Debug → debug}/crm-dashboard/CalendarWidget.d.ts +0 -0
  179. /package/dist/{components/Debug → debug}/crm-dashboard/CrmDashboardDemo.d.ts +0 -0
  180. /package/dist/{components/Debug → debug}/crm-dashboard/DashboardMetrics.d.ts +0 -0
  181. /package/dist/{components/Debug → debug}/crm-dashboard/PipelineOverview.d.ts +0 -0
  182. /package/dist/{components/Debug → debug}/crm-dashboard/RecentActivity.d.ts +0 -0
  183. /package/dist/{components/Debug → debug}/crm-dashboard/TaskFilters.d.ts +0 -0
  184. /package/dist/{components/Debug → debug}/crm-dashboard/TaskTable.d.ts +0 -0
  185. /package/dist/{components/Debug → debug}/crm-dashboard/TasksView.d.ts +0 -0
@@ -1,387 +0,0 @@
1
- import React, { useState, useMemo, useCallback } from "react";
2
- import {
3
- Typography,
4
- cls,
5
- Chip,
6
- Skeleton,
7
- IconButton,
8
- Separator,
9
- Button,
10
- ChevronLeftIcon,
11
- ChevronRightIcon
12
- } from "@rebasepro/ui";
13
-
14
- /* ── Types ─────────────────────────────────────────────── */
15
-
16
- interface TaskEntity {
17
- id: string;
18
- values: {
19
- title: string;
20
- status: string;
21
- dueDate: string | null;
22
- stageId: string | null;
23
- priority?: string | null;
24
- clientId: string | null;
25
- client?: { name?: string } | null;
26
- };
27
- }
28
-
29
- export interface CalendarWidgetProps {
30
- loading: boolean;
31
- tasks: TaskEntity[];
32
- onOpenTask: (taskId: string) => void;
33
- }
34
-
35
- /* ── Date helpers ──────────────────────────────────────── */
36
-
37
- function startOfMonth(date: Date): Date {
38
- return new Date(date.getFullYear(), date.getMonth(), 1);
39
- }
40
-
41
- function endOfMonth(date: Date): Date {
42
- return new Date(date.getFullYear(), date.getMonth() + 1, 0);
43
- }
44
-
45
- function isSameDay(a: Date, b: Date): boolean {
46
- return (
47
- a.getFullYear() === b.getFullYear() &&
48
- a.getMonth() === b.getMonth() &&
49
- a.getDate() === b.getDate()
50
- );
51
- }
52
-
53
- function toDateKey(date: Date): string {
54
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
55
- }
56
-
57
- function isBeforeToday(date: Date): boolean {
58
- const today = new Date();
59
- today.setHours(0, 0, 0, 0);
60
- const d = new Date(date);
61
- d.setHours(0, 0, 0, 0);
62
- return d < today;
63
- }
64
-
65
- /* ── Stage label map ───────────────────────────────────── */
66
-
67
- const stageLabels: Record<string, string> = {
68
- incoming: "Incoming",
69
- email_sent: "Intro Email",
70
- discovery_call: "Discovery",
71
- agreements: "Agreements",
72
- onboarding: "Onboarding",
73
- active: "Active",
74
- delivered: "Delivered",
75
- completed: "Done"
76
- };
77
-
78
- /* ── Calendar grid builder ─────────────────────────────── */
79
-
80
- interface CalendarDay {
81
- date: Date;
82
- isCurrentMonth: boolean;
83
- isToday: boolean;
84
- dateKey: string;
85
- }
86
-
87
- function buildCalendarGrid(viewDate: Date): CalendarDay[] {
88
- const today = new Date();
89
- const first = startOfMonth(viewDate);
90
- const last = endOfMonth(viewDate);
91
-
92
- // Monday = 0 ... Sunday = 6
93
- let startDay = first.getDay() - 1;
94
- if (startDay < 0) startDay = 6;
95
-
96
- const days: CalendarDay[] = [];
97
-
98
- // Fill leading days from previous month
99
- for (let i = startDay - 1; i >= 0; i--) {
100
- const d = new Date(first);
101
- d.setDate(d.getDate() - (i + 1));
102
- days.push({
103
- date: d,
104
- isCurrentMonth: false,
105
- isToday: isSameDay(d, today),
106
- dateKey: toDateKey(d)
107
- });
108
- }
109
-
110
- // Current month days
111
- for (let d = 1; d <= last.getDate(); d++) {
112
- const date = new Date(viewDate.getFullYear(), viewDate.getMonth(), d);
113
- days.push({
114
- date,
115
- isCurrentMonth: true,
116
- isToday: isSameDay(date, today),
117
- dateKey: toDateKey(date)
118
- });
119
- }
120
-
121
- // Fill trailing days to complete the last week
122
- while (days.length % 7 !== 0) {
123
- const d = new Date(last);
124
- d.setDate(d.getDate() + (days.length - (startDay + last.getDate())) + 1);
125
- days.push({
126
- date: d,
127
- isCurrentMonth: false,
128
- isToday: isSameDay(d, today),
129
- dateKey: toDateKey(d)
130
- });
131
- }
132
-
133
- return days;
134
- }
135
-
136
- /* ── Component ─────────────────────────────────────────── */
137
-
138
- const DAY_HEADERS = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"];
139
-
140
- const MONTH_NAMES = [
141
- "January", "February", "March", "April", "May", "June",
142
- "July", "August", "September", "October", "November", "December"
143
- ];
144
-
145
- export function CalendarWidget({ loading, tasks, onOpenTask }: CalendarWidgetProps) {
146
- const [viewDate, setViewDate] = useState(() => new Date());
147
- const [selectedDay, setSelectedDay] = useState<string | null>(null);
148
-
149
- /* ── Group tasks by date key ── */
150
- const tasksByDate = useMemo(() => {
151
- const map = new Map<string, TaskEntity[]>();
152
- for (const task of tasks) {
153
- if (!task.values?.dueDate) continue;
154
- const d = new Date(task.values.dueDate);
155
- const key = toDateKey(d);
156
- if (!map.has(key)) map.set(key, []);
157
- map.get(key)!.push(task);
158
- }
159
- return map;
160
- }, [tasks]);
161
-
162
- /* ── Calendar grid ── */
163
- const calendarDays = useMemo(() => buildCalendarGrid(viewDate), [viewDate]);
164
-
165
- /* ── Month navigation ── */
166
- const goToPrevMonth = useCallback(() => {
167
- setViewDate(prev => new Date(prev.getFullYear(), prev.getMonth() - 1, 1));
168
- setSelectedDay(null);
169
- }, []);
170
-
171
- const goToNextMonth = useCallback(() => {
172
- setViewDate(prev => new Date(prev.getFullYear(), prev.getMonth() + 1, 1));
173
- setSelectedDay(null);
174
- }, []);
175
-
176
- const goToToday = useCallback(() => {
177
- const today = new Date();
178
- setViewDate(new Date(today.getFullYear(), today.getMonth(), 1));
179
- setSelectedDay(toDateKey(today));
180
- }, []);
181
-
182
- /* ── Selected day tasks ── */
183
- const selectedDayTasks = useMemo(() => {
184
- if (!selectedDay) return [];
185
- return tasksByDate.get(selectedDay) || [];
186
- }, [selectedDay, tasksByDate]);
187
-
188
- return (
189
- <div>
190
- {/* Header */}
191
- <div className="flex items-center justify-between mb-3">
192
- <Typography variant="subtitle1">Calendar</Typography>
193
- <Button
194
- variant="text"
195
- size="small"
196
- color="primary"
197
- className="p-0 h-auto min-w-0"
198
- onClick={goToToday}
199
- >
200
- Today
201
- </Button>
202
- </div>
203
-
204
- {/* Month nav */}
205
- <div className="flex items-center justify-between mb-2">
206
- <IconButton
207
- size="smallest"
208
- aria-label="Previous month"
209
- onClick={goToPrevMonth}
210
- >
211
- <ChevronLeftIcon className="h-4 w-4" />
212
- </IconButton>
213
- <Typography variant="body2" className="font-semibold">
214
- {MONTH_NAMES[viewDate.getMonth()]} {viewDate.getFullYear()}
215
- </Typography>
216
- <IconButton
217
- size="smallest"
218
- aria-label="Next month"
219
- onClick={goToNextMonth}
220
- >
221
- <ChevronRightIcon className="h-4 w-4" />
222
- </IconButton>
223
- </div>
224
-
225
- {loading ? (
226
- <Skeleton className="h-48 w-full rounded-lg" />
227
- ) : (
228
- <>
229
- {/* Day headers */}
230
- <div className="grid grid-cols-7 mb-1">
231
- {DAY_HEADERS.map(d => (
232
- <div key={d} className="text-center py-1">
233
- <Typography variant="caption" color="secondary" className="text-[10px] font-semibold uppercase tracking-wider">
234
- {d}
235
- </Typography>
236
- </div>
237
- ))}
238
- </div>
239
-
240
- {/* Calendar grid */}
241
- <div className="grid grid-cols-7 gap-0.5">
242
- {calendarDays.map((day) => {
243
- const dayTasks = tasksByDate.get(day.dateKey) || [];
244
- const hasTasks = dayTasks.length > 0;
245
- const isSelected = selectedDay === day.dateKey;
246
-
247
- // Count tasks by status
248
- const pendingCount = dayTasks.filter(t => t.values.status === "pending").length;
249
- const completedCount = dayTasks.filter(t => t.values.status === "completed").length;
250
- const hasOverdue = dayTasks.some(
251
- t => t.values.status === "pending" && isBeforeToday(new Date(t.values.dueDate!))
252
- );
253
-
254
- return (
255
- <button
256
- key={day.dateKey}
257
- onClick={() => setSelectedDay(isSelected ? null : day.dateKey)}
258
- className={cls(
259
- "flex flex-col items-center justify-center py-1.5 rounded-md transition-colors duration-100 focus:outline-none",
260
- day.isCurrentMonth
261
- ? "text-text-primary dark:text-text-primary-dark"
262
- : "text-surface-300 dark:text-surface-650",
263
- day.isToday && !isSelected && "ring-1 ring-primary/50",
264
- isSelected
265
- ? "bg-primary/10 dark:bg-primary/15 ring-1 ring-primary/60"
266
- : "hover:bg-surface-100 dark:hover:bg-surface-800",
267
- hasTasks && "cursor-pointer"
268
- )}
269
- >
270
- <Typography
271
- variant="caption"
272
- color="inherit"
273
- className={cls(
274
- "leading-none tabular-nums text-[11px]",
275
- day.isToday && "font-semibold text-primary dark:text-primary-light"
276
- )}
277
- >
278
- {day.date.getDate()}
279
- </Typography>
280
-
281
- {/* Task dots */}
282
- {hasTasks ? (
283
- <div className="flex items-center gap-0.5 mt-1 h-[5px]">
284
- {hasOverdue && (
285
- <span className="w-[5px] h-[5px] rounded-full bg-red-500" />
286
- )}
287
- {pendingCount > 0 && !hasOverdue && (
288
- <span className="w-[5px] h-[5px] rounded-full bg-primary" />
289
- )}
290
- {completedCount > 0 && (
291
- <span className="w-[5px] h-[5px] rounded-full bg-emerald-500" />
292
- )}
293
- </div>
294
- ) : (
295
- <div className="h-[5px] mt-1" />
296
- )}
297
- </button>
298
- );
299
- })}
300
- </div>
301
-
302
- {/* Dot legend */}
303
- <div className="flex items-center gap-3 mt-3 mb-1 px-1">
304
- <div className="flex items-center gap-1">
305
- <span className="w-[5px] h-[5px] rounded-full bg-primary" />
306
- <Typography variant="caption" color="secondary" className="text-[10px]">Pending</Typography>
307
- </div>
308
- <div className="flex items-center gap-1">
309
- <span className="w-[5px] h-[5px] rounded-full bg-red-500" />
310
- <Typography variant="caption" color="secondary" className="text-[10px]">Overdue</Typography>
311
- </div>
312
- <div className="flex items-center gap-1">
313
- <span className="w-[5px] h-[5px] rounded-full bg-emerald-500" />
314
- <Typography variant="caption" color="secondary" className="text-[10px]">Done</Typography>
315
- </div>
316
- </div>
317
-
318
- {/* Selected day task list */}
319
- {selectedDay && (
320
- <div className="mt-2">
321
- <Separator orientation="horizontal" className="mb-2" />
322
- {selectedDayTasks.length === 0 ? (
323
- <div className="py-3 text-center">
324
- <Typography variant="caption" color="secondary">
325
- No tasks on this day
326
- </Typography>
327
- </div>
328
- ) : (
329
- <div className="flex flex-col gap-0.5">
330
- <Typography variant="caption" color="secondary" className="mb-1 px-1">
331
- {selectedDayTasks.length} task{selectedDayTasks.length !== 1 ? "s" : ""} — {new Date(selectedDay + "T00:00:00").toLocaleDateString("en-US", { weekday: "short", month: "short", day: "numeric" })}
332
- </Typography>
333
- {selectedDayTasks.map((task) => {
334
- const isPending = task.values.status === "pending";
335
- const isOverdue = isPending && isBeforeToday(new Date(task.values.dueDate!));
336
- return (
337
- <button
338
- key={task.id}
339
- onClick={() => onOpenTask(task.id)}
340
- className={cls(
341
- "flex items-start gap-2 px-2 py-1.5 rounded-md text-left w-full",
342
- "hover:bg-surface-100 dark:hover:bg-surface-800 transition-colors duration-100 focus:outline-none"
343
- )}
344
- >
345
- {/* Status dot */}
346
- <span
347
- className={cls(
348
- "w-1.5 h-1.5 rounded-full mt-1.5 shrink-0",
349
- isOverdue
350
- ? "bg-red-500"
351
- : isPending
352
- ? "bg-primary"
353
- : "bg-emerald-500"
354
- )}
355
- />
356
- <div className="flex-1 min-w-0">
357
- <Typography variant="body2" className="truncate leading-snug">
358
- {task.values.title}
359
- </Typography>
360
- <div className="flex items-center gap-2">
361
- {task.values.client?.name && (
362
- <Typography variant="caption" color="secondary" className="truncate text-[10px]">
363
- {task.values.client.name}
364
- </Typography>
365
- )}
366
- {task.values.stageId && (
367
- <Typography variant="caption" color="disabled" className="truncate text-[10px]">
368
- {stageLabels[task.values.stageId] || task.values.stageId}
369
- </Typography>
370
- )}
371
- </div>
372
- </div>
373
- {task.values.priority === "high" && (
374
- <Chip colorScheme="red" size="smallest">High</Chip>
375
- )}
376
- </button>
377
- );
378
- })}
379
- </div>
380
- )}
381
- </div>
382
- )}
383
- </>
384
- )}
385
- </div>
386
- );
387
- }