feat: fix per-view settings persistence and add recent weather cities

Per-view settings (cellDuration, showSomeday, etc.) now persist across
page reloads by using a ref to avoid stale closure bugs in saveViewSetting
and removing global state pollution from per-view onChange handlers.
Weather display fixed to use effectiveWeatherEnabled for fetch/render.
Added weatherRecentCities (max 8) as quick-switch pill buttons.
Kanban checkboxes now respect the showTaskCheckboxes per-view setting.

v1.51.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
mARTin 2026-03-19 08:32:48 +01:00
parent a26dc5efa6
commit 2141332bb3
5 changed files with 626 additions and 835 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "my-weekly-todo-list", "name": "my-weekly-todo-list",
"version": "1.50.0", "version": "1.51.0",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -115,6 +115,7 @@ model User {
weatherLat Float? weatherLat Float?
weatherLon Float? weatherLon Float?
weatherLocation String? weatherLocation String?
weatherRecentCities Json?
notificationsEnabled Boolean @default(false) notificationsEnabled Boolean @default(false)
somedayLists SomedayList[] somedayLists SomedayList[]
tasks Task[] tasks Task[]

View File

@ -101,6 +101,7 @@ export async function GET(request: NextRequest) {
weatherLat: true, weatherLat: true,
weatherLon: true, weatherLon: true,
weatherLocation: true, weatherLocation: true,
weatherRecentCities: true,
viewSettings: true, viewSettings: true,
createdAt: true createdAt: true
} }
@ -145,7 +146,7 @@ export async function PATCH(request: NextRequest) {
showTaskCheckboxes, dayHeaderGap, showTaskCheckboxes, dayHeaderGap,
showCompletedTasks, showLines, startDayOffset, weekdayFormat, weekdayCase, customWeekdayNames, quoteSourceUrls, quoteLanguages, showCompletedTasks, showLines, startDayOffset, weekdayFormat, weekdayCase, customWeekdayNames, quoteSourceUrls, quoteLanguages,
kanbanStages, lightTheme, darkTheme, notificationsEnabled, mobileFontScale, kanbanStages, lightTheme, darkTheme, notificationsEnabled, mobileFontScale,
weatherEnabled, weatherLat, weatherLon, weatherLocation, viewSettings weatherEnabled, weatherLat, weatherLon, weatherLocation, weatherRecentCities, viewSettings
} = body; } = body;
const updateData: any = { const updateData: any = {
@ -235,6 +236,7 @@ export async function PATCH(request: NextRequest) {
...(weatherLat !== undefined && { weatherLat: weatherLat !== null ? parseFloat(weatherLat) : null }), ...(weatherLat !== undefined && { weatherLat: weatherLat !== null ? parseFloat(weatherLat) : null }),
...(weatherLon !== undefined && { weatherLon: weatherLon !== null ? parseFloat(weatherLon) : null }), ...(weatherLon !== undefined && { weatherLon: weatherLon !== null ? parseFloat(weatherLon) : null }),
...(weatherLocation !== undefined && { weatherLocation }), ...(weatherLocation !== undefined && { weatherLocation }),
...(weatherRecentCities !== undefined && { weatherRecentCities }),
...(viewSettings !== undefined && { viewSettings }), ...(viewSettings !== undefined && { viewSettings }),
}; };
if (password && password.trim() !== "") { if (password && password.trim() !== "") {
@ -334,6 +336,7 @@ export async function PATCH(request: NextRequest) {
weatherLat: true, weatherLat: true,
weatherLon: true, weatherLon: true,
weatherLocation: true, weatherLocation: true,
weatherRecentCities: true,
viewSettings: true, viewSettings: true,
} }
}); });

View File

@ -21,7 +21,7 @@ export async function GET(request: NextRequest) {
select: { weatherEnabled: true, weatherLat: true, weatherLon: true }, select: { weatherEnabled: true, weatherLat: true, weatherLon: true },
}); });
if (!user?.weatherEnabled || !user.weatherLat || !user.weatherLon) { if (!user?.weatherLat || !user.weatherLon) {
return NextResponse.json({ error: 'Weather not configured' }, { status: 400 }); return NextResponse.json({ error: 'Weather not configured' }, { status: 400 });
} }

File diff suppressed because it is too large Load Diff