Commit Graph

117 Commits

Author SHA1 Message Date
d3a40e32a0 fix: localise auth emails, repair verify link, recover from expired
Wave-3 user feedback (points 1–3):
- Email templates: extract de/en/fr/es/it copy into emailTemplates.ts
  and pick the user's language. Signup forwards navigator.language and
  the API also respects Accept-Language; resend/reset reuse user.language.
- Verify link: the email button now points at the client page instead of
  the API GET handler, so corporate inbox scanners (M365 Safe Links etc.)
  can no longer pre-fetch and silently consume the one-shot token. The
  client page requires a real click before calling PATCH /api/auth/
  verify-email. The legacy GET handler now just redirects to the client
  page so old in-flight emails keep working.
- Code expired UX: when users land via an expired-link redirect we no
  longer leave them with a blank email field — the page exposes an email
  input so the resend button has something to act on. The verify-email
  redirect also forwards the email param.

Misc: tsconfig migrated to moduleResolution=bundler and dropped
downlevelIteration to clear the TS 7.0 deprecation errors.

v1.101.0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 20:09:33 +02:00
52d160ccea feat: projects tab, priority icons, list/tab visuals
Wave-1 user feedback (points 7–10):
- Settings: new Projects tab with full CRUD (name, color, icon picker)
- Priority Icons render in simple/calendar/list views with style-specific
  visuals (Eisenhower icons, ABCDE letters, Ivy Lee 1–6, Pareto star).
  Toggle + style selector in Settings; Ivy Lee ranks now persist to
  task.priority so cross-view badges stay consistent.
- Someday Lists gain optional icon (left of title) and color (left
  border tint), edited via a pencil-popup with IconPicker + color picker.
- Tabs gain optional icon and color, stored in user.viewSettings JSON
  and edited via the same popup pattern.

Schema: SomedayList.color/icon, User.showPriorityIcons/priorityStyle.

v1.99.0

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-01 14:23:56 +02:00
ac17ca2635 feat: improve PDF export — header, layout, icons, tab filter
- Add page header per PDF page: KW + date range (headline font/accent
  color) + motivational quote (right-aligned italic, from local quotes)
- Move all-day strip above weekday/date header to match webapp layout
- Increase font sizes across the board (task titles 7.5pt, time labels
  7.5pt, day date 8pt) to better match the web view
- Remove time prefix from task rows (hour-row label already provides
  context); completed tasks get strikethrough styling
- Calendar event chips in all-day strip now use solid calendar color +
  white text + small dot indicator (replaces 📅 emoji, which Helvetica
  cannot render in PDFs)
- Fix multi-day all-day events: expand CachedCalendarEvents across every
  day they span (iCal endDate is exclusive); deduplicate by title to
  prevent double-rendering when the same event exists in both Task and
  CachedCalendarEvent tables
- Someday page is now landscape (matches main week pages)
- Print modal: fetch available someday tabs on open; show pill-checkbox
  filter below "Aufgaben ohne Uhrzeit" toggle when multiple tabs exist;
  selected tabs are passed to the export route as noTimeTabs param
- New API endpoint GET /api/user/someday-tabs for fetching tab list
- Export route filters someday lists by noTimeTabs when provided

v1.97.2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 17:00:13 +02:00
1051dfd96c feat: list-style PDF layout with per-hour weather symbols
Layout — switched from absolute-positioned calendar grid to agenda/list:
- Each day column divided into equal-height hour rows (flex: 1)
- Tasks listed as text rows within their hour slot (time + title inline)
- No absolute positioning, no background stripes, no floating blocks
- External calendar events: light tinted row with left border + bold title
- User tasks with project: left border in project color
- User tasks without project: plain text, no border
- Time column updated to flex rows, stays aligned with day column rows

Weather — switched to hourly API data (temperature_2m + weather_code):
- Small colored circle + temperature shown in top-right of each hour row
- Color encodes condition: amber=clear, gray=cloudy, blue=rain,
  pale-blue=snow, purple=thunderstorm
- Removed WMO text dictionaries (no more written-out condition text)

v1.96.3
2026-04-13 12:56:55 +02:00
c414c2718d fix: move weather from day header to time-grid cell (top-right chip)
Matches webapp behaviour where weather appears as a chip in the top-right
corner of each day's time grid area, not inside the day header.

v1.96.2
2026-04-13 12:46:27 +02:00
38462c50f7 fix: PDF export style and header fixes
- Fix weather toggle disabled when lat/lon set but weatherEnabled=false:
  now enabled whenever a weather location is configured
- Default task duration: no-endTime tasks default to 30min (not 60min)
- Tasks without a project: remove left border entirely — only project-
  assigned tasks show a colored left border; this matches the user's
  explicit request that only calendar events have background/indicators
- Header order: show date first (top), then weekday name below — matches
  webapp "above" date layout setting
- Lighten grid lines (#ececec) and stripes (#fafafa/#f0f7ff) to reduce
  the heavy calendar-grid appearance; remove half-hour separator lines
- Lighten outer grid border and time-column border/bg to match

v1.96.1
2026-04-13 12:41:15 +02:00
62ebc56c71 feat: fix PDF export style, add calendar events, add print button
- Query CachedCalendarEvent table for all-day and timed external calendar
  events (Google/MS/Apple), so GANZ-TAG strip now shows actual events
- Regular user tasks: remove white background — transparent with left
  border only, matching the webapp's simple view style
- All-day strip: calendar events show light tinted chip, user tasks show
  left-border text only (no fill background)
- Add 'Im Browser drucken / Print in Browser' button to the print modal
  (opens PDF inline in new tab so browser print dialog can be triggered)
- Fix Content-Disposition to 'inline' when ?inline=1 param is passed
- Update modal preview to show left-border task style (not solid blocks)

v1.96.0
2026-04-13 10:14:05 +02:00
8fb9e04346 fix: plain style for user tasks, colored boxes only for calendar events
Per webapp behavior: regular user tasks render as white background with a
thin colored left border (clean/minimal); external calendar events
(externalProvider != null) get a light tinted background box. Completed
tasks use a subtle gray style. The all-day strip keeps solid bars for all
entries (matching the webapp's ALL DAY section).

v1.95.5
2026-04-13 09:45:33 +02:00
da31128121 fix: match webapp style — solid task blocks, fix all-day events, tab-sorted someday
- Fix all-day events: remove externalProvider distinction — ALL tasks with
  scheduledDate but no startTime belong in the GANZ-TAG strip regardless of
  source; was incorrectly routing them to a separate noTime strip that didn't
  show external-provider=null events
- Remove noTime calendar strip: it was a wrong concept; tasks outside the
  time window are simply not shown; someday page handles unscheduled tasks
- Solid task blocks: revert from light+border back to solid fill (matching
  the webapp); use contrastColor() helper to pick white or dark text
  automatically based on background luminance
- All-day strip also uses solid blocks (same style as webapp's ALL DAY bars)
- Someday page: group lists by their tab with a tab header row; query now
  sorts by [tab, order]; lists without a tab get a General/Allgemein header
- Show up to 5 all-day tasks per column (was 4)

v1.95.4
2026-04-13 09:36:38 +02:00
3fd738b185 fix: restore full day names, fix Oswald font, add someday page to PDF
- Always use full weekday names (MONTAG, DIENSTAG…) at all column counts;
  adaptive font size 8.5pt–16pt based on number of columns
- Fix Oswald detection: Font.getRegisteredFontFamilies() doesn't exist in
  react-pdf — now use module-level _oswaldRegistered flag set on successful
  Font.register() call, so Oswald actually gets applied
- Fix headline fallback: Helvetica-Bold (not plain Helvetica) when no Oswald
- Increase strip heights: ALL_DAY_H 38→40, NO_TIME_H 28→52, DAY_HDR_H 40→44
- Show 4 tasks in both all-day and anyday strips (was 2/3)
- Add someday page: last page (portrait) with all SomedayList tasks grouped
  by list, shown when showNoTime is enabled

v1.95.3
2026-04-13 09:23:21 +02:00
786ccf6921 fix: improve PDF export layout and task block styling
- Separate all-day (external calendar events) from anyday (user tasks
  without time) using externalProvider field; each gets its own strip
- Increase ALL_DAY_H from 22→38px and add NO_TIME_H=28px so both rows
  are actually visible
- Task blocks switch from solid fill to light-tinted background + colored
  left border (Google Calendar style) — much easier to read in print
- Use user's taskColor setting as fallback instead of hardcoded indigo
- Show up to 3 items in all-day strip, 2 in anyday strip with overflow count
- GRID_H now accounts for both optional strips in height calculation

v1.95.2
2026-04-13 09:08:16 +02:00
72c51c2bea fix: use per-day-of-week colors in PDF export (weekday/sat/sun)
The PDF was showing all day headers in the same weekdayColor. The webapp
uses three separate color settings: weekdayColor (Mon–Fri), weekendColorSat,
and weekendColorSun. Fetch both weekend colors from DB and apply via
dayColor() helper based on d.getDay().

v1.95.1
2026-04-09 10:31:43 +02:00
f75bd6ebe5 feat: add week view PDF/print export with live preview
Adds a print/export modal (WeekPrintModal) accessible via a Printer icon
in the header toolbar. Users can configure date range, time window (startHour–endHour),
number of days, and toggle all-day, no-time, and weather sections. A live
CSS-grid preview updates as settings change. The PDF is generated server-side
via @react-pdf/renderer on the /api/user/export-week-view route:
- Landscape A4 with absolute-positioned time-spanning task blocks
- Day headers use the user's weekdayColor/dateColor/headlineFontWeight from DB
- Oswald font loaded dynamically from Google Fonts (falls back to Helvetica-Bold)
- Timezone-aware task grouping (±1 day query buffer + local date key)
- Optional weather line (Open-Meteo) and all-day strip
- Footer with date range, username, and page numbers

v1.95.0
2026-04-09 10:26:06 +02:00
9485e78dab feat: PDF work report export + Goal of the Week + weekGoal field
Added @react-pdf/renderer for server-side PDF generation.

PDF report (/api/user/export-pdf):
- Indigo cover band: title, user name, period, export date
- Summary cards: total tasks / calendar weeks / projects
- Per-week sections with indigo header bar showing week label + count
- Goal of the week banner (blue left-border callout) when set
- Task table: priority-color dot, title, then selected columns
- Alternating row shading, column headers in grey
- Page numbers in footer
- A4, respects same field selection as CSV

CSV report updated:
- Added 'Goal of the week' as a section marker row (italic prefix)
- weekGoal field is default-on alongside week grouping

Both exports:
- New 'weekGoal' field in EXPORT_FIELDS (default on): shows the weekly
  goal text only when the user has customised it (skips default placeholder)
- Language-aware (de/en) labels and date formats

Settings UI:
- Two download buttons: CSV (plain) + PDF (indigo, prominent)
- weekGoal checkbox in field picker grid

v1.93.0
2026-04-07 09:37:57 +02:00
51e2b13ec6 feat: configurable field picker for work report CSV export
Users can now choose exactly which columns appear in the CSV:
- Title (always included)
- Calendar week grouping header
- Completed date, Scheduled date, Created date
- Project, List
- Priority (Eisenhower label or ABCDE grade)
- Link / URL
- Notes, Description
- Delegated to, Delegation note
- Start time, Kanban stage

UI additions in Settings > Data Export:
- 2-column checkbox grid with Select All / Default reset buttons
- Quick date presets: This week / This month / Last month / This year
- Download button shows the active column count

Default-on fields: week, completed date, scheduled date,
project, list, priority. All others opt-in.

API: fields passed as comma-separated ?fields= param; falls back to
defaults when omitted. Column headers are language-aware (de/en).

v1.92.0
2026-04-07 09:27:02 +02:00
6836cf58bc feat: filters in all priority mode right columns + work report CSV
Priority View: filter panel (project / list / timespan) is now always
visible in the right column of every priority mode — Eisenhower,
ABCDE, Ivy Lee, and 80/20. Removed the collapse toggle. An 'active'
indicator in the header shows when any filter is set. On mobile the
filter appears above the main content.

Work Report CSV (Settings > Data Export):
- Columns: Week / Completed / Scheduled / Created / Task / Project /
  List / Priority / Delegated to / Notes
- Rows grouped by calendar week (ISO week, most recent first), with a
  section header row showing "KW 14 — 2026 (30 Mär – 05 Apr)"
- Priority shows Eisenhower label (Sofort erledigen / Planen /
  Delegieren / Eliminieren) or ABCDE grade
- Includes project name, Someday list name, delegation info and notes
- UTF-8 BOM prepended so Excel opens German umlauts correctly
- Language-aware column headers (de/en) via ?lang= param
- Filename: arbeitsbericht_YYYY-MM-DD_bis_YYYY-MM-DD_date.csv

v1.91.0
2026-04-07 00:03:09 +02:00
0a84bf3114 feat: preserve tabs on sync disconnect/reconnect
Disconnecting a synced list (Google/Outlook/Synology) now uses a
soft-disconnect: tasks are soft-deleted and the external link is
cleared, but the SomedayList record is kept with its tab assignment
intact. When the user reconnects, the import route finds the list by
title, re-links the external provider, and restores tasks (clearing
deletedAt). Tabs survive the full disconnect/reconnect cycle without
the user needing to drag lists back to tabs.

Also clears deletedAt on task re-import so previously disconnected
tasks become visible again on reconnect.

v1.89.0
2026-04-06 18:07:03 +02:00
8ffc127671 fix: improve import — surface real errors, restore all task fields
- Export now includes kanbanStage, url, urgency, importance, priority,
  delegatedTo, delegationNote, recurrenceDays so backups are complete
- Import now handles those same fields (round-trip fidelity)
- Error handler returns the actual error message instead of the generic
  "Import failed. Please check the file format." — makes failures diagnosable
- Guard against empty task title with fallback '(untitled)'

v1.87.2
2026-04-06 11:42:21 +02:00
46a05a87c3 feat: add Priority View — Eisenhower, ABCDE, Ivy Lee, Pareto, delegation
New "Priority View" (Target icon in toolbar) fusing four prioritization
frameworks into a single, filterable view:

- Eisenhower Matrix: 4 quadrants (Do/Schedule/Delegate/Delete) based on
  urgency × importance; unclassified tasks shown below for quick assignment
- ABCDE Method: five collapsible groups (A=Critical → E=Eliminate) with
  inline grade assignment buttons
- Ivy Lee Method: pick exactly 6 tasks for tomorrow, ordered by priority
- Pareto 80/20: highlights the important 20% of tasks with a progress bar
  and one-click "mark as important" for the rest

New DB fields: urgency (Boolean), importance (Boolean), priority (A–E),
delegatedTo, delegationNote — all persisted via Prisma + API.

Filters: by project, someday list (incl. scheduled / unscheduled), and
timespan (today / this week / next week / all).

Delegation modal: assign to a named person or to AI with optional
instruction notes; displayed as inline badge on task cards.

v1.87.0
2026-04-06 02:07:05 +02:00
04b72a326a feat: integrate zitat-service.de API for DE/EN/ES quotes
- Add zitat-service.de as built-in multilingual fallback in goal API:
  tries the user's preferred language (de/en/es) automatically before
  falling back to ZenQuotes (EN) and then local curated quotes
- Parser now also handles {quote, authorName} response format from
  zitat-service.de alongside all previously supported formats
- Preset source pills in settings: add Zitat-Service (DE), (EN), (ES)
  (supports de, en, es — no fr/it available from that API)
- Remove Forismatic from presets (unreliable, often returns empty)
- Update hint text to reflect DE/EN/ES API availability vs FR/IT local

v1.84.1
2026-04-05 18:08:05 +02:00
2ec1278b19 feat: quote sources — preset buttons, universal parser, expanded local collection
Goal API (route.ts):
- Now actually uses profile.quoteSourceUrls — tries each user-configured URL
  in order before falling back to ZenQuotes
- Universal JSON parser handles ZenQuotes [{q,a}], Quotable {content,author},
  Forismatic {quoteText,quoteAuthor}, generic {text/quote/body, author/by},
  nested {data:{...}}, and advice-slip {slip:{advice}} formats
- ZenQuotes remains the built-in EN fallback when no user URLs are configured

SettingsSidebar:
- Adds clickable preset-source pill buttons below the "Add source" button:
  ZenQuotes, Stoic Quotes, Quotable, Forismatic (EN), Advice Slip
- Pills show ✓ and are disabled when the URL is already in the list
- Note explains DE/FR/IT/ES are served from the curated local collection

quotes.ts:
- Updated PRESET_QUOTE_SOURCES to match the 5 working English APIs
- +14 French quotes (Marcus Aurelius, Lombardi, Ali, MLK, Picasso, etc.)
- +13 Spanish quotes (Collier, Eliot, Darwin, Voltaire, Ashe, etc.)
- +13 Italian quotes (Collier, Eliot, Ali, MLK, Aurelius, da Vinci, etc.)

v1.84.0
2026-04-05 12:50:46 +02:00
a6a1a68c73 feat: upgrade notes/url to full sidebar+kanban coverage, fix onNotes save bug, harden URL sanitization
- Fix onNotes prop in all three TaskItem render sites: was calling
  setSelectedTaskForNotes (ignoring HTML), now correctly calls
  updateTaskNotes so inline RichTextEditor saves on every change
- NotesSidebar: replace plain markdown textarea+toolbar with RichTextEditor;
  add URL field with open/clear actions
- Kanban detail modal: add URL field; replace plain textarea with RichTextEditor
- Tasks API: add sanitizeUrl() helper — strips javascript:/data: schemes,
  normalises missing protocol to https:// before storing
- Remove dead code in TaskItem: notesRef, handleNotesBlur, insertMarkdown
  (all replaced by RichTextEditor)

v1.83.0
2026-04-05 11:59:44 +02:00
7bc43d3c98 feat: add hyperlink support to tasks
Option A — URL field per task:
- New url String? column in Task schema (migration: 20260403_add_task_url)
- Link icon button in GridTaskBlock action bar; click to open inline URL popup
  with input, clear (×) button, and open-in-new-tab shortcut
- Blue link indicator shown inline on the task card when a URL is set
- updateTaskUrl() in WeeklyView persists to DB via PATCH /api/tasks

Option B — Rich text notes with inline hyperlinks:
- GridTaskBlock notes popup upgraded from plain markdown textarea to
  RichTextEditor (Tiptap), which already has bold/italic/underline/
  bullet/blockquote/link toolbar and full link support
- Notes now save on every change via onChange (no blur required)

v1.82.0
2026-04-03 15:04:44 +02:00
f94f83af73 fix: restore project icons and persist someday tab assignments across reconnects
Project icons (faHeart, faBriefcase etc.) were rendering as literal text in
GridTaskBlock because the lookup skipped the legacy "faX" → "x" normalization
that ProjectIcon does. Added the same normalization before allIcons.find().

Someday list tabs now survive provider disconnects and reconnects:
- customTabs (empty tabs) saved to viewSettings in DB instead of localStorage only
- assignListToTab saves a title→tab mapping in viewSettings.somedayTabPrefs
- Profile load merges DB customTabs with localStorage for migration
- Import route reads somedayTabPrefs and auto-applies tab when creating/
  relinking a SomedayList by title match

v1.81.20
2026-04-03 11:11:11 +02:00
0371532e7d fix: resolve stale session ID in someday-lists and calendar/events routes
All handlers in someday-lists/route.ts and calendar/events/route.ts were
using (session.user as any).id which can be stale after DB restore/migration.
Fixed to look up by session.user.email instead — matching the pattern already
established in tasks/route.ts and calendar/sync/route.ts.

This was causing other users to see empty someday lists while their tasks
(fetched via the already-fixed tasks route) still had somedayListId references,
triggering false RESCUE recoveries on every load.

Also fixed outlook/callback/route.ts fallback which could still use stale ID.

v1.81.19
2026-04-03 11:04:32 +02:00
09caf5ffa0 fix: email-based user lookup, slot controls, sub-hour toggle
API routes (goal, weather, calendar/sync, calendar/events):
- All user lookups now use session email instead of session ID so stale
  JWTs after DB restore/migration no longer break requests (P2003 FK error)

WeeklyView QuickSettings sidebar:
- effectiveCellDuration now uses local cellDuration state as fallback
  instead of stale profile.cellDuration — slot buttons now actually update
  the time grid
- Added 20m slot option to all three button groups (sidebar, header, mobile)
- Added :15/:30/:45 sub-hour slots toggle to QuickSettings sidebar
- Slot controls now highlight using effectiveCellDuration (per-view aware)
- Someday and All-day toggles now use effective value, not global profile

v1.81.15
2026-04-02 22:34:26 +02:00
2d785ea2bf fix: suppress weather 400 noise, calendar sync email fallback
- Weather API returns empty hourly data (200) when lat/lon not configured,
  matching the 502 fix — no more browser console errors for weather
- Calendar sync route falls back to email lookup when session user ID
  doesn't match a DB record (handles stale JWT after DB restore/migration)

v1.81.14
2026-04-02 13:24:18 +02:00
86c462c920 fix: all-day label top-aligned, weather 502 silent, toggle consistency
- All-day label column uses flex-start so label is visible in small area
- Weather API returns empty data (200) instead of 502 when forecast range
  is out of bounds, suppressing console noise on future/past navigation
- QuickSettings toggles for project icons and checkboxes now use effective
  (per-view-aware) value, consistent with other toggles

v1.81.13
2026-04-02 13:10:25 +02:00
b7954f9367 fix: add showProjectIcons and weekStartDay to Prisma schema + route
Both fields existed in the DB but were missing from schema.prisma,
so the Prisma client didn't know about them. The client has been
regenerated (prisma db push). Added both fields to:
- prisma/schema.prisma (with correct defaults)
- GET select, PATCH destructure, updateData, PATCH select in route.ts

This resolves the 500 errors on PATCH /api/user/profile that occurred
when saveSetting() tried to persist these fields.

v1.81.8
2026-04-02 10:15:49 +02:00
e800d87235 feat: overhaul header display options with mobile portrait/landscape settings
- Rename options to be clearer:
  - "Vollständiges Datum" → "Heutiges Datum" (always today's date)
  - "Aktueller Tag" → "Selektierter Tag" with custom format input
  - "Benutzerdefiniert" → "Woche Benutzerdefiniert" (week-based tokens)
- Add custom format input for "Selektierter Tag" (headerCurrentDayFormat)
  with tokens: DDDD, DDD, DD, MMMM, MMM, MM, YYYY, WW
- Add separate header display settings for Mobile Portrait and
  Mobile Landscape (mobilePortraitHeaderDisplay, mobileLandscapeHeaderDisplay)
- Move refresh/sync icon to fixed-width slot right of date — date no
  longer shifts when the icon appears or the spinner replaces it
- Add 3 new Prisma fields (db push required on deploy)
- All 5 languages updated (EN, DE, FR, ES, IT)

v1.81.0
2026-03-31 09:14:16 +02:00
6fed38381c perf: limit recurring task projection + O(1) calendar event dedup
- tasks/route.ts: add per-unit instance cap for virtual task projection
  (daily: 60, weekly: 26, monthly: 12, yearly: 3) to prevent unbounded
  generation from high-frequency recurring tasks
- WeeklyView: extract calendarEditabilityMap as a separate useMemo keyed
  on connections; replace O(n²) nested find() loop with O(1) Map.get()
  lookup in the calendarEvents deduplication useMemo

v1.79.0
2026-03-30 16:02:56 +02:00
6e8ed34578 perf: batch sync DB lookups, fix calendar cache race, lazy-load IconPicker
- tasks/sync GET: batch Google/Outlook/Synology credential fetches with
  Promise.all instead of sequential awaits; move per-list Synology
  findMany outside the loop to eliminate N+1
- calendar/sync: replace fire-and-forget background refresh with 800ms
  Promise.race so fast refreshes return fresh data without blocking
- Extract icon data to iconRegistry.ts; lazy-load IconPicker via
  next/dynamic so picker UI code is deferred until needed

v1.78.0
2026-03-30 15:54:12 +02:00
620118e6d5 feat: add cross-provider calendar sync tool
Users can now create sync rules to automatically sync events between
any two connected calendar providers (Google, Apple, Outlook, Synology).

- New Prisma models: CalendarSyncRule + CalendarSyncMapping
- Sync engine in src/lib/calendar-cross-sync.ts: fingerprint-based
  change detection, anti-loop protection, one-way and two-way support
- API routes: GET/POST rules, PATCH/DELETE rule by id, POST run
- CalendarSyncRulesPanel component with rule list, add/edit form,
  toggle enable/disable, Sync Now button with result summary
- New "Sync" tab in settings sidebar (between Connections and Account)
- Sync rules run automatically after each forced calendar cache refresh

v1.76.0
2026-03-29 10:58:07 +02:00
e1190a8fe6 fix: attach calendar color to created/updated events for cache + frontend
Events created or updated via the API were missing the calendar's
backgroundColor, causing them to render without their provider color.

v1.72.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 02:10:11 +01:00
74a8c9a9a9 feat: recurring event edit confirmation (this event / all events)
When editing a recurring calendar event (via modal or drag/resize),
the user is now asked whether changes apply to just this instance or
all events in the series.

- Modal: Save button shows "This event" / "All events" options for
  recurring events
- Drag/resize: centered overlay prompt with same options + cancel
- API PATCH: editMode=all routes update to the series master ID
  (recurringEventId) instead of the instance ID
- Cancel on drag prompt reverts to original position

v1.69.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 12:41:21 +01:00
13bd90bd2a fix: cross-day drag-and-drop + persist showCalendarProviderIcon setting
- Cross-day drag now works: getEventsForSlot uses drag state's current
  start time to assign the dragged event to the correct day column
- Add showCalendarProviderIcon to Prisma schema, profile API GET/PATCH
  so the setting persists across sessions (was frontend-only before)
- DB migration applied via prisma db push

v1.68.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 12:30:42 +01:00
57eeb3d8e8 feat: recurring event delete options (this/future/all instances)
When deleting a recurring calendar event, users now choose between
deleting just this instance, this and future instances, or all instances.
Supports Google, Apple (iCloud), and Synology CalDAV providers.

v1.62.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 22:06:23 +01:00
1011aef639 fix: recurring event DST time shift and block height overflow
- Use TZID-based local time (instead of UTC 'Z') for DTSTART/DTEND
  when creating recurring CalDAV events, preventing DST-related time
  shifts (e.g. 13:40 CET showing as 14:40 CEST after clock change)
- Send browser timezone from CalendarEventModal to server
- Guard against NaN event duration (missing/invalid endTime) which
  caused event blocks to stretch to end of day

v1.61.1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 21:23:24 +01:00
c5dc315f82 feat: sync calendar colors from all providers and add custom recurrence
- Store calendar colors (backgroundColor) from Apple and Synology
  during connection setup
- Auto-refresh missing colors for existing Apple/Synology connections
- Show color dots next to calendar names in settings
- Add "Custom..." recurrence option with interval (every N days/weeks/
  months/years) and day-of-week selection for weekly recurrence
- Generate proper RRULE with INTERVAL and BYDAY for all providers
- Generate proper Outlook Graph recurrence with custom intervals

v1.61.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:35:22 +01:00
1ab98025a6 feat: add Outlook calendar colors and recurrence end date/count
- Fetch and display Outlook calendar colors from Microsoft Graph API
  instead of hardcoded blue
- Add recurrence end options to calendar event modal: Never, On Date
  (UNTIL), or After X occurrences (COUNT)
- Pass recurrence end parameters through to RRULE generation for all
  providers (Google, Apple, Synology, Outlook)

v1.60.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:14:13 +01:00
8402adbd45 fix: always full-fetch Google Tasks for linked someday lists
The updatedMin optimization skipped tasks that were missed during
initial sync. Now does a full fetch when a someday list is linked,
ensuring all remote tasks are discovered.

v1.57.13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 01:35:56 +01:00
a009a4953a fix: paginate task sync and unblock connections endpoint
- Google Tasks and Microsoft To-Do sync now paginate through all
  results instead of capping at 100 tasks per list.
- Synology calendar pruning in GET /connections is now fire-and-forget
  so a slow/unreachable NAS doesn't block the entire response.

v1.57.12

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 01:11:23 +01:00
9e7266053b fix: clean up someday lists and tasks when disconnecting a calendar provider
Unlink external references (externalId, externalProvider, externalListId)
from someday lists and tasks when their associated calendar connection
is deleted, so orphaned entries don't persist in the UI.

v1.57.8

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 00:21:16 +01:00
af46c0c21f chore: add debug logging for Synology calendar pruning
Log individual calendar names/URLs from server and stale calendar IDs
to diagnose why deleted calendars persist in stored list.

v1.57.5

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 23:54:08 +01:00
87d78d78b5 fix: handle deleted Google Tasks lists gracefully (404 cleanup)
When a Google Tasks list returns 404 during sync, soft-delete all local
tasks linked to it and unlink the synced someday list instead of spamming
error logs.

v1.57.3

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 23:02:16 +01:00
ba19482a41 fix: prune deleted Synology calendars from settings list
When loading calendar connections, the API now fetches the live calendar
list from Synology and removes entries that no longer exist on the server.

v1.57.2

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 22:48:06 +01:00
ee4b540558 feat: add Notion provider integration + Apple Reminders deprecation note
- Notion OAuth integration: start/callback routes, calendar-events dispatch,
  CRUD operations (create/update/delete via Notion API)
- New notion-calendar.ts provider library with database discovery
- Onboarding wizard: expanded to 6 steps (header/tasks/display design),
  improved preview fidelity, universal dummy content, Notion in connect step
- Apple Calendar: label changed to "events only", added warning that
  Reminders are unsupported since iOS 13 (no CalDAV/API from Apple)
- Fixed 12h time format on now-line, wizard settings apply on completion

v1.57.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 21:02:25 +01:00
4ac73d3e03 feat: onboarding wizard for first-time users + UI fixes
- 6-step onboarding wizard (welcome, language, connect providers,
  view style, work hours, styling) for new signups
- Added hasCompletedOnboarding field to User schema
- Fixed subtask progress bar in GridTaskBlock (simple/calendar views)
- Fixed kanban drag-and-drop to someday area
- Fixed weather/provider icon overlap in time grid tasks
- Provider icon positioning: inline when weather on, top-right when off

v1.56.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 13:52:29 +01:00
bce86aeb9b feat: kanban task creation and Google Tasks API quota optimization
Add inline task creation in kanban view columns - creates tasks in a
"Kanban" someday list (or project-named list if filtered by project).
Optimize Google Tasks sync: use updatedMin to fetch only changed tasks,
increase sync interval to 5min, handle 429 quota errors gracefully.

v1.54.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 19:28:15 +01:00
876bd1047b feat: real-time sync across devices via Server-Sent Events
Adds SSE-based push notifications so changes made on one device
appear instantly on all other connected devices for the same user.

- SSE notification hub (src/lib/sse.ts) with per-user client tracking
- Stream endpoint (/api/events/stream) with 30s heartbeat
- Task and list API routes notify connected clients on mutations
- Client auto-connects with 5s reconnect on connection loss
- Existing 2-minute polling sync remains as fallback

v1.53.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 07:44:00 +01:00