react-os-shell 0.2.44 → 0.2.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Calendar-4UQDQ3NT.js → Calendar-PKRZ5MBU.js} +153 -54
- package/dist/Calendar-PKRZ5MBU.js.map +1 -0
- package/dist/{CurrencyConverter-TXBFDFG2.js → CurrencyConverter-5N44NZ6Z.js} +3 -3
- package/dist/{CurrencyConverter-TXBFDFG2.js.map → CurrencyConverter-5N44NZ6Z.js.map} +1 -1
- package/dist/{Email-HRBZUWPY.js → Email-CR6XS2AD.js} +4 -4
- package/dist/{Email-HRBZUWPY.js.map → Email-CR6XS2AD.js.map} +1 -1
- package/dist/{GeminiChat-ITU46EH4.js → GeminiChat-XTEBZIVK.js} +3 -3
- package/dist/{GeminiChat-ITU46EH4.js.map → GeminiChat-XTEBZIVK.js.map} +1 -1
- package/dist/{PomodoroTimer-PRP5CZ3S.js → PomodoroTimer-FHSOLF3O.js} +49 -49
- package/dist/PomodoroTimer-FHSOLF3O.js.map +1 -0
- package/dist/TodoList-7JZ2SLDI.js +494 -0
- package/dist/TodoList-7JZ2SLDI.js.map +1 -0
- package/dist/{WorldClock-QO5PVJQQ.js → WorldClock-XHM7WAUV.js} +43 -97
- package/dist/WorldClock-XHM7WAUV.js.map +1 -0
- package/dist/apps/index.d.ts +4 -1
- package/dist/apps/index.js +10 -8
- package/dist/apps/index.js.map +1 -1
- package/dist/chunk-25L4DIKH.js +90 -0
- package/dist/chunk-25L4DIKH.js.map +1 -0
- package/dist/{chunk-62MVMTBT.js → chunk-5VXRBUEH.js} +20 -3
- package/dist/chunk-5VXRBUEH.js.map +1 -0
- package/dist/{chunk-46LICZUM.js → chunk-MVWEL34Y.js} +3 -2
- package/dist/chunk-MVWEL34Y.js.map +1 -0
- package/dist/index.js +2 -2
- package/dist/styles.css +6 -4
- package/package.json +1 -1
- package/dist/Calendar-4UQDQ3NT.js.map +0 -1
- package/dist/PomodoroTimer-PRP5CZ3S.js.map +0 -1
- package/dist/WorldClock-QO5PVJQQ.js.map +0 -1
- package/dist/chunk-46LICZUM.js.map +0 -1
- package/dist/chunk-62MVMTBT.js.map +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { isDemoMode, getDemoCalendarEvents } from './chunk-
|
|
2
|
-
import {
|
|
1
|
+
import { isDemoMode, getDemoCalendarEvents } from './chunk-5VXRBUEH.js';
|
|
2
|
+
import { useTodoTasks } from './chunk-25L4DIKH.js';
|
|
3
|
+
import { useGoogleAuth, getGoogleAccessToken } from './chunk-MVWEL34Y.js';
|
|
3
4
|
import { useShellPrefs } from './chunk-36VM54SC.js';
|
|
4
5
|
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
5
6
|
import { Modal, ModalActions } from './chunk-7M3BBAHQ.js';
|
|
@@ -65,9 +66,24 @@ function Calendar() {
|
|
|
65
66
|
() => isDemoMode() && !google.isConnected ? getDemoCalendarEvents() : [],
|
|
66
67
|
[google.isConnected]
|
|
67
68
|
);
|
|
69
|
+
const { tasks: todoTasks, toggleDone: toggleTodoDone } = useTodoTasks();
|
|
70
|
+
const todoEvents = useMemo(
|
|
71
|
+
() => todoTasks.filter((t) => !!t.dueDate).map((t) => ({
|
|
72
|
+
id: `todo-${t.id}`,
|
|
73
|
+
title: t.name,
|
|
74
|
+
date: t.dueDate,
|
|
75
|
+
color: "gray",
|
|
76
|
+
// Marker fields consumed by MonthView / WeekView to render a
|
|
77
|
+
// checkbox affordance instead of the regular event button.
|
|
78
|
+
_todo: true,
|
|
79
|
+
_todoId: t.id,
|
|
80
|
+
_done: t.done
|
|
81
|
+
})),
|
|
82
|
+
[todoTasks]
|
|
83
|
+
);
|
|
68
84
|
const events = useMemo(
|
|
69
|
-
() => [...localEvents, ...googleEvents, ...demoEvents],
|
|
70
|
-
[localEvents, googleEvents, demoEvents]
|
|
85
|
+
() => [...localEvents, ...googleEvents, ...demoEvents, ...todoEvents],
|
|
86
|
+
[localEvents, googleEvents, demoEvents, todoEvents]
|
|
71
87
|
);
|
|
72
88
|
const today = /* @__PURE__ */ new Date();
|
|
73
89
|
const [currentDate, setCurrentDate] = useState(new Date(today.getFullYear(), today.getMonth(), 1));
|
|
@@ -127,7 +143,8 @@ function Calendar() {
|
|
|
127
143
|
};
|
|
128
144
|
const goToday = () => setCurrentDate(new Date(today.getFullYear(), today.getMonth(), 1));
|
|
129
145
|
const goPrev = () => {
|
|
130
|
-
if (view === "
|
|
146
|
+
if (view === "year") setCurrentDate(new Date(currentDate.getFullYear() - 1, currentDate.getMonth(), 1));
|
|
147
|
+
else if (view === "month") setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1));
|
|
131
148
|
else {
|
|
132
149
|
const d = new Date(currentDate);
|
|
133
150
|
d.setDate(d.getDate() - 7);
|
|
@@ -135,14 +152,15 @@ function Calendar() {
|
|
|
135
152
|
}
|
|
136
153
|
};
|
|
137
154
|
const goNext = () => {
|
|
138
|
-
if (view === "
|
|
155
|
+
if (view === "year") setCurrentDate(new Date(currentDate.getFullYear() + 1, currentDate.getMonth(), 1));
|
|
156
|
+
else if (view === "month") setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1));
|
|
139
157
|
else {
|
|
140
158
|
const d = new Date(currentDate);
|
|
141
159
|
d.setDate(d.getDate() + 7);
|
|
142
160
|
setCurrentDate(d);
|
|
143
161
|
}
|
|
144
162
|
};
|
|
145
|
-
const monthLabel = currentDate.toLocaleDateString(void 0, { month: "long", year: "numeric" });
|
|
163
|
+
const monthLabel = view === "year" ? String(currentDate.getFullYear()) : currentDate.toLocaleDateString(void 0, { month: "long", year: "numeric" });
|
|
146
164
|
const eventsByDate = useMemo(() => {
|
|
147
165
|
const map = {};
|
|
148
166
|
events.forEach((e) => {
|
|
@@ -217,7 +235,7 @@ function Calendar() {
|
|
|
217
235
|
),
|
|
218
236
|
google.error && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-red-500", children: google.error }),
|
|
219
237
|
/* @__PURE__ */ jsx("div", { className: "w-px h-4 bg-gray-200" }),
|
|
220
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["month", "week"].map((v) => /* @__PURE__ */ jsx(
|
|
238
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["year", "month", "week"].map((v) => /* @__PURE__ */ jsx(
|
|
221
239
|
"button",
|
|
222
240
|
{
|
|
223
241
|
onClick: () => setView(v),
|
|
@@ -228,7 +246,19 @@ function Calendar() {
|
|
|
228
246
|
)) })
|
|
229
247
|
] })
|
|
230
248
|
] }),
|
|
231
|
-
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: view === "
|
|
249
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 overflow-hidden", children: view === "year" ? /* @__PURE__ */ jsx(
|
|
250
|
+
YearView,
|
|
251
|
+
{
|
|
252
|
+
year: currentDate.getFullYear(),
|
|
253
|
+
eventsByDate,
|
|
254
|
+
today: toDateStr(today),
|
|
255
|
+
onPickMonth: (m) => {
|
|
256
|
+
setCurrentDate(new Date(currentDate.getFullYear(), m, 1));
|
|
257
|
+
setView("month");
|
|
258
|
+
},
|
|
259
|
+
onDayClick: handleDayClick
|
|
260
|
+
}
|
|
261
|
+
) : view === "month" ? /* @__PURE__ */ jsx(
|
|
232
262
|
MonthView,
|
|
233
263
|
{
|
|
234
264
|
year: currentDate.getFullYear(),
|
|
@@ -236,7 +266,8 @@ function Calendar() {
|
|
|
236
266
|
eventsByDate,
|
|
237
267
|
today: toDateStr(today),
|
|
238
268
|
onDayClick: handleDayClick,
|
|
239
|
-
onEventClick: setEditingEvent
|
|
269
|
+
onEventClick: setEditingEvent,
|
|
270
|
+
onToggleTodo: toggleTodoDone
|
|
240
271
|
}
|
|
241
272
|
) : /* @__PURE__ */ jsx(
|
|
242
273
|
WeekView,
|
|
@@ -245,7 +276,8 @@ function Calendar() {
|
|
|
245
276
|
eventsByDate,
|
|
246
277
|
today: toDateStr(today),
|
|
247
278
|
onDayClick: handleDayClick,
|
|
248
|
-
onEventClick: setEditingEvent
|
|
279
|
+
onEventClick: setEditingEvent,
|
|
280
|
+
onToggleTodo: toggleTodoDone
|
|
249
281
|
}
|
|
250
282
|
) }),
|
|
251
283
|
editingEvent && /* @__PURE__ */ jsx(
|
|
@@ -263,7 +295,71 @@ function Calendar() {
|
|
|
263
295
|
)
|
|
264
296
|
] });
|
|
265
297
|
}
|
|
266
|
-
function
|
|
298
|
+
function DayEventBadge({ evt, onEventClick, onToggleTodo, compact = false }) {
|
|
299
|
+
const e = evt;
|
|
300
|
+
if (e._todo && e._todoId) {
|
|
301
|
+
return compact ? /* @__PURE__ */ jsxs(
|
|
302
|
+
"button",
|
|
303
|
+
{
|
|
304
|
+
onClick: (ev) => {
|
|
305
|
+
ev.stopPropagation();
|
|
306
|
+
onToggleTodo(e._todoId);
|
|
307
|
+
},
|
|
308
|
+
title: e.title,
|
|
309
|
+
className: `w-full text-left flex items-center gap-1 truncate rounded px-1 py-0.5 text-[10px] leading-tight font-medium hover:bg-gray-100 transition-colors ${e._done ? "text-gray-400" : "text-gray-700"}`,
|
|
310
|
+
children: [
|
|
311
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0", children: e._done ? "\u2611" : "\u2610" }),
|
|
312
|
+
/* @__PURE__ */ jsx("span", { className: `truncate ${e._done ? "line-through" : ""}`, children: e.title || "Task" })
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
) : /* @__PURE__ */ jsxs(
|
|
316
|
+
"button",
|
|
317
|
+
{
|
|
318
|
+
onClick: (ev) => {
|
|
319
|
+
ev.stopPropagation();
|
|
320
|
+
onToggleTodo(e._todoId);
|
|
321
|
+
},
|
|
322
|
+
className: `w-full text-left flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-gray-100 transition-colors ${e._done ? "text-gray-400" : "text-gray-700"}`,
|
|
323
|
+
children: [
|
|
324
|
+
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-base leading-none", children: e._done ? "\u2611" : "\u2610" }),
|
|
325
|
+
/* @__PURE__ */ jsx("span", { className: `text-xs font-medium truncate ${e._done ? "line-through" : ""}`, children: e.title || "Task" })
|
|
326
|
+
]
|
|
327
|
+
}
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
const c = getColor(evt.color);
|
|
331
|
+
return compact ? /* @__PURE__ */ jsxs(
|
|
332
|
+
"button",
|
|
333
|
+
{
|
|
334
|
+
onClick: (ev) => {
|
|
335
|
+
ev.stopPropagation();
|
|
336
|
+
onEventClick(evt);
|
|
337
|
+
},
|
|
338
|
+
className: `w-full text-left truncate rounded px-1 py-0.5 text-[10px] leading-tight font-medium ${c.light} hover:opacity-80 transition-opacity`,
|
|
339
|
+
children: [
|
|
340
|
+
!evt.all_day && evt.start_time && /* @__PURE__ */ jsx("span", { className: "text-[9px] opacity-70 mr-0.5", children: evt.start_time }),
|
|
341
|
+
evt.title || "Untitled"
|
|
342
|
+
]
|
|
343
|
+
}
|
|
344
|
+
) : /* @__PURE__ */ jsxs(
|
|
345
|
+
"button",
|
|
346
|
+
{
|
|
347
|
+
onClick: (ev) => {
|
|
348
|
+
ev.stopPropagation();
|
|
349
|
+
onEventClick(evt);
|
|
350
|
+
},
|
|
351
|
+
className: `w-full text-left rounded-md px-2 py-1.5 ${c.light} hover:opacity-80 transition-opacity`,
|
|
352
|
+
children: [
|
|
353
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium truncate", children: evt.title || "Untitled" }),
|
|
354
|
+
!evt.all_day && evt.start_time && /* @__PURE__ */ jsxs("p", { className: "text-[10px] opacity-70", children: [
|
|
355
|
+
evt.start_time,
|
|
356
|
+
evt.end_time ? ` - ${evt.end_time}` : ""
|
|
357
|
+
] })
|
|
358
|
+
]
|
|
359
|
+
}
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
function MonthView({ year, month, eventsByDate, today, onDayClick, onEventClick, onToggleTodo }) {
|
|
267
363
|
const cells = useMemo(() => getMonthDays(year, month), [year, month]);
|
|
268
364
|
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col", children: [
|
|
269
365
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 border-b border-gray-200", children: DAYS.map((d) => /* @__PURE__ */ jsx("div", { className: "px-2 py-1.5 text-[10px] font-semibold text-gray-500 uppercase text-center", children: d }, d)) }),
|
|
@@ -279,24 +375,7 @@ function MonthView({ year, month, eventsByDate, today, onDayClick, onEventClick
|
|
|
279
375
|
children: [
|
|
280
376
|
/* @__PURE__ */ jsx("div", { className: `text-[11px] font-medium mb-0.5 w-5 h-5 flex items-center justify-center rounded-full ${isToday ? "bg-blue-600 text-white" : cell.isCurrentMonth ? "text-gray-900" : "text-gray-400"}`, children: cell.date.getDate() }),
|
|
281
377
|
/* @__PURE__ */ jsxs("div", { className: "space-y-0.5", children: [
|
|
282
|
-
dayEvents.slice(0, 3).map((evt) => {
|
|
283
|
-
const c = getColor(evt.color);
|
|
284
|
-
return /* @__PURE__ */ jsxs(
|
|
285
|
-
"button",
|
|
286
|
-
{
|
|
287
|
-
onClick: (e) => {
|
|
288
|
-
e.stopPropagation();
|
|
289
|
-
onEventClick(evt);
|
|
290
|
-
},
|
|
291
|
-
className: `w-full text-left truncate rounded px-1 py-0.5 text-[10px] leading-tight font-medium ${c.light} hover:opacity-80 transition-opacity`,
|
|
292
|
-
children: [
|
|
293
|
-
!evt.all_day && evt.start_time && /* @__PURE__ */ jsx("span", { className: "text-[9px] opacity-70 mr-0.5", children: evt.start_time }),
|
|
294
|
-
evt.title || "Untitled"
|
|
295
|
-
]
|
|
296
|
-
},
|
|
297
|
-
evt.id
|
|
298
|
-
);
|
|
299
|
-
}),
|
|
378
|
+
dayEvents.slice(0, 3).map((evt) => /* @__PURE__ */ jsx(DayEventBadge, { evt, onEventClick, onToggleTodo, compact: true }, evt.id)),
|
|
300
379
|
dayEvents.length > 3 && /* @__PURE__ */ jsxs("p", { className: "text-[9px] text-gray-400 pl-1", children: [
|
|
301
380
|
"+",
|
|
302
381
|
dayEvents.length - 3,
|
|
@@ -310,7 +389,47 @@ function MonthView({ year, month, eventsByDate, today, onDayClick, onEventClick
|
|
|
310
389
|
}) })
|
|
311
390
|
] });
|
|
312
391
|
}
|
|
313
|
-
function
|
|
392
|
+
function YearView({ year, eventsByDate, today, onPickMonth, onDayClick }) {
|
|
393
|
+
const monthShort = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
394
|
+
const dowShort = ["S", "M", "T", "W", "T", "F", "S"];
|
|
395
|
+
return /* @__PURE__ */ jsx("div", { className: "h-full overflow-y-auto p-4", children: /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-x-6 gap-y-5 max-w-5xl mx-auto", children: monthShort.map((label, m) => {
|
|
396
|
+
const cells = getMonthDays(year, m);
|
|
397
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
398
|
+
/* @__PURE__ */ jsx(
|
|
399
|
+
"button",
|
|
400
|
+
{
|
|
401
|
+
onClick: () => onPickMonth(m),
|
|
402
|
+
className: "self-start text-[13px] font-semibold text-blue-600 hover:text-blue-800 mb-1 px-1 -ml-1 rounded transition-colors",
|
|
403
|
+
children: label
|
|
404
|
+
}
|
|
405
|
+
),
|
|
406
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 mb-0.5", children: dowShort.map((d, i) => /* @__PURE__ */ jsx("div", { className: "text-[9px] font-medium text-gray-400 text-center", children: d }, i)) }),
|
|
407
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7", children: cells.map((cell, i) => {
|
|
408
|
+
const dateStr = toDateStr(cell.date);
|
|
409
|
+
const isToday = dateStr === today;
|
|
410
|
+
const hasEvents = !!eventsByDate[dateStr]?.length;
|
|
411
|
+
return /* @__PURE__ */ jsxs(
|
|
412
|
+
"button",
|
|
413
|
+
{
|
|
414
|
+
onClick: (e) => {
|
|
415
|
+
e.stopPropagation();
|
|
416
|
+
onDayClick(dateStr);
|
|
417
|
+
},
|
|
418
|
+
className: "relative h-6 flex items-center justify-center group",
|
|
419
|
+
tabIndex: cell.isCurrentMonth ? 0 : -1,
|
|
420
|
+
children: [
|
|
421
|
+
/* @__PURE__ */ jsx("span", { className: `text-[10px] tabular-nums leading-none flex items-center justify-center w-5 h-5 rounded-full transition-colors
|
|
422
|
+
${isToday ? "bg-blue-600 text-white font-semibold" : cell.isCurrentMonth ? "text-gray-700 group-hover:bg-blue-100" : "text-gray-300"}`, children: cell.date.getDate() }),
|
|
423
|
+
hasEvents && cell.isCurrentMonth && !isToday && /* @__PURE__ */ jsx("span", { className: "absolute bottom-0 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-blue-500" })
|
|
424
|
+
]
|
|
425
|
+
},
|
|
426
|
+
i
|
|
427
|
+
);
|
|
428
|
+
}) })
|
|
429
|
+
] }, m);
|
|
430
|
+
}) }) });
|
|
431
|
+
}
|
|
432
|
+
function WeekView({ currentDate, eventsByDate, today, onDayClick, onEventClick, onToggleTodo }) {
|
|
314
433
|
const days = useMemo(() => getWeekDays(currentDate), [currentDate]);
|
|
315
434
|
return /* @__PURE__ */ jsxs("div", { className: "h-full flex flex-col", children: [
|
|
316
435
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-7 border-b border-gray-200", children: days.map((d) => {
|
|
@@ -329,27 +448,7 @@ function WeekView({ currentDate, eventsByDate, today, onDayClick, onEventClick }
|
|
|
329
448
|
{
|
|
330
449
|
onClick: () => onDayClick(dateStr),
|
|
331
450
|
className: "border-r border-gray-100 px-1.5 py-2 cursor-pointer hover:bg-blue-50/30 transition-colors min-h-[200px]",
|
|
332
|
-
children: /* @__PURE__ */ jsx("div", { className: "space-y-1", children: dayEvents.map((evt) => {
|
|
333
|
-
const c = getColor(evt.color);
|
|
334
|
-
return /* @__PURE__ */ jsxs(
|
|
335
|
-
"button",
|
|
336
|
-
{
|
|
337
|
-
onClick: (e) => {
|
|
338
|
-
e.stopPropagation();
|
|
339
|
-
onEventClick(evt);
|
|
340
|
-
},
|
|
341
|
-
className: `w-full text-left rounded-md px-2 py-1.5 ${c.light} hover:opacity-80 transition-opacity`,
|
|
342
|
-
children: [
|
|
343
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs font-medium truncate", children: evt.title || "Untitled" }),
|
|
344
|
-
!evt.all_day && evt.start_time && /* @__PURE__ */ jsxs("p", { className: "text-[10px] opacity-70", children: [
|
|
345
|
-
evt.start_time,
|
|
346
|
-
evt.end_time ? ` - ${evt.end_time}` : ""
|
|
347
|
-
] })
|
|
348
|
-
]
|
|
349
|
-
},
|
|
350
|
-
evt.id
|
|
351
|
-
);
|
|
352
|
-
}) })
|
|
451
|
+
children: /* @__PURE__ */ jsx("div", { className: "space-y-1", children: dayEvents.map((evt) => /* @__PURE__ */ jsx(DayEventBadge, { evt, onEventClick, onToggleTodo }, evt.id)) })
|
|
353
452
|
},
|
|
354
453
|
dateStr
|
|
355
454
|
);
|
|
@@ -427,5 +526,5 @@ function EventEditor({ event, isNew, onSave, onDelete, onClose }) {
|
|
|
427
526
|
}
|
|
428
527
|
|
|
429
528
|
export { Calendar as default };
|
|
430
|
-
//# sourceMappingURL=Calendar-
|
|
431
|
-
//# sourceMappingURL=Calendar-
|
|
529
|
+
//# sourceMappingURL=Calendar-PKRZ5MBU.js.map
|
|
530
|
+
//# sourceMappingURL=Calendar-PKRZ5MBU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/apps/Calendar.tsx"],"names":[],"mappings":"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","file":"Calendar-PKRZ5MBU.js","sourcesContent":["import { useState, useMemo, useCallback, useEffect } from 'react';\nimport Modal, { ModalActions } from '../shell/Modal';\nimport toast from '../shell/toast';\nimport useGoogleAuth, { getGoogleAccessToken } from '../hooks/useGoogleAuth';\nimport { isDemoMode, getDemoCalendarEvents } from './google-demo-fixtures';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { useTodoTasks } from './_todoStore';\n\n// ── Types ──\ninterface CalendarEvent {\n id: string;\n title: string;\n date: string; // YYYY-MM-DD\n start_time?: string; // HH:MM\n end_time?: string; // HH:MM\n color: string;\n description?: string;\n all_day?: boolean;\n}\n\ntype ViewMode = 'year' | 'month' | 'week';\n\nconst COLORS = [\n { key: 'blue', bg: 'bg-blue-500', light: 'bg-blue-100 text-blue-800', dot: 'bg-blue-500' },\n { key: 'green', bg: 'bg-green-500', light: 'bg-green-100 text-green-800', dot: 'bg-green-500' },\n { key: 'red', bg: 'bg-red-500', light: 'bg-red-100 text-red-800', dot: 'bg-red-500' },\n { key: 'purple', bg: 'bg-purple-500', light: 'bg-purple-100 text-purple-800', dot: 'bg-purple-500' },\n { key: 'orange', bg: 'bg-orange-500', light: 'bg-orange-100 text-orange-800', dot: 'bg-orange-500' },\n { key: 'pink', bg: 'bg-pink-500', light: 'bg-pink-100 text-pink-800', dot: 'bg-pink-500' },\n { key: 'yellow', bg: 'bg-yellow-500', light: 'bg-yellow-100 text-yellow-800', dot: 'bg-yellow-500' },\n { key: 'gray', bg: 'bg-gray-500', light: 'bg-gray-100 text-gray-800', dot: 'bg-gray-500' },\n];\n\nfunction getColor(key: string) {\n return COLORS.find(c => c.key === key) || COLORS[0];\n}\n\nconst DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n\nfunction pad(n: number) { return String(n).padStart(2, '0'); }\n\nfunction toDateStr(d: Date) {\n return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;\n}\n\nfunction getMonthDays(year: number, month: number) {\n const first = new Date(year, month, 1);\n const startDay = first.getDay();\n const daysInMonth = new Date(year, month + 1, 0).getDate();\n const prevDays = new Date(year, month, 0).getDate();\n\n const cells: { date: Date; isCurrentMonth: boolean }[] = [];\n // Previous month padding\n for (let i = startDay - 1; i >= 0; i--) {\n cells.push({ date: new Date(year, month - 1, prevDays - i), isCurrentMonth: false });\n }\n // Current month\n for (let d = 1; d <= daysInMonth; d++) {\n cells.push({ date: new Date(year, month, d), isCurrentMonth: true });\n }\n // Next month padding\n const remaining = 42 - cells.length;\n for (let d = 1; d <= remaining; d++) {\n cells.push({ date: new Date(year, month + 1, d), isCurrentMonth: false });\n }\n return cells;\n}\n\nfunction getWeekDays(date: Date) {\n const start = new Date(date);\n start.setDate(start.getDate() - start.getDay());\n const days: Date[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(start);\n d.setDate(d.getDate() + i);\n days.push(d);\n }\n return days;\n}\n\n// ── Main Component ──\nexport default function Calendar() {\n const { prefs, save } = useShellPrefs();\n const google = useGoogleAuth();\n const localEvents: CalendarEvent[] = prefs.calendar_events || [];\n const [googleEvents, setGoogleEvents] = useState<CalendarEvent[]>([]);\n // Demo mode: when no Google account is connected, show bundled sample\n // events so the public demo isn't an empty calendar.\n const demoEvents = useMemo<CalendarEvent[]>(\n () => (isDemoMode() && !google.isConnected ? getDemoCalendarEvents() : []),\n [google.isConnected],\n );\n // Pull Todo List tasks that have a due date — render them as a\n // checkbox badge on the matching day. Toggling the checkbox flips\n // `done` in the shared store, which the Todo and Pomodoro apps both\n // see immediately.\n const { tasks: todoTasks, toggleDone: toggleTodoDone } = useTodoTasks();\n const todoEvents = useMemo<CalendarEvent[]>(\n () => todoTasks\n .filter(t => !!t.dueDate)\n .map(t => ({\n id: `todo-${t.id}`,\n title: t.name,\n date: t.dueDate!,\n color: 'gray',\n // Marker fields consumed by MonthView / WeekView to render a\n // checkbox affordance instead of the regular event button.\n _todo: true,\n _todoId: t.id,\n _done: t.done,\n } as CalendarEvent & { _todo: true; _todoId: string; _done: boolean })),\n [todoTasks],\n );\n\n const events = useMemo(\n () => [...localEvents, ...googleEvents, ...demoEvents, ...todoEvents],\n [localEvents, googleEvents, demoEvents, todoEvents],\n );\n const today = new Date();\n const [currentDate, setCurrentDate] = useState(new Date(today.getFullYear(), today.getMonth(), 1));\n\n // Fetch Google Calendar events\n useEffect(() => {\n const token = getGoogleAccessToken();\n if (!token) { setGoogleEvents([]); return; }\n const year = currentDate.getFullYear();\n const month = currentDate.getMonth();\n const timeMin = new Date(year, month - 1, 1).toISOString();\n const timeMax = new Date(year, month + 2, 0).toISOString();\n fetch(`https://www.googleapis.com/calendar/v3/calendars/primary/events?timeMin=${timeMin}&timeMax=${timeMax}&maxResults=250&singleEvents=true&orderBy=startTime`, {\n headers: { Authorization: `Bearer ${token}` },\n })\n .then(r => r.ok ? r.json() : null)\n .then(data => {\n if (!data?.items) return;\n const mapped: CalendarEvent[] = data.items.map((item: any) => {\n const isAllDay = !!item.start?.date;\n const startDate = isAllDay ? item.start.date : item.start?.dateTime?.split('T')[0];\n const startTime = isAllDay ? undefined : item.start?.dateTime?.split('T')[1]?.slice(0, 5);\n const endTime = isAllDay ? undefined : item.end?.dateTime?.split('T')[1]?.slice(0, 5);\n return {\n id: `gcal-${item.id}`,\n title: item.summary || '(No title)',\n date: startDate,\n start_time: startTime,\n end_time: endTime,\n color: 'blue',\n all_day: isAllDay,\n description: item.description,\n _google: true,\n } as CalendarEvent;\n });\n setGoogleEvents(mapped);\n })\n .catch(() => setGoogleEvents([]));\n }, [currentDate]);\n const [view, setView] = useState<ViewMode>('month');\n const [editingEvent, setEditingEvent] = useState<CalendarEvent | null>(null);\n const [newEventDate, setNewEventDate] = useState<string | null>(null);\n\n const saveLocalEvents = useCallback((updated: CalendarEvent[]) => {\n save({ calendar_events: updated });\n }, [save]);\n\n const saveEvent = (evt: CalendarEvent) => {\n const existing = localEvents.find(e => e.id === evt.id);\n if (existing) {\n saveLocalEvents(localEvents.map(e => e.id === evt.id ? evt : e));\n } else {\n saveLocalEvents([...localEvents, evt]);\n }\n setEditingEvent(null);\n setNewEventDate(null);\n };\n\n const deleteEvent = (id: string) => {\n saveLocalEvents(localEvents.filter(e => e.id !== id));\n setEditingEvent(null);\n };\n\n // ── Navigation ──\n const goToday = () => setCurrentDate(new Date(today.getFullYear(), today.getMonth(), 1));\n const goPrev = () => {\n if (view === 'year') setCurrentDate(new Date(currentDate.getFullYear() - 1, currentDate.getMonth(), 1));\n else if (view === 'month') setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1));\n else {\n const d = new Date(currentDate);\n d.setDate(d.getDate() - 7);\n setCurrentDate(d);\n }\n };\n const goNext = () => {\n if (view === 'year') setCurrentDate(new Date(currentDate.getFullYear() + 1, currentDate.getMonth(), 1));\n else if (view === 'month') setCurrentDate(new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1));\n else {\n const d = new Date(currentDate);\n d.setDate(d.getDate() + 7);\n setCurrentDate(d);\n }\n };\n\n // Header label switches to just the year when the year view is active.\n const monthLabel = view === 'year'\n ? String(currentDate.getFullYear())\n : currentDate.toLocaleDateString(undefined, { month: 'long', year: 'numeric' });\n\n // Events by date\n const eventsByDate = useMemo(() => {\n const map: Record<string, CalendarEvent[]> = {};\n events.forEach(e => {\n if (!map[e.date]) map[e.date] = [];\n map[e.date].push(e);\n });\n // Sort by start_time within each day\n for (const key of Object.keys(map)) {\n map[key].sort((a, b) => (a.start_time || '').localeCompare(b.start_time || ''));\n }\n return map;\n }, [events]);\n\n const handleDayClick = (dateStr: string) => {\n setNewEventDate(dateStr);\n setEditingEvent({\n id: `evt-${Date.now()}-${Math.random().toString(36).slice(2, 5)}`,\n title: '',\n date: dateStr,\n start_time: '09:00',\n end_time: '10:00',\n color: 'blue',\n all_day: false,\n });\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-2 border-b border-gray-200 shrink-0\">\n <div className=\"flex items-center gap-3\">\n <button onClick={goToday} className=\"px-2.5 py-1 text-xs font-medium rounded-md border border-gray-300 text-gray-700 hover:bg-gray-50\">Today</button>\n <div className=\"flex items-center gap-1\">\n <button onClick={goPrev} className=\"p-1 rounded hover:bg-gray-100\">\n <svg className=\"h-4 w-4 text-gray-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M15.75 19.5L8.25 12l7.5-7.5\" /></svg>\n </button>\n <button onClick={goNext} className=\"p-1 rounded hover:bg-gray-100\">\n <svg className=\"h-4 w-4 text-gray-600\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" /></svg>\n </button>\n </div>\n <h2 className=\"text-sm font-semibold text-gray-900\">{monthLabel}</h2>\n </div>\n <div className=\"flex items-center gap-2\">\n {/* Google Calendar connection */}\n {google.isConnected ? (\n <button onClick={() => window.dispatchEvent(new Event('open-google-connect'))} title=\"Google Services\"\n className=\"flex items-center gap-2 hover:bg-gray-50 rounded-md px-1.5 py-1 transition-colors\">\n {google.user?.picture ? (\n <img src={google.user.picture} alt=\"\" className=\"h-6 w-6 rounded-full\" />\n ) : (\n <div className=\"h-6 w-6 rounded-full bg-gray-200\" />\n )}\n <div className=\"text-left\">\n <p className=\"text-[11px] font-medium text-gray-900\">{google.user?.name}</p>\n <p className=\"text-[10px] text-gray-500\">{google.user?.email}</p>\n </div>\n </button>\n ) : (\n <button onClick={() => {\n if (!google.hasClientId) {\n const id = prompt('Enter your Google OAuth Client ID\\n\\nCreate one at console.cloud.google.com > APIs > Credentials > OAuth 2.0 Client ID (Web application)');\n if (id?.trim()) google.setClientId(id.trim());\n return;\n }\n google.connect();\n }} disabled={google.loading}\n className=\"inline-flex items-center gap-1.5 border border-gray-300 bg-white rounded-md px-2 py-1 text-[10px] font-medium text-gray-600 hover:bg-gray-50 transition-colors disabled:opacity-50\">\n <svg className=\"h-3.5 w-3.5\" viewBox=\"0 0 24 24\">\n <path d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z\" fill=\"#4285F4\"/>\n <path d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\" fill=\"#34A853\"/>\n <path d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\" fill=\"#FBBC05\"/>\n <path d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\" fill=\"#EA4335\"/>\n </svg>\n {google.loading ? 'Connecting...' : 'Connect Google Calendar'}\n </button>\n )}\n {google.error && <span className=\"text-[10px] text-red-500\">{google.error}</span>}\n\n <div className=\"w-px h-4 bg-gray-200\" />\n <div className=\"flex gap-1\">\n {(['year', 'month', 'week'] as const).map(v => (\n <button key={v} onClick={() => setView(v)}\n className={`px-3 py-1 text-xs font-medium rounded-md transition-colors ${view === v ? 'bg-blue-600 text-white' : 'bg-white border border-gray-300 text-gray-600 hover:bg-gray-50'}`}>\n {v.charAt(0).toUpperCase() + v.slice(1)}\n </button>\n ))}\n </div>\n </div>\n </div>\n\n {/* Calendar grid */}\n <div className=\"flex-1 overflow-hidden\">\n {view === 'year' ? (\n <YearView\n year={currentDate.getFullYear()}\n eventsByDate={eventsByDate}\n today={toDateStr(today)}\n onPickMonth={(m) => { setCurrentDate(new Date(currentDate.getFullYear(), m, 1)); setView('month'); }}\n onDayClick={handleDayClick}\n />\n ) : view === 'month' ? (\n <MonthView\n year={currentDate.getFullYear()}\n month={currentDate.getMonth()}\n eventsByDate={eventsByDate}\n today={toDateStr(today)}\n onDayClick={handleDayClick}\n onEventClick={setEditingEvent}\n onToggleTodo={toggleTodoDone}\n />\n ) : (\n <WeekView\n currentDate={currentDate}\n eventsByDate={eventsByDate}\n today={toDateStr(today)}\n onDayClick={handleDayClick}\n onEventClick={setEditingEvent}\n onToggleTodo={toggleTodoDone}\n />\n )}\n </div>\n\n {/* Event editor modal */}\n {editingEvent && (\n <EventEditor\n event={editingEvent}\n isNew={!!newEventDate}\n onSave={saveEvent}\n onDelete={deleteEvent}\n onClose={() => { setEditingEvent(null); setNewEventDate(null); }}\n />\n )}\n </div>\n );\n}\n\n// ── Shared event/todo badge — used by MonthView and WeekView ──\n// Todo events (recognised by the `_todo` marker on the event object)\n// render as a checkbox + name affordance instead of the regular event\n// pill. Toggling the checkbox flips `done` in the shared todo store.\nfunction DayEventBadge({ evt, onEventClick, onToggleTodo, compact = false }: {\n evt: CalendarEvent;\n onEventClick: (e: CalendarEvent) => void;\n onToggleTodo: (id: string) => void;\n compact?: boolean;\n}) {\n const e = evt as CalendarEvent & { _todo?: true; _todoId?: string; _done?: boolean };\n if (e._todo && e._todoId) {\n return compact ? (\n <button onClick={(ev) => { ev.stopPropagation(); onToggleTodo(e._todoId!); }}\n title={e.title}\n className={`w-full text-left flex items-center gap-1 truncate rounded px-1 py-0.5 text-[10px] leading-tight font-medium hover:bg-gray-100 transition-colors ${e._done ? 'text-gray-400' : 'text-gray-700'}`}>\n <span className=\"shrink-0\">{e._done ? '☑' : '☐'}</span>\n <span className={`truncate ${e._done ? 'line-through' : ''}`}>{e.title || 'Task'}</span>\n </button>\n ) : (\n <button onClick={(ev) => { ev.stopPropagation(); onToggleTodo(e._todoId!); }}\n className={`w-full text-left flex items-center gap-2 rounded-md px-2 py-1.5 hover:bg-gray-100 transition-colors ${e._done ? 'text-gray-400' : 'text-gray-700'}`}>\n <span className=\"shrink-0 text-base leading-none\">{e._done ? '☑' : '☐'}</span>\n <span className={`text-xs font-medium truncate ${e._done ? 'line-through' : ''}`}>{e.title || 'Task'}</span>\n </button>\n );\n }\n // Regular event — same rendering as before.\n const c = getColor(evt.color);\n return compact ? (\n <button onClick={(ev) => { ev.stopPropagation(); onEventClick(evt); }}\n className={`w-full text-left truncate rounded px-1 py-0.5 text-[10px] leading-tight font-medium ${c.light} hover:opacity-80 transition-opacity`}>\n {!evt.all_day && evt.start_time && <span className=\"text-[9px] opacity-70 mr-0.5\">{evt.start_time}</span>}\n {evt.title || 'Untitled'}\n </button>\n ) : (\n <button onClick={(ev) => { ev.stopPropagation(); onEventClick(evt); }}\n className={`w-full text-left rounded-md px-2 py-1.5 ${c.light} hover:opacity-80 transition-opacity`}>\n <p className=\"text-xs font-medium truncate\">{evt.title || 'Untitled'}</p>\n {!evt.all_day && evt.start_time && (\n <p className=\"text-[10px] opacity-70\">{evt.start_time}{evt.end_time ? ` - ${evt.end_time}` : ''}</p>\n )}\n </button>\n );\n}\n\n// ── Month View ──\nfunction MonthView({ year, month, eventsByDate, today, onDayClick, onEventClick, onToggleTodo }: {\n year: number; month: number; eventsByDate: Record<string, CalendarEvent[]>;\n today: string; onDayClick: (d: string) => void; onEventClick: (e: CalendarEvent) => void;\n onToggleTodo: (id: string) => void;\n}) {\n const cells = useMemo(() => getMonthDays(year, month), [year, month]);\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Day headers */}\n <div className=\"grid grid-cols-7 border-b border-gray-200\">\n {DAYS.map(d => (\n <div key={d} className=\"px-2 py-1.5 text-[10px] font-semibold text-gray-500 uppercase text-center\">{d}</div>\n ))}\n </div>\n {/* Day cells */}\n <div className=\"grid grid-cols-7 flex-1 auto-rows-fr\">\n {cells.map((cell, i) => {\n const dateStr = toDateStr(cell.date);\n const isToday = dateStr === today;\n const dayEvents = eventsByDate[dateStr] || [];\n return (\n <div key={i}\n onClick={() => onDayClick(dateStr)}\n className={`border-b border-r border-gray-100 px-1 py-0.5 cursor-pointer hover:bg-blue-50/50 transition-colors overflow-hidden ${!cell.isCurrentMonth ? 'bg-gray-50/50' : ''}`}\n >\n <div className={`text-[11px] font-medium mb-0.5 w-5 h-5 flex items-center justify-center rounded-full ${isToday ? 'bg-blue-600 text-white' : cell.isCurrentMonth ? 'text-gray-900' : 'text-gray-400'}`}>\n {cell.date.getDate()}\n </div>\n <div className=\"space-y-0.5\">\n {dayEvents.slice(0, 3).map(evt => <DayEventBadge key={evt.id} evt={evt} onEventClick={onEventClick} onToggleTodo={onToggleTodo} compact />)}\n {dayEvents.length > 3 && (\n <p className=\"text-[9px] text-gray-400 pl-1\">+{dayEvents.length - 3} more</p>\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ── Year View ──\n// Apple-Calendar-style 4×3 grid of compact mini-month cards. The month\n// names are abbreviated (Jan / Feb / …) so the title hierarchy stays\n// \"year on the left of the toolbar, month above each grid\". Today is\n// highlighted with a filled blue circle; days with events get a tiny\n// dot under the number. Clicking the month label jumps to Month view;\n// clicking a day jumps to Month view AND opens the event editor for\n// that day.\nfunction YearView({ year, eventsByDate, today, onPickMonth, onDayClick }: {\n year: number;\n eventsByDate: Record<string, CalendarEvent[]>;\n today: string;\n onPickMonth: (month: number) => void;\n onDayClick: (dateStr: string) => void;\n}) {\n const monthShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n const dowShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];\n\n return (\n <div className=\"h-full overflow-y-auto p-4\">\n <div className=\"grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-x-6 gap-y-5 max-w-5xl mx-auto\">\n {monthShort.map((label, m) => {\n const cells = getMonthDays(year, m);\n return (\n <div key={m} className=\"flex flex-col\">\n {/* Compact title: month abbrev as a small button that jumps\n to that month in Month view. */}\n <button onClick={() => onPickMonth(m)}\n className=\"self-start text-[13px] font-semibold text-blue-600 hover:text-blue-800 mb-1 px-1 -ml-1 rounded transition-colors\">\n {label}\n </button>\n\n {/* Day-of-week labels */}\n <div className=\"grid grid-cols-7 mb-0.5\">\n {dowShort.map((d, i) => (\n <div key={i} className=\"text-[9px] font-medium text-gray-400 text-center\">{d}</div>\n ))}\n </div>\n\n {/* Date grid */}\n <div className=\"grid grid-cols-7\">\n {cells.map((cell, i) => {\n const dateStr = toDateStr(cell.date);\n const isToday = dateStr === today;\n const hasEvents = !!eventsByDate[dateStr]?.length;\n return (\n <button key={i}\n onClick={(e) => { e.stopPropagation(); onDayClick(dateStr); }}\n className=\"relative h-6 flex items-center justify-center group\"\n tabIndex={cell.isCurrentMonth ? 0 : -1}>\n <span className={`text-[10px] tabular-nums leading-none flex items-center justify-center w-5 h-5 rounded-full transition-colors\n ${isToday\n ? 'bg-blue-600 text-white font-semibold'\n : cell.isCurrentMonth\n ? 'text-gray-700 group-hover:bg-blue-100'\n : 'text-gray-300'}`}>\n {cell.date.getDate()}\n </span>\n {hasEvents && cell.isCurrentMonth && !isToday && (\n <span className=\"absolute bottom-0 left-1/2 -translate-x-1/2 w-1 h-1 rounded-full bg-blue-500\" />\n )}\n </button>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ── Week View ──\nfunction WeekView({ currentDate, eventsByDate, today, onDayClick, onEventClick, onToggleTodo }: {\n currentDate: Date; eventsByDate: Record<string, CalendarEvent[]>;\n today: string; onDayClick: (d: string) => void; onEventClick: (e: CalendarEvent) => void;\n onToggleTodo: (id: string) => void;\n}) {\n const days = useMemo(() => getWeekDays(currentDate), [currentDate]);\n\n return (\n <div className=\"h-full flex flex-col\">\n {/* Day headers */}\n <div className=\"grid grid-cols-7 border-b border-gray-200\">\n {days.map(d => {\n const dateStr = toDateStr(d);\n const isToday = dateStr === today;\n return (\n <div key={dateStr} className=\"px-2 py-2 text-center\">\n <p className=\"text-[10px] font-medium text-gray-500 uppercase\">{DAYS[d.getDay()]}</p>\n <p className={`text-lg font-semibold mt-0.5 ${isToday ? 'text-blue-600' : 'text-gray-900'}`}>{d.getDate()}</p>\n </div>\n );\n })}\n </div>\n {/* Day columns */}\n <div className=\"grid grid-cols-7 flex-1 overflow-y-auto\">\n {days.map(d => {\n const dateStr = toDateStr(d);\n const dayEvents = eventsByDate[dateStr] || [];\n return (\n <div key={dateStr}\n onClick={() => onDayClick(dateStr)}\n className=\"border-r border-gray-100 px-1.5 py-2 cursor-pointer hover:bg-blue-50/30 transition-colors min-h-[200px]\">\n <div className=\"space-y-1\">\n {dayEvents.map(evt => <DayEventBadge key={evt.id} evt={evt} onEventClick={onEventClick} onToggleTodo={onToggleTodo} />)}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n// ── Event Editor ──\nfunction EventEditor({ event, isNew, onSave, onDelete, onClose }: {\n event: CalendarEvent; isNew: boolean;\n onSave: (e: CalendarEvent) => void; onDelete: (id: string) => void; onClose: () => void;\n}) {\n const [title, setTitle] = useState(event.title);\n const [date, setDate] = useState(event.date);\n const [startTime, setStartTime] = useState(event.start_time || '09:00');\n const [endTime, setEndTime] = useState(event.end_time || '10:00');\n const [color, setColor] = useState(event.color);\n const [allDay, setAllDay] = useState(event.all_day ?? false);\n const [description, setDescription] = useState(event.description || '');\n\n const handleSave = () => {\n if (!title.trim()) { toast.error('Event title is required.'); return; }\n onSave({\n ...event,\n title: title.trim(),\n date,\n start_time: allDay ? undefined : startTime,\n end_time: allDay ? undefined : endTime,\n color,\n all_day: allDay,\n description: description.trim() || undefined,\n });\n };\n\n const inp = 'block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm';\n\n return (\n <Modal open onClose={onClose} title={isNew ? 'New Event' : 'Edit Event'} size=\"sm\">\n <div className=\"space-y-4\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Title *</label>\n <input value={title} onChange={e => setTitle(e.target.value)} className={inp} placeholder=\"Event title\" autoFocus />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Date</label>\n <input type=\"date\" value={date} onChange={e => setDate(e.target.value)} className={inp} />\n </div>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={allDay} onChange={e => setAllDay(e.target.checked)} className=\"h-4 w-4 rounded border-gray-300 text-blue-600\" />\n <span className=\"text-sm text-gray-700\">All day</span>\n </label>\n {!allDay && (\n <div className=\"grid grid-cols-2 gap-3\">\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Start</label>\n <input type=\"time\" value={startTime} onChange={e => setStartTime(e.target.value)} className={inp} />\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">End</label>\n <input type=\"time\" value={endTime} onChange={e => setEndTime(e.target.value)} className={inp} />\n </div>\n </div>\n )}\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Color</label>\n <div className=\"flex gap-2\">\n {COLORS.map(c => (\n <button key={c.key} onClick={() => setColor(c.key)}\n className={`w-6 h-6 rounded-full ${c.bg} border-2 transition-all ${color === c.key ? 'border-gray-700 scale-110' : 'border-transparent hover:border-gray-400'}`} />\n ))}\n </div>\n </div>\n <div>\n <label className=\"block text-sm font-medium text-gray-700 mb-1\">Description</label>\n <textarea value={description} onChange={e => setDescription(e.target.value)} rows={2} className={inp} placeholder=\"Optional notes...\" />\n </div>\n </div>\n\n {!isNew && (\n <ModalActions position=\"left\">\n <button onClick={() => onDelete(event.id)} className=\"text-sm text-red-600 hover:text-red-800 font-medium\">Delete</button>\n </ModalActions>\n )}\n <ModalActions>\n <button onClick={handleSave} className=\"bg-blue-600 text-white px-4 py-2 text-sm font-medium rounded-lg hover:bg-blue-700\">\n {isNew ? 'Create' : 'Save'}\n </button>\n </ModalActions>\n </Modal>\n );\n}\n"]}
|
|
@@ -119,7 +119,7 @@ function CurrencyConverter() {
|
|
|
119
119
|
/* @__PURE__ */ jsx(
|
|
120
120
|
"div",
|
|
121
121
|
{
|
|
122
|
-
className: "flex flex-col h-full
|
|
122
|
+
className: "flex flex-col h-full",
|
|
123
123
|
style: { backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : void 0 },
|
|
124
124
|
children: /* @__PURE__ */ jsxs("div", { className: "px-4 py-3 space-y-1 flex-1", children: [
|
|
125
125
|
loading && /* @__PURE__ */ jsx("div", { className: "text-xs text-gray-400 text-center py-4", children: "Loading rates..." }),
|
|
@@ -225,5 +225,5 @@ function CurrencyConverter() {
|
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
export { CurrencyConverter as default };
|
|
228
|
-
//# sourceMappingURL=CurrencyConverter-
|
|
229
|
-
//# sourceMappingURL=CurrencyConverter-
|
|
228
|
+
//# sourceMappingURL=CurrencyConverter-5N44NZ6Z.js.map
|
|
229
|
+
//# sourceMappingURL=CurrencyConverter-5N44NZ6Z.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/CurrencyConverter.tsx"],"names":[],"mappings":"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","file":"CurrencyConverter-TXBFDFG2.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\nconst ALL_CURRENCIES = ['USD', 'CNY', 'AUD', 'GBP', 'EUR', 'JPY', 'CAD', 'THB', 'NZD', 'SGD', 'HKD', 'CHF', 'KRW', 'INR', 'MXN', 'BRL'];\n\n/** Cap the rate list at 4 — keeps the widget compact and avoids\n * overwhelming the user with currencies they don't actually track. */\nconst MAX_PAIRS = 4;\n\nconst DEFAULT_PAIRS: [string, string][] = [\n ['USD', 'CNY'], ['USD', 'AUD'], ['GBP', 'USD'], ['USD', 'JPY'],\n];\n\nconst PAIRS_KEY = 'currency_pairs';\nconst SETTINGS_KEY = 'currency_appearance';\nconst CACHE_KEY = 'currency_rates_cache';\nconst CACHE_TTL = 3600000;\n\ntype CacheEntry = { rates: Record<string, number>; timestamp: number };\n\nfunction getCached(base: string): Record<string, number> | null {\n try { const c: Record<string, CacheEntry> = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); const e = c[base]; if (e && Date.now() - e.timestamp < CACHE_TTL) return e.rates; } catch {} return null;\n}\nfunction setCache(base: string, rates: Record<string, number>) {\n try { const c = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); c[base] = { rates, timestamp: Date.now() }; localStorage.setItem(CACHE_KEY, JSON.stringify(c)); } catch {}\n}\nfunction loadPairs(): [string, string][] {\n try {\n const s = JSON.parse(localStorage.getItem(PAIRS_KEY) || '');\n if (Array.isArray(s) && s.length) return s.slice(0, MAX_PAIRS);\n } catch {}\n return DEFAULT_PAIRS;\n}\n\nconst FLAG: Record<string, string> = {\n USD: '\\u{1F1FA}\\u{1F1F8}', CNY: '\\u{1F1E8}\\u{1F1F3}', AUD: '\\u{1F1E6}\\u{1F1FA}',\n GBP: '\\u{1F1EC}\\u{1F1E7}', JPY: '\\u{1F1EF}\\u{1F1F5}', CAD: '\\u{1F1E8}\\u{1F1E6}',\n EUR: '\\u{1F1EA}\\u{1F1FA}', THB: '\\u{1F1F9}\\u{1F1ED}', NZD: '\\u{1F1F3}\\u{1F1FF}',\n SGD: '\\u{1F1F8}\\u{1F1EC}', HKD: '\\u{1F1ED}\\u{1F1F0}', CHF: '\\u{1F1E8}\\u{1F1ED}',\n KRW: '\\u{1F1F0}\\u{1F1F7}', INR: '\\u{1F1EE}\\u{1F1F3}', MXN: '\\u{1F1F2}\\u{1F1FD}',\n BRL: '\\u{1F1E7}\\u{1F1F7}',\n};\n\nexport default function CurrencyConverter() {\n const [pairs, setPairs] = useState(loadPairs);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [allRates, setAllRates] = useState<Record<string, Record<string, number>>>({});\n const [loading, setLoading] = useState(false);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configPairs, setConfigPairs] = useState<[string, string][]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n const [newFrom, setNewFrom] = useState('USD');\n const [newTo, setNewTo] = useState('CNY');\n\n useWidgetSettings(useCallback(() => {\n setConfigPairs([...pairs]);\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [pairs, appearance]));\n\n useEffect(() => {\n const bases = [...new Set(pairs.map(([from]) => from))];\n let mounted = true;\n async function fetchAll() {\n setLoading(true);\n const result: Record<string, Record<string, number>> = {};\n for (const base of bases) {\n const cached = getCached(base);\n if (cached) { result[base] = cached; continue; }\n try { const res = await fetch(`https://open.er-api.com/v6/latest/${base}`); const data = await res.json(); if (data.rates) { result[base] = data.rates; setCache(base, data.rates); } } catch {}\n }\n if (mounted) { setAllRates(result); setLoading(false); }\n }\n fetchAll();\n return () => { mounted = false; };\n }, [pairs]);\n\n const saveSettings = () => {\n if (configPairs.length === 0) return;\n const capped = configPairs.slice(0, MAX_PAIRS);\n setPairs(capped); setAppearance(configAppearance);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(capped));\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n return (\n <>\n {/* Theme-aware panel — pulls the same `--taskbar-bg-rgb` colour the\n * taskbar uses so the widget matches it across all themes\n * (gray-100-ish on light, Catppuccin mantle in dark). Tailwind\n * gray-* text/border classes auto-invert in dark via the existing\n * `[data-theme=\"dark\"]` overrides in styles.css. */}\n <div className=\"flex flex-col h-full rounded-2xl overflow-hidden\"\n style={{ backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined }}>\n <div className=\"px-4 py-3 space-y-1 flex-1\">\n {loading && <div className=\"text-xs text-gray-400 text-center py-4\">Loading rates...</div>}\n {pairs.map(([from, to], idx) => {\n const rate = allRates[from]?.[to];\n return (\n <button key={`${from}-${to}-${idx}`} onClick={() => {\n const swapped: [string, string][] = pairs.map((p, i) => i === idx ? [p[1], p[0]] : p);\n setPairs(swapped);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(swapped));\n }}\n className=\"flex items-center justify-between px-2 py-2 border-b border-gray-200 last:border-0 w-full hover:bg-gray-100 rounded transition-colors cursor-pointer\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-base\">{FLAG[from] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{from}</span>\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" /></svg>\n <span className=\"text-base\">{FLAG[to] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{to}</span>\n </div>\n <div className=\"text-base font-mono font-semibold text-gray-900 tabular-nums\">\n {rate != null ? rate.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 }) : '—'}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Currency Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Currency Pairs <span className=\"text-[11px] font-normal text-gray-400\">({configPairs.length}/{MAX_PAIRS})</span></h3>\n <div className=\"space-y-1 mb-2\">\n {configPairs.map(([f, t], i) => (\n <div key={i} className=\"flex items-center justify-between py-1 px-2 bg-gray-50 rounded\">\n <span className=\"text-sm\">{FLAG[f] || ''} {f} → {FLAG[t] || ''} {t}</span>\n <button onClick={() => setConfigPairs(p => p.filter((_, idx) => idx !== i))} className=\"text-red-400 hover:text-red-600\">×</button>\n </div>\n ))}\n </div>\n {configPairs.length < MAX_PAIRS ? (\n <div className=\"flex items-center gap-2\">\n <select value={newFrom} onChange={e => setNewFrom(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <span className=\"text-gray-400\">→</span>\n <select value={newTo} onChange={e => setNewTo(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <button onClick={() => { if (newFrom !== newTo && configPairs.length < MAX_PAIRS) setConfigPairs(p => [...p, [newFrom, newTo]]); }}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800 px-2\">+ Add</button>\n </div>\n ) : (\n <p className=\"text-[11px] text-gray-400 italic\">Max {MAX_PAIRS} pairs — remove one to add another.</p>\n )}\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/CurrencyConverter.tsx"],"names":[],"mappings":"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","file":"CurrencyConverter-5N44NZ6Z.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\n\nconst ALL_CURRENCIES = ['USD', 'CNY', 'AUD', 'GBP', 'EUR', 'JPY', 'CAD', 'THB', 'NZD', 'SGD', 'HKD', 'CHF', 'KRW', 'INR', 'MXN', 'BRL'];\n\n/** Cap the rate list at 4 — keeps the widget compact and avoids\n * overwhelming the user with currencies they don't actually track. */\nconst MAX_PAIRS = 4;\n\nconst DEFAULT_PAIRS: [string, string][] = [\n ['USD', 'CNY'], ['USD', 'AUD'], ['GBP', 'USD'], ['USD', 'JPY'],\n];\n\nconst PAIRS_KEY = 'currency_pairs';\nconst SETTINGS_KEY = 'currency_appearance';\nconst CACHE_KEY = 'currency_rates_cache';\nconst CACHE_TTL = 3600000;\n\ntype CacheEntry = { rates: Record<string, number>; timestamp: number };\n\nfunction getCached(base: string): Record<string, number> | null {\n try { const c: Record<string, CacheEntry> = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); const e = c[base]; if (e && Date.now() - e.timestamp < CACHE_TTL) return e.rates; } catch {} return null;\n}\nfunction setCache(base: string, rates: Record<string, number>) {\n try { const c = JSON.parse(localStorage.getItem(CACHE_KEY) || '{}'); c[base] = { rates, timestamp: Date.now() }; localStorage.setItem(CACHE_KEY, JSON.stringify(c)); } catch {}\n}\nfunction loadPairs(): [string, string][] {\n try {\n const s = JSON.parse(localStorage.getItem(PAIRS_KEY) || '');\n if (Array.isArray(s) && s.length) return s.slice(0, MAX_PAIRS);\n } catch {}\n return DEFAULT_PAIRS;\n}\n\nconst FLAG: Record<string, string> = {\n USD: '\\u{1F1FA}\\u{1F1F8}', CNY: '\\u{1F1E8}\\u{1F1F3}', AUD: '\\u{1F1E6}\\u{1F1FA}',\n GBP: '\\u{1F1EC}\\u{1F1E7}', JPY: '\\u{1F1EF}\\u{1F1F5}', CAD: '\\u{1F1E8}\\u{1F1E6}',\n EUR: '\\u{1F1EA}\\u{1F1FA}', THB: '\\u{1F1F9}\\u{1F1ED}', NZD: '\\u{1F1F3}\\u{1F1FF}',\n SGD: '\\u{1F1F8}\\u{1F1EC}', HKD: '\\u{1F1ED}\\u{1F1F0}', CHF: '\\u{1F1E8}\\u{1F1ED}',\n KRW: '\\u{1F1F0}\\u{1F1F7}', INR: '\\u{1F1EE}\\u{1F1F3}', MXN: '\\u{1F1F2}\\u{1F1FD}',\n BRL: '\\u{1F1E7}\\u{1F1F7}',\n};\n\nexport default function CurrencyConverter() {\n const [pairs, setPairs] = useState(loadPairs);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [allRates, setAllRates] = useState<Record<string, Record<string, number>>>({});\n const [loading, setLoading] = useState(false);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configPairs, setConfigPairs] = useState<[string, string][]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n const [newFrom, setNewFrom] = useState('USD');\n const [newTo, setNewTo] = useState('CNY');\n\n useWidgetSettings(useCallback(() => {\n setConfigPairs([...pairs]);\n setConfigAppearance({ ...appearance });\n setSettingsOpen(true);\n }, [pairs, appearance]));\n\n useEffect(() => {\n const bases = [...new Set(pairs.map(([from]) => from))];\n let mounted = true;\n async function fetchAll() {\n setLoading(true);\n const result: Record<string, Record<string, number>> = {};\n for (const base of bases) {\n const cached = getCached(base);\n if (cached) { result[base] = cached; continue; }\n try { const res = await fetch(`https://open.er-api.com/v6/latest/${base}`); const data = await res.json(); if (data.rates) { result[base] = data.rates; setCache(base, data.rates); } } catch {}\n }\n if (mounted) { setAllRates(result); setLoading(false); }\n }\n fetchAll();\n return () => { mounted = false; };\n }, [pairs]);\n\n const saveSettings = () => {\n if (configPairs.length === 0) return;\n const capped = configPairs.slice(0, MAX_PAIRS);\n setPairs(capped); setAppearance(configAppearance);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(capped));\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n return (\n <>\n {/* Theme-aware panel — pulls the same `--taskbar-bg-rgb` colour the\n * taskbar uses so the widget matches it across all themes\n * (gray-100-ish on light, Catppuccin mantle in dark). Tailwind\n * gray-* text/border classes auto-invert in dark via the existing\n * `[data-theme=\"dark\"]` overrides in styles.css. */}\n <div className=\"flex flex-col h-full\"\n style={{ backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`, backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined }}>\n <div className=\"px-4 py-3 space-y-1 flex-1\">\n {loading && <div className=\"text-xs text-gray-400 text-center py-4\">Loading rates...</div>}\n {pairs.map(([from, to], idx) => {\n const rate = allRates[from]?.[to];\n return (\n <button key={`${from}-${to}-${idx}`} onClick={() => {\n const swapped: [string, string][] = pairs.map((p, i) => i === idx ? [p[1], p[0]] : p);\n setPairs(swapped);\n localStorage.setItem(PAIRS_KEY, JSON.stringify(swapped));\n }}\n className=\"flex items-center justify-between px-2 py-2 border-b border-gray-200 last:border-0 w-full hover:bg-gray-100 rounded transition-colors cursor-pointer\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-base\">{FLAG[from] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{from}</span>\n <svg className=\"h-3 w-3 text-gray-400\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}><path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4\" /></svg>\n <span className=\"text-base\">{FLAG[to] || ''}</span>\n <span className=\"text-sm font-semibold text-gray-700\">{to}</span>\n </div>\n <div className=\"text-base font-mono font-semibold text-gray-900 tabular-nums\">\n {rate != null ? rate.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 }) : '—'}\n </div>\n </button>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Currency Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Currency Pairs <span className=\"text-[11px] font-normal text-gray-400\">({configPairs.length}/{MAX_PAIRS})</span></h3>\n <div className=\"space-y-1 mb-2\">\n {configPairs.map(([f, t], i) => (\n <div key={i} className=\"flex items-center justify-between py-1 px-2 bg-gray-50 rounded\">\n <span className=\"text-sm\">{FLAG[f] || ''} {f} → {FLAG[t] || ''} {t}</span>\n <button onClick={() => setConfigPairs(p => p.filter((_, idx) => idx !== i))} className=\"text-red-400 hover:text-red-600\">×</button>\n </div>\n ))}\n </div>\n {configPairs.length < MAX_PAIRS ? (\n <div className=\"flex items-center gap-2\">\n <select value={newFrom} onChange={e => setNewFrom(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <span className=\"text-gray-400\">→</span>\n <select value={newTo} onChange={e => setNewTo(e.target.value)}\n className=\"bg-gray-50 border border-gray-200 rounded px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {ALL_CURRENCIES.map(c => <option key={c}>{c}</option>)}\n </select>\n <button onClick={() => { if (newFrom !== newTo && configPairs.length < MAX_PAIRS) setConfigPairs(p => [...p, [newFrom, newTo]]); }}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800 px-2\">+ Add</button>\n </div>\n ) : (\n <p className=\"text-[11px] text-gray-400 italic\">Max {MAX_PAIRS} pairs — remove one to add another.</p>\n )}\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { isDemoMode, getDemoEmails } from './chunk-62MVMTBT.js';
|
|
2
1
|
import { EditableGrid } from './chunk-GP4Y3VCB.js';
|
|
2
|
+
import { isDemoMode, getDemoEmails } from './chunk-5VXRBUEH.js';
|
|
3
3
|
import { setEmailUnreadCount } from './chunk-PDFQNHW7.js';
|
|
4
4
|
import { formatDateTime, formatDate } from './chunk-NSU7OHPC.js';
|
|
5
|
-
import { useGoogleAuth } from './chunk-
|
|
5
|
+
import { useGoogleAuth } from './chunk-MVWEL34Y.js';
|
|
6
6
|
import { toast_default } from './chunk-WIJ45SYD.js';
|
|
7
7
|
import { Modal, ModalActions, glassStyle } from './chunk-7M3BBAHQ.js';
|
|
8
8
|
import './chunk-PLGHQ7QW.js';
|
|
@@ -1878,5 +1878,5 @@ function EmailDemoView() {
|
|
|
1878
1878
|
}
|
|
1879
1879
|
|
|
1880
1880
|
export { Email as default };
|
|
1881
|
-
//# sourceMappingURL=Email-
|
|
1882
|
-
//# sourceMappingURL=Email-
|
|
1881
|
+
//# sourceMappingURL=Email-CR6XS2AD.js.map
|
|
1882
|
+
//# sourceMappingURL=Email-CR6XS2AD.js.map
|