Commit Graph

282 Commits

Author SHA1 Message Date
Ulas 2508473265 fix(pwa): fix UI overlap, scroll bleed and wrong nav height on iOS
Three root causes fixed:

1. Double safe-area padding: pwa.css set padding-top/bottom on body
   globally, but page containers already account for safe-area-inset
   in their height calculations. Removed body vertical padding (kept
   only in standalone media query for padding-top).

2. Wrong nav token: all page containers used --nav-height-mobile (56px)
   instead of --nav-bottom-height (68px = 56px scroll + 12px dots),
   causing 12px of content to render behind the bottom nav.

3. Scroll bleed: fixed-height page containers lacked overflow:hidden,
   allowing scroll events to propagate to the body. Added
   overscroll-behavior-y:contain on app-content globally.

Fixes #16
2026-04-04 22:02:19 +02:00
Ulas 7eb06ed905 fix(modal): replace native prompt() with custom modal dialogs
Native browser prompt() is unreliable on mobile browsers and PWAs,
often requiring multiple clicks to close. Replace all prompt() calls
with custom promptModal() and selectModal() functions that use the
existing modal system with proper focus management and animations.

Affected pages: shopping (create/rename list), tasks (add subtask),
meals (choose shopping list).

Fixes #12
2026-04-04 21:31:50 +02:00
Ulas c93be9049c feat(dashboard): add shopping list widget
Show shopping lists with open items directly on the dashboard.
Each list displays a progress bar, the first few unchecked items,
and a "+N more" overflow indicator. Widget only appears when there
are lists with open items.

Backend: new shoppingLists query in /api/v1/dashboard (up to 3 lists,
6 open items each). Frontend: renderShoppingLists() widget following
existing widget pattern. CSS: compact list/progress/item styles.
i18n: shoppingMore key added to de/en/it.

Requested in discussion #9
2026-04-04 14:30:31 +02:00
Ulas 47b34c4829 fix(modal): add fallback timer for mobile close animation
On mobile, closeModal() relies on the CSS animationend event to call
_doClose(). When the animation does not fire (prefers-reduced-motion,
tab switch, browser quirk), the modal stays stuck and the user cannot
dismiss it. A 300ms fallback timer now guarantees cleanup runs.

Reported in discussion #9
2026-04-04 14:16:00 +02:00
Ulas 597c2602aa fix(i18n): translate category names in tasks and budget displays
Category group headers in tasks and bar chart labels / transaction meta
in budget were showing raw German database keys instead of going through
CATEGORY_LABELS() i18n mapping.

Closes #11
2026-04-04 14:08:41 +02:00
Ulas 38c5852c78 fix(ux): improve microinteractions across the app
1. Nav-item tap: smooth scale transition instead of abrupt snap
2. Custom toggle switch: iOS-style toggle replaces native checkboxes
3. Focus-visible: outline on cards, buttons, FABs for keyboard users
4. Empty-state: gentle fade-in animation
5. Toast icons: SVG icons for success/danger/warning types
6. Swipe haptic: vibrate(15) fires at threshold during touchmove
2026-04-04 07:25:54 +02:00
Ulas dd10974997 fix(ux): defer old stylesheet removal until after page content is gone
Previous fix removed the old CSS when new CSS loaded, but that happened
BEFORE the out-animation completed - causing a flash of unstyled content.
Now the old stylesheet stays until replaceChildren removes the old DOM.
2026-04-04 07:04:52 +02:00
Ulas a9d2a802ab fix(ux): prevent flash of unstyled content during page transitions
- Keep old page stylesheet until new one is fully loaded
- Hide new page wrapper until render() completes before starting animation
2026-04-04 06:58:12 +02:00
Ulas d92f7ca446 fix(design): replace hardcoded values with design tokens
Audit found ~35 violations against the token system. Fixed:
- Hardcoded shadows in layout.css replaced with --shadow-sm/md
- 8 rgba colors extracted to new glass tokens (--color-glass-*)
- border-radius: 50% replaced with var(--radius-full)
- ~25 off-grid spacing values (5px, 6px, 7px, 14px, 15px, 22px,
  26px, 34px) aligned to 4px grid using space tokens
2026-04-04 06:50:19 +02:00
Ulas 364d029950 fix(ux): prevent iOS auto-zoom on inputs + lazy-load page CSS
Increase font-size to 16px on mobile for shopping quick-add inputs,
notes search, and contacts search. Desktop breakpoint restores compact
sizes. Move 9 page-specific stylesheets from index.html to on-demand
loading in router.js, reducing initial CSS payload.
2026-04-04 06:39:45 +02:00
Ulas 70c1291ae7 fix(a11y): skip-link target, priority labels, greeting tokens
- Rename #page-content to #main-content so skip-to-content link
  targets the semantic <main> landmark
- Add sr-only priority labels to dashboard task items for screen
  readers (WCAG 1.4.1 color-not-only)
- Replace hardcoded hex in greeting gradient with accent tokens
  so dark mode themes the banner correctly
- Replace hardcoded gap: 2px with --space-0h token
- Bump version to 0.7.2
2026-04-04 06:31:21 +02:00
Ulas 6bc4c46f03 fix(security): eliminate XSS vectors and restore zoom accessibility
- Extract shared esc() utility (public/utils/html.js) replacing 8
  duplicate escHtml() functions across all page modules
- Apply HTML escaping to all user-controlled data in innerHTML
  templates: titles, names, locations, descriptions, colors, notes
  content, weather data, autocomplete suggestions
- Remove user-scalable=no and maximum-scale=1 from viewport meta
  tag, restoring pinch-to-zoom for WCAG 1.4.4 compliance
- Bump version to 0.7.1
2026-04-04 06:25:28 +02:00
Ulas 3d2604bab9 fix(security): address critical and high findings from security audit
Fix stored XSS in tasks (titles/subtasks) and settings (member list)
by applying escHtml(). Harden trust proxy to loopback default, add
OAuth state parameter for Google Calendar CSRF protection, sanitize
CSV export against formula injection, invalidate sessions on user
deletion, restrict usernames to alphanumeric chars, and require admin
role for calendar sync triggers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 17:28:36 +02:00
Ulas 1122bd269b style: replace em dashes with hyphens throughout codebase
Replace all — with - in all source files (JS, CSS, HTML, JSON,
Markdown) for consistency and readability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-03 17:04:39 +02:00
Ulas b1ee4439be feat(i18n): add Italian localization
Add complete Italian translation (497 keys) based on PR #7 by
@albanobattistella. Fixed filename from "it. json" to "it.json" and
registered Italian in SUPPORTED_LOCALES and the locale picker component.

Co-Authored-By: albanobattistella <34811668+albanobattistella@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 15:35:08 +02:00
Ulas c59338fe2c chore: repository hygiene — P2 cleanup
- .gitignore: add coverage/ and data/ patterns
- .dockerignore: exclude screenshots, tests, scripts, .github, docs
  assets from build context for faster Docker builds
- Delete docs/social-preview.html (one-time generator, no longer needed)
- Delete public/locales/.gitkeep (directory has de.json and en.json)
- scripts/seed-demo.js: replace hardcoded absolute path with portable
  resolve(__dirname, '..', 'data', 'oikos.db') default
- Add .github/PULL_REQUEST_TEMPLATE.md with summary, changes, checklist

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 14:19:27 +02:00
Ulas ef51c43032 fix: meals drag & drop crash — destructure dragging before cleanup()
cleanup() set dragging = null, then onUp accessed dragging.slot,
.mealId, .sourceDate, .sourceType on the now-null reference.
Fix: destructure all needed values before calling cleanup().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 10:11:24 +02:00
Ulas be8801aef7 fix: proxy weather icons through server to fix PWA standalone on Android
External image requests to openweathermap.org fail silently in Chrome
Android PWA standalone mode. Icons are now proxied via
GET /api/v1/weather/icon/:code, making them same-origin — cacheable by
the service worker and free of CORS/CSP issues.

Tightened CSP: removed openweathermap.org from imgSrc (no longer needed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:57:48 +02:00
Ulas af69431eac fix: weather icons in PWA + locale picker dropdown
- SW: skip cross-origin asset requests (opaque responses caused weather
  icons to break in PWA standalone mode on Android)
- Replace oikos-locale-picker radio buttons with <select> dropdown
- Add settings.localeLabel i18n key (de + en)
- Bump SW cache to v22

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:42:06 +02:00
Ulas cd9f26911b fix: improve PWA manifest and SW cache for Android standalone mode
- Add id field and display_override to manifest.json for reliable
  Chrome Android PWA recognition
- Serve manifest.json with application/manifest+json MIME type
- Add /i18n.js and locale files to SW app shell cache (were missing)
- Bump SW cache version to v21

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:07:57 +02:00
Ulas dd940ab05d fix: replace placeholder icons with house logo for PWA install
Android was showing only a blue circle because maskable icons had no
visible content after the adaptive icon mask was applied. All icons now
use the actual Oikos house logo from docs/logo.svg. Maskable variants
use full-bleed background with logo within the 80% safe zone.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 09:02:55 +02:00
Ulas 752d0f919f fix: resolve nested i18n keys via dot notation in t()
The locale JSON files use nested structure (e.g. {"nav":{"tasks":"…"}}),
but t() did a flat lookup, always falling back to the raw key string.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:47:59 +02:00
Ulas 431d6af356 feat: add oikos-locale-picker component and language settings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:29:13 +02:00
Ulas 26a8434369 fix: replace hardcoded Uhr suffix and use getLocale() in budget 2026-03-31 23:27:44 +02:00
Ulas 66a9bdfa44 feat: replace manual date formatting with formatDate/formatTime from i18n
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:24:21 +02:00
Ulas 3aefca0a44 feat: i18n navigation labels
Replace all hardcoded German strings in router.js (navItems labels,
aria-labels, skip-link, error/toast messages) with t() calls. Add a
locale-changed event listener that re-renders sidebar and bottom-nav
items on language switch.
2026-03-31 23:19:05 +02:00
Ulas fe70cbf979 feat: i18n web components with locale-changed listener
Replace hardcoded German strings in modal.js and oikos-install-prompt.js
with t() calls; wire locale-changed event listener for live re-render on
locale switch.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:15:51 +02:00
Ulas a21fe6afdd fix: replace hardcoded Fehler fallbacks with t(common.unknownError)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:13:41 +02:00
Ulas 29e334c114 fix: i18n contact categories and budget month names 2026-03-31 23:07:09 +02:00
Ulas 26bbd61e1d feat: i18n notes, contacts, budget, settings pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 22:57:45 +02:00
Ulas e6c6b0a4fc feat: add missing calendar keys to locales
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 22:52:51 +02:00
Ulas 2f89e623b2 feat: i18n shopping, meals, calendar pages
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 22:50:16 +02:00
Ulas 752f6ee24d feat: add missing tasks keys to locales 2026-03-31 22:33:54 +02:00
Ulas f6a4879dd0 feat: i18n login, dashboard, tasks pages 2026-03-31 22:31:57 +02:00
Ulas af8f9ccb56 feat: initialize i18n before first route render 2026-03-31 21:53:14 +02:00
Ulas ad921e1637 feat: add de.json and en.json locale files
Extracts all German UI strings from public/pages/, public/components/,
and public/router.js into 482 i18n keys organized by module prefix.
English translations added for all keys.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 21:51:18 +02:00
Ulas 9bf8f2abbb fix: improve i18n robustness (null guards, race condition, error resilience) 2026-03-31 21:43:55 +02:00
Ulas 3bec77db3b feat: add i18n module (public/i18n.js) 2026-03-31 21:41:20 +02:00
Ulas 3df20fc78b chore: remove unused files and duplicate assets
Delete orphaned Python screenshot generators, social-preview template,
and duplicate icon files in public/assets/ (superseded by public/icons/).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 17:46:56 +02:00
Ulas fe41f84a62 fix: add missing toolbar stripe to meals and --module-accent to settings 2026-03-31 15:14:21 +02:00
Ulas c6551166a9 fix: add missing dark-mode overrides for shopping, notes, contacts, budget, settings module tokens
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 15:10:42 +02:00
Ulas 6f22ef8268 feat: list items get module accent border-left stripe
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 15:00:41 +02:00
Ulas 4ac9cd16d1 fix: add missing --module-accent declaration to calendar-page 2026-03-31 14:58:16 +02:00
Ulas 3bf2d2bbc0 feat: toolbar top-border stripe uses module accent colour 2026-03-31 14:54:10 +02:00
Ulas 7f41ee380a refactor: move --active-module-accent update into navigate() to avoid duplicate ROUTES.find
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 13:31:57 +02:00
Ulas 6a018867e0 feat: active nav tab uses module accent colour 2026-03-31 13:22:16 +02:00
Ulas cd017c4d0d fix: escape user input in shopping renderItem to prevent XSS 2026-03-31 12:53:00 +02:00
Ulas 0e035af492 feat: swipe gestures on shopping list items (toggle + delete) 2026-03-31 12:49:29 +02:00
Ulas 33bef8eb3f feat: wrap shopping items in swipe-row 2026-03-31 12:47:37 +02:00
Ulas dc2e874cb2 feat: add shopping swipe CSS (delete reveal, mobile button hide) 2026-03-31 12:46:26 +02:00