Commit Graph

221 Commits

Author SHA1 Message Date
ulsklyc 1629356a6d fix: add missing submit button to CalDAV and CardDAV add account modals (#130)
The onSave callback was being executed immediately on modal open (its
purpose is to wire up event listeners), causing the required-fields
error to appear instantly and leaving the form with no way to submit.

Both forms now include modal-actions buttons in the content HTML, and
onSave correctly attaches a submit event listener instead of running
validation directly.

Fixes #128

Co-authored-by: Ulas Kalayci <ulas.kalayci@googlemail.com>
2026-05-06 10:37:35 +02:00
Ulas Kalayci 2a48fb7af0 feat: multi-person assignment for tasks and calendar events
- DB migration v32: task_assignments and event_assignments join tables
  with CASCADE delete; existing assigned_to data migrated automatically
- Tasks API: accepts assigned_to as array, returns assigned_users[]
  with json_group_array; filter uses EXISTS on task_assignments
- Calendar API: same pattern via event_assignments; serializeEvent
  includes assigned_users array
- Recurring task completion copies all assignments to the new instance
- Frontend: shared UserMultiSelect component with avatar stack display
  (renderAvatarStack, renderUserMultiSelect, getSelectedUserIds,
  bindUserMultiSelect); tasks.js and calendar.js use it in modals
  and card/agenda views
- CSS: user-multi-select.css with avatar-stack and user-ms classes
- 14 new tests covering CRUD, JSON aggregation, EXISTS filter,
  and CASCADE behavior for both task and event assignments

Closes #125
2026-05-06 10:04:41 +02:00
Ulas Kalayci c4cb52d042 feat(nav): shared sub-tabs component for settings and kitchen
Extracts the tab-bar UI into a reusable renderSubTabs() utility
(public/utils/sub-tabs.js + public/styles/sub-tabs.css) so all
sub-module navigation shares one implementation and visual style.

- Settings: replaces template-literal <nav class="settings-tabs">
  with renderSubTabs(); tabs now show icon + label (pill-style),
  group separators via separatorBefore, panel switching via onChange
- Kitchen: renderKitchenTabsBar() becomes a thin wrapper around
  renderSubTabs(); kitchen-tabs.css keeps only layout adjustment rules
- CSS: kitchen-tab* rules removed from kitchen-tabs.css,
  settings-tab-btn* rules removed from settings.css; both now
  inherit from sub-tabs.css
- tokens.css: adds --sub-tabs-height (52px default;
  kitchen overrides to --kitchen-tabs-height: 56px)
- test-browser-loader.mjs: resolves browser-absolute /utils/*.js
  imports to public/ directory for Node test compatibility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 07:33:54 +02:00
Ulas Kalayci c465713418 refactor(settings): prioritize CalDAV/CardDAV in sync tab, fix heading hierarchy
Open standards (CalDAV, CardDAV, ICS) now appear first in the Sync tab
under a dedicated "CalDAV & CardDAV" section, making self-hosted sync
options prominent. Cloud services (Google, Apple) move to a secondary
"Cloud-Dienste" section. Fixes raw <h2> heading in CalDAV card — now
uses consistent settings-card__title like all other cards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 07:22:39 +02:00
Ulas Kalayci b545d83f64 fix: modal onClose callback, calendar popup truncation, datetime validation
- modal.js: add onClose callback to openModal(), fix _initialFormTimeout
  cleanup, deduplicate escape/overlay-click handlers in confirmModal,
  promptModal, selectModal using the new callback
- calendar.js: replace popup.innerHTML with insertAdjacentHTML (constraint),
  add truncateDescription() to cap long event descriptions at 500 chars
- validate.js: extend DATETIME_RE to cover ISO 8601 with ms/timezone,
  normalise datetime values to YYYY-MM-DDTHH:MM on input
- index.js: include app version in startup log message
- docker-compose.yml / .env.example: switch from named volume to
  host-mounted DATA_DIR/BACKUP_DIR with sane defaults
- docs/installation.md: document host-mount data paths

Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-06 07:00:07 +02:00
Ulas Kalayci 289b079f47 chore: bump version to 0.47.2
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-05 07:06:29 +02:00
Ulas Kalayci bc61311ebc fix(settings): resolve scope error for CalDAV/CardDAV load functions
Root cause: loadCalDAVAccounts and loadCardDAVAccounts were defined
inside the render function but called from bindIcsEvents (outside render),
causing ReferenceError when accessing Settings page.

Changes:
- Move loadCalDAVAccounts and loadCardDAVAccounts to top-level functions
- Add user parameter to both functions (no longer in render scope)
- Update all recursive calls to pass user parameter
- Move initial load code from bindIcsEvents to render function

Fixes the "loadCalDAVAccounts is not defined" error in v0.47.0.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-04 22:27:48 +02:00
Ulas Kalayci 6cdef0102c feat(settings): add dedicated Sync tab with CardDAV contacts integration
- Rename Calendar tab to Synchronization with two sections:
  * Calendar Sync (Google, Apple, CalDAV, ICS)
  * Contact Sync (CardDAV) - NEW
- Add visual tab grouping with CSS separators between sections
- Implement CardDAV account management UI:
  * Add/delete accounts
  * Enable/disable addressbooks
  * Manual sync trigger
  * Connection testing
- Add UX improvements:
  * Status badges (success/error/syncing)
  * Empty states with onboarding
  * Inline help tooltips (prepared)
  * Breadcrumb navigation (prepared)
- Update i18n keys in all 14 locales
- All 109 tests passing

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-04 21:50:59 +02:00
Ulas Kalayci 82a1f2c239 feat: add flexible reminder options for birthdays
Add support for customizable birthday reminders with preset offsets
(none, at time, 15min, 1h, 1d, 2d, 1w, 2w) and custom intervals.
Users can now configure when to be reminded of upcoming birthdays.

- Add migration 31: reminder_offset, reminder_custom_amount, reminder_custom_unit to birthdays table
- Update POST/PUT /birthdays routes to accept reminder fields
- Add getOffsetMinutes() helper in birthday service
- Update birthdayReminderAt() to calculate reminder time with offset
- Modify syncBirthdayReminder() to handle empty offset (no reminder)
- Add renderBirthdayReminderSection() UI component
- Move reminder-custom CSS from calendar.css to reminders.css
- Add protocol check to service worker (non-http protocol guard)

All translations already present in de.json.
Tests: 109 passing, 0 failing.

Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-04 20:31:42 +02:00
Ulas Kalayci 3c9b2840e7 feat(caldav): add Settings UI and Event Modal CalDAV target selection
- Add CalDAV accounts card to Settings page with:
  * List of configured accounts showing URL and last sync
  * Expandable calendar list with enable/disable checkboxes
  * Sync Now, Refresh Calendars, and Delete actions per account
  * Add Account modal with name, URL, username, password fields
- Add CalDAV target selector to event modal:
  * Dropdown showing local and all enabled CalDAV calendars
  * Grouped by account using optgroups
  * Pre-selects current target when editing events
  * Includes target_caldav_account_id and target_caldav_calendar_url in save
- Add CalDAV component styles to settings.css:
  * Account cards with header, meta, and action sections
  * Expandable calendar details with checkboxes and color dots
  * Empty state for no accounts
- Add missing i18n keys for calendar enable/disable, refresh, delete confirm
- Load CalDAV targets async when modal opens
- Admin-only access to account management

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 08:41:02 +02:00
Ulas Kalayci 9b29d1847c feat: automatische geplante Backups mit Rotation
Phase 1.3 - Automatische Backups:
- Cron-basierter Scheduler (Standard: täglich 2 Uhr)
- Konfigurierbar über .env (Zeitplan, Verzeichnis, Anzahl)
- Automatische Rotation: behält nur letzte N Backups (Standard: 7)
- UI in Settings → Backup: Status-Anzeige und manueller Trigger
- Tests: 7 erfolgreiche Tests für Scheduler-Funktionalität

Neue Umgebungsvariablen:
- BACKUP_ENABLED (Standard: true)
- BACKUP_SCHEDULE (Standard: 0 2 * * *)
- BACKUP_DIR (Standard: ./backups)
- BACKUP_KEEP (Standard: 7)
- TZ (für Zeitzone)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 07:02:38 +02:00
Ulas Kalayci 99a2280c02 chore: release v0.42.0
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-04 06:52:35 +02:00
Ulas Kalayci 6eae4bae24 chore: release v0.41.0 2026-05-01 18:40:24 +02:00
Ulas Kalayci d61bdab65d Merge origin/main into improvement-dashboard-customization
Resolve sv.json conflict: take Swedish subcategory translations from
main and loan keys from PR branch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 17:42:23 +02:00
Ulas Kalayci f3dbbb37d7 fix: preserve dmy=DD.MM.YYYY, add dmy_slash for DD/MM/YYYY
The PR changed dmy from dots to slashes, breaking existing users.
Revert dmy to dots (backward compat), add dmy_slash for DD/MM/YYYY.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 15:28:18 +02:00
Rafael Foster 2b4f7352ed Refactor widget size selector to show only numeric dimensions 2026-05-01 09:18:44 -03:00
Rafael Foster f5377bd2f1 Improve dashboard widget sizing controls 2026-05-01 09:05:20 -03:00
Rafael Foster 9c5f8c9a99 Add dashboard widget customization 2026-05-01 08:53:25 -03:00
Rafael Foster e34ba33f9b Refine loan tab filtering and date formats 2026-05-01 08:24:39 -03:00
Rafael Foster 79f55cbfbc Improve loan dashboard interactions 2026-05-01 08:09:12 -03:00
Rafael Foster 977bee8a3a Separate budget and loan views 2026-05-01 07:52:43 -03:00
Ulas Kalayci 2588cc43f1 chore: release v0.39.2 2026-05-01 09:46:54 +02:00
Rafael Foster 9a80b785c8 Refine budget loan entry flow 2026-04-30 23:20:25 -03:00
Rafael Foster ce107c80a4 Add budget loan tracking 2026-04-30 23:12:38 -03:00
Ulas Kalayci e59a9818a9 fix(i18n): add time format translations to all 13 missing locales
Also translate server error message to English and remove stale
comment from calendar.js catch block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 19:54:12 +02:00
Rafael Foster 8c9a5c6aa2 feat(settings): add time format preference 2026-04-30 13:48:35 -03:00
Rafael Foster f1050e1fdb Merge branch 'main' of github.com:rafaelfoster/oikos 2026-04-30 13:44:58 -03:00
Rafael Foster 04aa5f5527 feat(calendar): remember last selected view 2026-04-30 13:40:11 -03:00
Ulas Kalayci edd8d0889d ux: accent glow on quick-add input after successful item add 2026-04-30 09:13:48 +02:00
Ulas Kalayci 6e40ba89df fix(calendar): zeige korrekte Fehlermeldung bei zu großem Anhang; nutze --module-accent statt --module-calendar im Dropzone-CSS
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 07:15:14 +02:00
Rafael Foster 4aa9bc2a48 fix(calendar): tighten modal and attachment rendering 2026-04-29 22:44:25 -03:00
Ulas Kalayci 3f69c7c698 chore: release v0.36.0 2026-04-29 21:15:26 +02:00
Rafael Foster 3b93cf0643 Merge branch 'ulsklyc:main' into main 2026-04-29 15:30:32 -03:00
Ulas Kalayci dcc87f02d8 fix: kitchen tabs bar cleared by second container.innerHTML in shopping.js 2026-04-29 20:14:30 +02:00
Ulas Kalayci 88778a95c9 feat: integrate kitchen tabs bar into meals, recipes, shopping 2026-04-29 19:56:41 +02:00
Rafael Foster f44d018d5c fix(docs): restore backups without helper script 2026-04-29 14:35:59 -03:00
Rafael Foster a31865beef fix(docs): simplify docker restore command 2026-04-29 14:26:58 -03:00
Rafael Foster 7d02ac6c18 fix(settings): guard backup binding during cache updates 2026-04-29 14:07:21 -03:00
Rafael Foster 0cbd93e4e0 feat(settings): add database backup management 2026-04-29 14:04:04 -03:00
Ulas Kalayci ab30c2ab35 feat: overlapping event layout and calendar event attachments (#107)
- Overlapping timed events in week/day views now render side-by-side using a column-layout algorithm
- Calendar events support optional file attachments (images, PDFs, documents up to 5 MB)
- Attachment images shown in event popup; other files as download links
- Birthday modal redesigned with photo/avatar side-by-side with name/date fields
- DB migration 27: adds attachment_name, attachment_mime, attachment_size, attachment_data columns to calendar_events
- Server-side MIME allowlist and size validation for attachments
- i18n: all 15 locales include new attachment keys (de properly translated)

Co-Authored-By: Rafael Foster <rafaelfoster@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 16:54:02 +02:00
Ulas Kalayci 3fc95da48f fix: innerHTML violations, German translations, and PT diacritics
- Replace innerHTML with replaceChildren/insertAdjacentHTML in birthdays.js and calendar.js (hook compliance)
- Translate calendar attachment i18n keys to German in de.json
- Fix missing diacritical marks in pt.json attachment strings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 16:53:45 +02:00
Ulas Kalayci 593ca9009e feat: visual hierarchy in dashboard — primary widgets (tasks, calendar) span 2 columns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-29 16:42:09 +02:00
Rafael Foster d9218a4941 feat(calendar): add overlapping layout and event attachments 2026-04-29 08:53:07 -03:00
Rafael Foster f1ac3c29f0 Merge branch 'main' of github.com:rafaelfoster/oikos 2026-04-29 07:21:18 -03:00
Rafael Foster 36913faf8d fix(birthdays): anchor photo action buttons under avatar 2026-04-29 07:11:34 -03:00
Rafael Foster 3e0549524e fix(birthdays): match profile picture editor pattern 2026-04-29 07:09:37 -03:00
Rafael Foster 1ca8110d56 fix(documents): improve upload modal and document theme 2026-04-29 06:27:37 -03:00
Rafael Foster 72fca92066 feat(documents): add family document management 2026-04-29 06:14:29 -03:00
Rafael Foster 6eafe80395 feat(tasks): add archive button in list cards 2026-04-29 05:51:52 -03:00
Rafael Foster 6028c4562a Merge branch 'main' of github.com:rafaelfoster/oikos 2026-04-29 05:48:27 -03:00