Commit Graph

96 Commits

Author SHA1 Message Date
Ulas Kalayci e92487f464 feat: add FAB to meals page for quick meal creation (#62) 2026-04-20 10:15:04 +02:00
Ulas Kalayci 30d3d6cd13 fix: theme reverts to light on reload when system preference stored (#61) 2026-04-20 10:08:07 +02:00
Ulas Kalayci e48d249fbe chore: release v0.20.24
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 10:05:12 +02:00
Ulas Kalayci aae895d704 feat: filter panel + english category keys
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:50:55 +02:00
Ulas Kalayci b867917995 feat: kanban touch drag, swipe undo, dashboard task deep-link
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 09:44:50 +02:00
Ulas Kalayci c8e20b22c8 chore: release v0.20.21
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 07:36:07 +02:00
Ulas Kalayci 87be39364d chore: release v0.20.20
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 07:17:30 +02:00
Ulas Kalayci 40fc080c3a chore: release v0.20.19 2026-04-20 07:09:07 +02:00
Ulas Kalayci 51fcac3cfe chore: release v0.20.18
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 06:56:51 +02:00
Ulas Kalayci 18c90653d4 refactor: dark-mode token deduplication via private-variable indirection (v0.20.17)
All tokens with dark-mode overrides gain a private --_name counterpart in :root.
Public tokens (--color-*, --module-*, --glass-* etc.) become stable var(--_name)
references. Both dark blocks now only override compact private tokens — no more
manual two-block sync for every future colour change.

Also removes the redundant --color-surface-2 dark override (already auto-derived
via var(--neutral-50)). No visual change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 06:53:08 +02:00
Ulas Kalayci c567ff17e4 chore: release v0.20.15 — colour redesign + nav-badge visibility fix
Bundles the Indigo accent migration, module-colour decoupling, WCAG
contrast improvements and nav-badge base-style relocation into one
release. See CHANGELOG.md [0.20.15] for full details.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:16:07 +02:00
Ulas Kalayci 39fd25eafc fix: tasks filters not applied on tab re-entry (closes #49)
render() always fetched /tasks without query params, so active filter
chips appeared selected but all tasks were shown after navigating away
and back. Fixed by building the same filter query in render() that
loadTasks() uses, keeping both parallel fetches and correct filtering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 07:23:46 +02:00
Ulas Kalayci 3c2a2fe6e9 fix: resolve modal header scroll-behind issue on iOS PWA (closes #50)
position: sticky on .modal-panel__header failed on iOS WebKit when the
scroll container had padding-top applied (drag-handle spacing). Restructured
modal layout: .modal-panel is now a flex-column with overflow:hidden and
.modal-panel__body handles scrolling (overflow-y:auto, flex:1). The header
is a non-scrolled flex sibling, so it stays visible without sticky. Updated
swipe-to-close to read .modal-panel__body scroll position.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 07:19:42 +02:00
Ulas Kalayci 6fee35d1d9 chore: upgrade Express 4 → 5 and fix wildcard route for path-to-regexp v8 (closes #54)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 22:23:57 +02:00
Ulas Kalayci 6746a5a175 feat: Ukrainian translation, UAH currency, shopping category i18n (closes #52)
- Add Ukrainian (uk) locale to SUPPORTED_LOCALES and locale picker
- Add public/locales/uk.json (622 keys, full Ukrainian translation)
- Add UAH (Ukrainian Hryvnia) to SUPPORTED_CURRENCIES and VALID_CURRENCIES
- Add CATEGORY_I18N map and catLabel() in settings.js to translate default
  shopping category names in the settings panel; rename and delete dialogs
  now also use the translated name instead of the raw German DB string
- Align server VALID_CURRENCIES with frontend: add missing AED, BRL, INR, SAR

Co-Authored-By: baragoon <baragoon@users.noreply.github.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 22:09:42 +02:00
Ulas Kalayci 4aca9f4189 chore: update dependencies and add Dependabot (closes #53)
- better-sqlite3 9 → 12 (Node.js ≥22 required, already enforced)
- dotenv 16 → 17 (minor: logging now enabled by default)
- express-rate-limit 7 → 8 (IPv6 /56 subnet grouping, no deprecated options used)
- express-session 1.18 → 1.19
- helmet 8.0 → 8.1
- googleapis 144 → 171
- tsdav 2.0 → 2.1
- Add .github/dependabot.yml for automated weekly npm updates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 19:30:25 +02:00
Ulas 21c1ea1dca chore: bump version to 0.20.7 2026-04-16 16:12:43 +02:00
Ulas 5bd80b1333 fix: reduce page transition lag on Android (closes #48)
Two causes of ~1s navigation delay fixed:

1. glass.css Section 19 was extending the page-in animation from 0.20s
   to 0.30s using spring easing. Reverted to 0.20s in / 0.12s out.

2. During transitions, dozens of backdrop-filter layers (widgets, cards,
   inputs, toolbars) were composited simultaneously for both the outgoing
   and incoming page, overloading mid-range Android GPUs.
   Added html.navigating class: router.js sets it at transition start,
   glass.css overrides all app-content backdrop-filters to none while
   active, animationend removes it once the in-animation completes.
2026-04-16 13:50:38 +02:00
Ulas a7ac7d105c fix: remove will-change from nav-bottom and add iOS height fallback
will-change: transform on a position:relative flex child causes iOS WebKit
to composite the element at an incorrect position - creating a visible gap
below the nav bar. Remove it; CSS transform transitions use hardware
acceleration automatically on modern iOS without this hint.

Add -webkit-fill-available before 100dvh on .app-shell as a fallback for
iOS WebKit versions where 100dvh is computed slightly smaller than the
actual WKWebView height.
2026-04-16 12:48:43 +02:00
Ulas 51f211d72a fix: resolve iOS PWA bottom nav positioning via flex layout
Switch .nav-bottom from position: fixed to a flex child of .app-shell.
With position: fixed and will-change: transform (used for the hide/show
animation), iOS compositor layers can misplace the element. As a flex
child (position: relative; flex-shrink: 0) at the end of a height: 100dvh
container the nav is guaranteed to sit flush at the physical screen bottom.

Remove padding-bottom clearance from .app-content, .tasks-page and
.dashboard - no longer needed since the nav no longer overlaps the
content area.
2026-04-16 09:59:16 +02:00
Ulas 62bb3546a8 chore: bump version to 0.20.3 2026-04-16 09:20:25 +02:00
Ulas 9ef9680e82 chore: bump version to 0.20.2 2026-04-16 08:17:06 +02:00
Ulas dfd809c284 chore: bump version to 0.20.1 2026-04-15 18:16:56 +02:00
Ulas e384ae1037 feat: add reminders for tasks and calendar events (closes #13)
- DB migration #8: reminders table (entity_type, entity_id, remind_at, dismissed, created_by)
- REST API: GET /pending, GET /?entity, POST /, PATCH /:id/dismiss, DELETE
- Client polling module (reminders.js): 60s interval, toast + Browser Notification API
- Tasks: enable reminder with custom date/time in edit modal
- Calendar: reminder offset selector (at time / 15min / 1h / 1d before)
- Bell badge shows pending count; reminders auto-dismiss after 30s or on user action
- SW shell cache updated to include reminders.js + reminders.css
- 11 new DB tests covering CRUD, pending query, dismiss, upsert, cascade delete, constraints
2026-04-15 11:40:24 +02:00
Ulas d16919ef7c feat: per-ingredient category selection for shopping list transfer (closes #33)
When adding ingredients in the meal editor, each ingredient now has a
category dropdown. Categories are stored on the ingredient and applied
automatically when transferring to the shopping list, so items appear
pre-grouped by category without manual re-sorting.
2026-04-15 07:11:49 +02:00
Ulas d6d2c41bfa fix: eliminate black gap below bottom nav in iOS PWA standalone mode
iOS reserves the home indicator area outside the CSS viewport, leaving
a black strip below the bottom navigation. A fixed body::after pseudo-
element now fills this zone with the surface color. Also added explicit
background-color on body for consistent rendering.
2026-04-14 23:02:06 +02:00
Ulas 44d1b88e3d fix: resolve iOS forbidden errors by delivering CSRF token in response body
iOS Safari (especially PWA/standalone mode) unreliably exposes cookies
via document.cookie, causing CSRF token mismatch on state-changing
requests. The CSRF token is now included in /auth/login and /auth/me
response bodies and stored in-memory on the client. Cookie remains as
fallback. Retry mechanism also improved to read token from response
body and handle expired sessions.
2026-04-14 18:53:42 +02:00
Ulas b152d0e53f feat: add arm64 Docker image support (closes #44)
Add QEMU and multi-platform build (linux/amd64 + linux/arm64) to
GitHub Actions workflow, enabling self-hosting on Raspberry Pi and
other ARM64 devices.
2026-04-14 18:45:31 +02:00
Ulas f988ab348f fix: improve accessibility and tokenize remaining hardcoded CSS values
- FAB focus ring: double-ring pattern replacing invisible #fff outline
- forced-colors media query for Windows High Contrast Mode
- New tokens: --color-accent-secondary, --content-max-width-narrow, --cal-hour-height
- Apple sync logo uses semantic tokens for correct dark mode inversion
- Sidebar logo gradient references token instead of hardcoded #7C5CFC
2026-04-14 18:05:19 +02:00
Ulas e33c792083 chore: release v0.19.1 - iOS PWA forbidden fix 2026-04-14 17:38:38 +02:00
Ulas 8af730e9cf feat: add Japanese, Arabic, Hindi, Portuguese locales + new currencies
- 4 new locale files (ja, ar, hi, pt) with 567 keys each - full coverage
- Japanese (日本語): Hiragana/Kanji script
- Arabic (العربية): RTL-ready text
- Hindi (हिन्दी): Devanagari script
- Portuguese (Português): Brazilian Portuguese
- SUPPORTED_LOCALES updated in i18n.js (10 → 14 locales)
- LOCALE_LABELS updated in oikos-locale-picker.js
- New currencies: AED, BRL, INR, SAR added to budget settings
- Service Worker v31: new locale files pre-cached in APP_SHELL
- Docs: README, SPEC.md, BACKLOG.md, CHANGELOG.md updated
2026-04-14 10:28:17 +02:00
Ulas 3f387b616e fix: default TRUST_PROXY to 1 for Docker+reverse-proxy setups (#46)
With the previous default of 'loopback', Express ignored X-Forwarded-Proto
headers from Caddy/nginx when running in Docker (bridge IP, not loopback).
This caused req.secure=false, which made express-session silently drop the
session cookie on login - resulting in a 401 on every subsequent request.

Changing the default to 1 (trust one proxy hop) fixes this for all standard
Docker+reverse-proxy deployments without requiring manual configuration.
2026-04-14 09:04:06 +02:00
Ulas 8f96e066f3 feat: customizable dashboard layout (#32)
Users can now show/hide widgets and reorder them via a settings button
in the greeting header. Configuration is persisted server-side in
sync_config (dashboard_widgets key) and shared across all family members.

- Greeting widget gets a settings icon button opening a customize modal
- Modal lists all widgets (tasks, calendar, shopping, meals, notes,
  weather) with toggle switches and up/down reorder buttons
- Reset to default layout available in the modal
- GET /preferences now returns dashboard_widgets; PUT accepts it
- All 10 locales updated with new i18n keys
2026-04-14 08:04:26 +02:00
Ulas 6f532e45ec feat: Liquid Glass Phase 4 - vibrancy, module tint, deeper glass penetration
Dashboard widgets, task cards, note items, meal slots, form inputs,
toolbars, and FAB actions now use semi-transparent glass backgrounds
with backdrop-filter blur. Each surface gets a subtle module accent
color tint via color-mix gradient overlay. App background uses a
radial accent gradient for ambient vibrancy.

New tokens: --glass-bg-card, --glass-bg-input, --glass-bg-toolbar,
--glass-tint-strength with full dark mode and accessibility overrides.
2026-04-14 07:35:59 +02:00
Ulas 3bc926d766 fix: iOS PWA bottom nav shifting up in standalone mode
In iOS WebKit standalone (home screen) mode, position:fixed elements
move with the page when the body itself becomes scrollable - unlike
regular Safari where fixed elements stay pinned. The root cause was
body having min-height: 100dvh without overflow: hidden, which allowed
body scroll to occur when content overflowed.

Fix: html and body are now overflow: hidden with fixed height (100% / 100dvh)
so all scrolling is confined to .app-content. Service worker bumped to
shell-v30 to force re-download of reset.css on installed PWAs.
2026-04-13 22:17:31 +02:00
Ulas 5a2bc5cdb1 fix: Safari < 18 glass UI - webkit backdrop-filter @supports fallback
- All @supports checks extended to include or (-webkit-backdrop-filter: blur(1px))
  so Safari < 18 (which only recognizes the -webkit- prefix) no longer skips
  the entire @supports block and receives no glass styles at all
- Non-blur glass styles (background-color, border, box-shadow) moved outside
  @supports blocks - always active on all browsers regardless of blur support
- Capsule buttons, specular highlights, glass borders and shadows now visible
  on all devices, blur effects added on top where supported
2026-04-13 22:02:23 +02:00
Ulas 35186ca87f fix: change SameSite=Strict to SameSite=Lax for session and CSRF cookies (#46)
Safari's ITP blocks Strict cookies on certain navigations (direct URL entry,
reverse proxy context), resulting in a 401 on login even with valid credentials.
Lax is safe: CSRF attacks are prevented by the double-submit token and the
HTTPS-only secure flag. Firefox and Chrome were unaffected.
2026-04-13 21:36:35 +02:00
Ulas bd21a890e9 chore: release v0.17.1 - glass CSS load-order fixes 2026-04-13 21:13:17 +02:00
Ulas 70cf691f56 chore: release v0.17.0 - Liquid Glass redesign
Bump version to 0.17.0, update CHANGELOG with full Phase 0-3 glass layer
changes, and update SPEC.md design system documentation with glass tokens,
glass.css layer architecture, and corrected color token values.
2026-04-13 17:19:05 +02:00
Ulas 2dc8984c3e feat(shopping): custom categories - add, rename, delete and reorder (#26)
- New DB table shopping_categories (migration v5) seeds 9 default
  categories with Lucide icons and sort_order
- Backend CRUD routes: GET/POST/PUT/DELETE /shopping/categories
  plus PATCH /shopping/categories/reorder
- Category validation now uses DB instead of hardcoded constant;
  items of deleted category are moved to the next available one
- Frontend shopping page loads categories from API, dropdown and
  grouping reflect custom order dynamically
- Settings -> Shopping section: list categories with up/down buttons,
  click-to-rename, delete with confirmation; add new categories inline
- i18n keys added in de/en/sv/it
2026-04-05 17:24:06 +02:00
Ulas cde511da1d docs: update README, installation guide and GitHub Pages
- README: GHCR badge, Kanban quick-status buttons and configurable
  currency mentioned in highlights
- installation.md: Option A (pre-built image, no clone) as primary path,
  Option B (build from source) as alternative; Updates section updated;
  SQLCipher troubleshooting tip added
- index.html: Get Started block now shows pre-built image path;
  task and budget feature cards updated (EN + DE translations)
2026-04-05 16:29:12 +02:00
Ulas 7292b14945 feat(docker): use pre-built GHCR image in docker-compose by default (#25)
docker-compose.yml now references ghcr.io/ulsklyc/oikos:latest so users
can start the app with a single 'docker compose up' without cloning or
building locally. The build: . entry is retained for contributors who
want to build from source with --build.

README Quick Start updated to document both the no-clone path (curl
docker-compose + .env.example) and the build-from-source path.
2026-04-05 16:20:24 +02:00
Ulas 19a7161307 feat(tasks): add quick-status button to kanban cards (#24)
Adds a small button on each kanban card that cycles the task status
(open → in_progress → done → open) without requiring drag-and-drop.
Useful for touch devices and kiosk browsers (e.g. Fully Kiosk Browser)
where drag-and-drop is unavailable. All four locales updated.
2026-04-05 16:16:46 +02:00
Ulas 31a9538518 chore: bump version to 0.11.6 2026-04-05 14:47:12 +02:00
Ulas a8275f5ec9 chore: bump version to 0.11.5 2026-04-05 13:50:03 +02:00
Ulas 014873f516 chore: bump version to 0.11.4 2026-04-05 13:24:17 +02:00
Ulas 3a6ae4a64a feat(i18n): add Swedish (sv) translation and Italian as explicit language option (#19)
Swedish translation contributed by @olsson82 (PR #19), integrated with
minor corrections (dayShortSunday: Sun → Sön, amountLabel aligned with
v0.11.2, new v0.11.2 currency keys added).

Italian was already supported server-side but is now explicitly listed
in the locale picker alongside German, English, and Swedish.
2026-04-05 12:01:16 +02:00
Ulas 446b9b1388 feat(budget): configurable currency in settings (#20)
Add household-wide currency preference for the budget section.
Users can select from 13 currencies (EUR, USD, GBP, SEK, NOK, DKK,
CHF, PLN, CZK, HUF, JPY, AUD, CAD) in Settings → Budget.

- preferences API (GET/PUT) now includes currency field
- budget page loads currency from preferences on render
- formatAmount() uses locale-aware Intl.NumberFormat with chosen currency
- settings page gains a Budget section with a currency select
- all three locales (de, en, it) updated with new i18n keys
2026-04-05 11:55:38 +02:00
Ulas 212a8bdb0a fix(dashboard): filter todayMeals by visible_meal_types preference (#14)
The dashboard meal widget was showing all meal types regardless of the
household meal visibility settings configured in Settings > Meal Plan.

Root cause: the todayMeals SQL query in dashboard.js did not read
visible_meal_types from sync_config. The Meals page applied this filter
client-side, but the dashboard API returned unfiltered data.

Fix: read visible_meal_types from sync_config before the query and inject
the active types as IN (?) placeholders. Falls back to all four types when
no preference is stored.
2026-04-05 03:12:01 +02:00
Ulas 0940afc170 chore(release): v0.11.0
Bump version and update CHANGELOG for release v0.11.0.
2026-04-05 03:09:06 +02:00