Commit graph

21 commits

Author SHA1 Message Date
Jon Seager
5820c162f6
fix: address static assets code review findings
- Remove dead CSS color property in .tab-mobile
- Fix design token violations (text-red-500, fallback colors)
- Add disconnectedCallback to chip-scroll, image-upload, searchable-select
- Replace innerHTML with safe DOM APIs in world-map screen reader table
- Add credentials: same-origin to WebAuthn fetch calls
- Move page-specific scripts (donut-chart, location) out of base.html
- Add client-side image resizing (1920px max dimension)
- Resize app-icon-512.png from 2048x2048 to 512x512
- Document Datastar unsafe-eval CSP requirement
- Add static asset serving tests (16 routes)
- Add e2e tests for world-map, donut-chart, chip-scroll presence
- Add cache-busting query params to all static asset URLs
2026-02-13 17:13:02 +00:00
Jon Seager
2e41c28429
fix: apply EXIF orientation to uploaded photos
iPhone photos were displayed rotated because EXIF orientation metadata
was not being applied. Fix both the client-side canvas conversion
(use createImageBitmap which respects EXIF) and the server-side image
processing (read and apply EXIF orientation before resizing).
2026-02-12 18:07:52 +00:00
Jon Seager
4ee8cf7964
fix: polish edit forms and detail pages
- Skip payload in tracing::instrument to avoid logging base64 image data
- Add blob: to CSP img-src for image preview support
- Add deferred_upload_with_preview macro for edit form image previews
  with Replace/Remove buttons and proper DOM cleanup on replacement
- Fix datastar-fetch finished handler (evt.detail.response is undefined
  for redirect scripts)
- Display brew time in M:SS format on edit form
- Add full-width Save Changes button with check icon and Cancel button
  to all edit forms
- Fix country flag emoji spacing on cafe and cup detail pages
- Add "View on Map" Google Maps link to cafe and cup detail pages
2026-02-10 19:43:03 +00:00
Jon Seager
fbf5a288c1
feat: support HEIF/HEIC image uploads via client-side Canvas conversion
Convert all image files to JPEG on the client before uploading, allowing
iPhone HEIF/HEIC photos to work without server-side libheif dependency.
2026-02-10 17:56:48 +00:00
Jon Seager
7bacd30854
feat: improve image loading states on detail pages
Replace "Uploading..." text with animated spinner when uploading via
thumbnail, and show placeholder icon while image loads from server.
2026-02-10 17:50:27 +00:00
Jon Seager
4b3f03f5d3
feat: add entity image support with display on detail pages
Add image infrastructure, API, and detail page integration:

- EntityImage domain model with ImageRepository trait
- SQLite storage for images and thumbnails as BLOBs
- Image processing with data URL decoding and thumbnail generation
- REST API: upload, get, delete, thumbnail at /{entity_type}/{id}/image
- resolve_image_url helper for image fallback chains
- image-upload web component for direct upload on detail pages
- Image display with vignette overlay and lightbox viewer
- Template macros: image_thumbnail, readonly_image, lightbox_script
- All 7 detail pages updated with image thumbnails
- Brew images fall back to roast; cup images fall back to cafe then roast
- Delete handler macro extended with optional image cleanup
2026-02-10 17:50:13 +00:00
Jon Seager
aad927085b
refactor: extract location JS into static file with nearby keyboard nav
Move locateUser and nearbyKeydown functions from an Askama macro into
static/js/location.js served as a deferred script. Add arrow key, Enter,
and Escape navigation for nearby cafe search results.
2026-02-09 19:54:49 +00:00
Jon Seager
f4411fdc76
feat(a11y): add role=img and sr-only data to map and chart components
Add ARIA role=img with descriptive labels to world-map SVG and
donut-chart SVG. Include a screen-reader-only data table in world-map
for country/count pairs.
2026-02-09 19:54:42 +00:00
Jon Seager
8f79c5aaf3
feat(a11y): add combobox ARIA and keyboard nav to searchable-select
Add role=combobox, aria-expanded, aria-controls, and role=listbox/option
attributes. Support arrow key navigation, Enter to select, and Escape
to dismiss. Add aria-label to clear button.
2026-02-09 19:54:33 +00:00
Jon Seager
1a71fb4158
chore: autoformat templates with prettier 2026-02-09 13:40:05 +00:00
Jon Seager
f144526288
feat(stats): add world-map theme awareness and highlight color
- Add --highlight-rgb CSS custom property for light and dark themes
- Add MutationObserver to world-map for theme change detection
- Read choropleth colors from CSS custom properties instead of hardcoded values
- Simplify stats_map partial to use text-highlight class
2026-02-08 15:20:44 +00:00
Jon Seager
66c5cd0d6c
feat(stats): add full stats page with consumption, brewing, and charts
- Refactor stats handler to load_or_compute with cache fallback
- Add donut charts for brewer and grinder usage (with XSS-safe labels)
- Add bar charts for origins, flavours, grind weight, and brew time
- Add consumption cards (total brewed, avg per brew, bags consumed)
- Add roast summary section (top origins, processes, producers)
- Register donut-chart.js static asset route
- Add Recompute Stats button to admin page
2026-02-08 15:20:29 +00:00
Jon Seager
585eb77799
feat(home): add floating chevron scroll buttons to card sections
Extract <chip-scroll> custom element into its own file and wrap
Recent Brews and Open Bags horizontal scrollers with desktop-only
chevron navigation that half-overlaps the card edges.
2026-02-08 11:51:13 +00:00
Jon Seager
7f99ffc993
feat(stats): add geographic stats page with choropleth world map
- New /stats page with Roasters, Roasts, Cups, and Cafes tabs
- Interactive choropleth world map (SVG) colored by country counts
- Clickable country chips that highlight individual countries on the map
- Horizontal chip scroller with chevron navigation on desktop
- Datastar-powered tab switching without page reload
- Domain layer: country name → ISO code mapping, flag emoji generation
- StatsRepository trait with four aggregate SQL queries
- <world-map> and <chip-scroll> custom elements for Datastar compatibility
2026-02-08 11:03:15 +00:00
Jon Seager
51f8122201
feat(ui): improve form UX with collapsible equipment and clickable controls
- Split equipment into separate Grinder and Brewer collapsible sections
  with summary bars showing current selection
- Make all summary bars, matched-entity cards, and searchable-select
  selected values clickable anywhere to change (not just the X/Change button)
- Fix stepper buttons broken after manual input by switching from
  data-attr:value to data-bind with Number() coercion
- Merge Water + Brew Time into single Recipe section
- Make all add/confirm buttons full-width
- Add sticky submit button on mobile
- Fix missing closing > on cafe indicator div
- Fix broken Askama syntax on checkin page from formatter
2026-02-07 12:10:56 +00:00
Jon Seager
a3cfc22f09
fix(ui): show native camera/gallery picker on mobile photo capture
Remove capture="environment" from the file input so mobile browsers
present the OS-native action sheet instead of opening the camera directly.
2026-02-07 10:27:32 +00:00
Jon Seager
28a64a93d1
fix(ui): block native change events in searchable-select component
Native change events from child inputs were bubbling up and reaching
data-on:change handlers, which expect only the CustomEvent with
evt.detail. Capture and stop native change events so only the
component's own CustomEvent propagates.
2026-02-07 08:28:22 +00:00
Jon Seager
3594ad40ea
style(js): convert webauthn.js to arrow functions and template literals
Replace function declarations with const arrow functions and string
concatenation with template literals to match the project's JS style.
2026-02-06 18:19:18 +00:00
Jon Seager
4a7b054de1
feat(brews): pre-select bag when clicking Brew on homepage bag card
- Add initial-value attribute to searchable-select web component
- Update bag card Brew link to pass bag_id query parameter to add page
- Thread bag_id through route handler and template to pre-select the bag
2026-02-06 10:53:42 +00:00
Jon Seager
709adcdd3e
fix(ui): tokenize neutral text colors for dark mode contrast
Replace ~268 hardcoded text-stone-* classes with theme-aware token
utilities (text-text, text-text-secondary, text-text-muted) across all
templates and JS components. Adjust dark mode token values to meet
WCAG AA contrast ratios on dark surfaces.
2026-02-05 20:57:59 +00:00
Jon Seager
4e917cee75
refactor: move static assets out of templates/ into static/
Move CSS, JS, favicon files to static/ directory to separate
compiled-in assets from Askama templates. Update all include paths,
build.rs, flake.nix, and Tailwind @source directives.
2026-02-05 17:47:32 +00:00