Commit Graph

155 Commits

Author SHA1 Message Date
jbrechtel 3c3b6b853a Fix cook history ordering: sort months by date, not name
Build and Deploy / build-and-deploy (push) Successful in 1m46s
groupEntries was sorting month groups by reverse-alphabetical name
(e.g. 'June' before 'July'), producing oldest-first ordering.
Now sorts by the actual entry dates within each group (newest first).
Combined with the earlier DESC fix in fetchAllEntries, the cook
history page now shows newest months at top, newest entries within
each month at top.
2026-07-08 09:25:41 -04:00
jbrechtel 78612eaa06 Fix cook history ordering: show newest entries first
Build and Deploy / build-and-deploy (push) Successful in 19m31s
fetchAllEntries had ORDER BY cooked_date ASC but the doc comment
claimed 'newest first'. Changed to DESC to match fetchEntries
behavior and fix the cook-history page (most recent at top).
2026-07-08 08:59:13 -04:00
jbrechtel 506de6c4d8 Uses latest sonnet model
Build and Deploy / build-and-deploy (push) Successful in 1m46s
2026-05-31 14:48:32 -04:00
jbrechtel 518d62fcb6 HLint 2026-05-31 14:46:58 -04:00
jbrechtel dbc2026422 Format code with fourmolu
Build and Deploy / build-and-deploy (push) Successful in 13m50s
2026-05-27 21:31:00 -04:00
jbrechtel 5aab9a8018 Move recipe filter tabs from nav into page content
Build and Deploy / build-and-deploy (push) Failing after 1m33s
- A-Z, By Tag, By Course now render as .roux-filter-tabs above the
  search box, not in the navigation header
- Index page nav matches all other pages: Home | Recipes | Import | Cook History
- JS active-tab tracking targets filter links instead of nav links
2026-05-27 21:22:47 -04:00
jbrechtel 541dc0e7ce Unify header navigation and page padding across all pages
- Add Home link to every page's navigation header (index, recipe,
  cook history, import)
- Move landing page padding (36px 48px 80px) into base main.container
  CSS so all pages share the same consistent spacing
- Remove per-page padding overrides from .lnd-page and .rp-page
2026-05-27 21:13:48 -04:00
jbrechtel 0eb6e6ea3c UI adjustments: Import link in header, matching font sizes, cook history titles, click-to-upload images
- Add Import link to all page headers (landing, recipe, cook history, import)
- Match ingredient list font size to recipe method text (both 15px)
- Show recipe titles instead of filenames on Cook History page
- Make clicking anywhere on recipe hero image/placeholder trigger file upload dialog
2026-05-27 20:59:24 -04:00
jbrechtel 2124630146 Recipe page: ingredients and method side-by-side layout
Build and Deploy / build-and-deploy (push) Successful in 13m14s
- Change rp-body-grid from 1.5fr 1fr (content|history) to 1fr 1fr
  (ingredients|method)
- Move cook history to full-width section below the grid
- Move sections list binding out of inner div so both columns can use it
2026-05-26 09:36:07 -04:00
jbrechtel 7b77cf2840 Fix recipe page: step text contrast and interactive ingredient checkboxes
Build and Deploy / build-and-deploy (push) Successful in 1m55s
- Darken step text: use --roux-text instead of #4A3525, explicit p color
  to override Pico CSS defaults
- Make ingredient list interactive: each ingredient is now a checkbox
  row that shows ✓ checkmark on click with line-through + muted opacity
- Collect ingredients from ALL sections (not just sections named
  'Ingredients'), deduplicated per section, grouped by section name
- Switch from <ul>/<li> to <div>/<label> with checkbox inputs
2026-05-26 09:32:34 -04:00
jbrechtel 7b64f9576b Fix 'btn is not defined' JS error in Record meal modal
Build and Deploy / build-and-deploy (push) Successful in 12m59s
When the trigger JS was updated to use querySelectorAll('.roux-record-trigger')
for dual-button support, the variable was renamed from 'btn' to 'btns' but the
submit handler still referenced 'btn'. This commit:

- Adds activeBtn tracking: the button that opened the modal is stored in
  activeBtn via 'this' in the click handler
- Uses activeBtn.dataset.filename in the submit handler (with null guard)
- Removes the stale btn reference
2026-05-26 07:44:50 -04:00
jbrechtel 65b096bc31 Landing page: use recipe images in cards, make cards clickable
Build and Deploy / build-and-deploy (push) Successful in 1m48s
- Card images now show the recipe's actual image when available
  (background-image: url(...) with background-size: contain to preserve
  aspect ratio without distortion), falling back to gradient placeholders
- Cards are now wrapped in <a href="/recipes/{filename}"> so clicking
  anywhere on a card navigates to the recipe page
- Added .contain CSS class for image-fit behavior and .lnd-card a for
  link styling
2026-05-26 07:43:04 -04:00
jbrechtel 162d2f8a1e Formats repo 2026-05-26 07:39:28 -04:00
jbrechtel 0643dda10d Update recipe view page layout to match roux-recipe-mockup.html
Build and Deploy / build-and-deploy (push) Failing after 1m40s
Layout changes:
- Nav matching landing page style (ROUX logo + Recipes + Cook History)
- Large serif title with inline editing preserved
- Subtitle from recipe description
- Meta strip: rounded background with last cook info + source link + Log meal button
- Full-width hero image with upload/replace overlay
- 2-column body grid (1.5fr ingredients+method | 1fr cook history rail)
- Flat ingredient list with quantities (no checkboxes)
- Numbered method paragraphs (no checkboxes, timers preserved)
- Cook history rail on right with + Add button
- Tags displayed below the grid
- Responsive: single column on mobile

Architecture:
- Removed: renderMetaBar, renderCookLog, renderRecentCookEntries,
  renderRecentEntry, renderEntry, renderIngredientGroup, renderIngredientRow,
  collectSectionIngredients, dedupFirst, renderMethodSections, renderMethodStep,
  isEmptyStep, isBlankText, isMethodSection, sectionMethodSteps,
  renderMarginalNote, collectNotes, bodyItemSteps, pairWith
- Added: recipePageStyles, rpHeroImage, rpLastCookInfo, formatFullDate,
  rpIngredientList, rpNamedIngredientSection, collectIngredients,
  rpIngredientItems, rpMethodList, rpRenderMethodStep, rpHistoryList,
  rpRenderHistoryEntry
- Updated cookLogJs to use .roux-record-trigger class for dual trigger buttons
- Removed unused imports (Data.Function, catMaybes)
- All hlint warnings fixed, 51 tests passing
2026-05-26 07:38:15 -04:00
jbrechtel 6a7374c912 Formatting
Build and Deploy / build-and-deploy (push) Successful in 14m49s
2026-05-26 07:25:18 -04:00
jbrechtel d22c8a79d4 Add landing page with cook log integration
Build and Deploy / build-and-deploy (push) Failing after 1m15s
- New landing page (/) based on roux-landing-mockup.html layout
  - Shuffle card that suggests random recipes
  - Recently cooked shelf (driven by cook log DB)
  - Recently added shelf (by file modification time)
- Existing recipe index moved to /recipes
- Updated nav links throughout to point to /recipes
- All hlint warnings fixed
2026-05-26 07:15:38 -04:00
jbrechtel edb682c8bc fix: skip empty/whitespace-only steps so step numbering starts at 1
Build and Deploy / build-and-deploy (push) Failing after 8s
2026-05-26 06:59:07 -04:00
jbrechtel 0be6e299d5 fix: normalize recipe filenames in cook-log (strip .cork ext, lowercase); also fetch with .cork fallback for legacy entries
Build and Deploy / build-and-deploy (push) Failing after 1m25s
2026-05-26 06:48:11 -04:00
jbrechtel 4dd580a042 Formats repo
Build and Deploy / build-and-deploy (push) Successful in 13m25s
2026-05-26 06:45:02 -04:00
jbrechtel ee42bfd981 fix: darken text colors — define --roux-muted, add explicit color to Cancel button, darken recent entry comment/date colors
Build and Deploy / build-and-deploy (push) Failing after 9s
2026-05-26 06:44:23 -04:00
jbrechtel 92ec058114 feat: show most recent 5 cook entries under Record meal button
Build and Deploy / build-and-deploy (push) Failing after 1m17s
2026-05-26 06:40:24 -04:00
jbrechtel 14f43a4ae9 fix: send URL-encoded form data instead of multipart, show errors inline, default empty date to today
Build and Deploy / build-and-deploy (push) Successful in 15m46s
2026-05-25 22:26:53 -04:00
jbrechtel 930fba369c feat: replace inline cook log form with 'Record meal' button + modal
Build and Deploy / build-and-deploy (push) Successful in 17m20s
2026-05-25 22:20:00 -04:00
jbrechtel ac7a979fe9 Formats repo
Build and Deploy / build-and-deploy (push) Successful in 15m3s
2026-05-25 22:11:28 -04:00
jbrechtel 0b6b9c3d17 fix: use Text for created_at, fix show-bug in ToJSON, add /cook-history route
Build and Deploy / build-and-deploy (push) Failing after 21s
2026-05-25 22:10:23 -04:00
jbrechtel 90971568a3 feat: add cook history nav link to index page 2026-05-25 22:01:24 -04:00
jbrechtel c6a9c2dee4 feat: wire up cook log DB at server startup 2026-05-25 22:00:45 -04:00
jbrechtel ceadf50c59 feat: add CookLog module with types and DB operations 2026-05-25 21:55:43 -04:00
jbrechtel 0b5fa61acd chore: add sqlite-simple dependency 2026-05-25 21:54:22 -04:00
jbrechtel edfa9bac76 docs: add implementation plan for cooking log feature 2026-05-25 21:48:51 -04:00
jbrechtel f2bd667b75 docs: add cooking log design spec 2026-05-25 21:45:49 -04:00
jbrechtel ed015d3799 Fix all 20 hlint warnings across 5 source files
Build and Deploy / build-and-deploy (push) Successful in 12m38s
- Use newtype instead of data for single-field types (RouxConfig, ImportError)
- Replace maybe "" id with fromMaybe "" throughout
- Replace not (x `elem` ys) with x `notElem` ys
- Remove redundant brackets, redundant $, and eta-reduce lookupRecipe
- Use numeric underscore for 1_000_000
2026-05-25 21:30:21 -04:00
jbrechtel 67c3b4df6c Merge branch 'feat/inline-title-edit'
Build and Deploy / build-and-deploy (push) Successful in 2m10s
2026-05-21 21:37:20 -04:00
jbrechtel 69f4184f2e feat: add PATCH endpoint for recipe title updates 2026-05-21 21:31:33 -04:00
jbrechtel 7b51c617de feat: add inline title editing JavaScript 2026-05-21 21:29:54 -04:00
jbrechtel e5ed706aa6 Updates prompt 2026-05-21 21:29:34 -04:00
jbrechtel 1f7b55af6f feat: add CSS class and styles for editable recipe title 2026-05-21 21:29:20 -04:00
jbrechtel 8e6e572b35 chore: add .worktrees to gitignore 2026-05-21 21:28:03 -04:00
jbrechtel 59fd96b57d docs: add design and plan for inline title editing 2026-05-21 21:28:00 -04:00
jbrechtel d64129fc9f fix: save recipe images to recipe-images/ subdirectory
Build and Deploy / build-and-deploy (push) Successful in 1m49s
Previously images were saved directly in the recipe directory
alongside .cook files. Now they go into <recipes-dir>/recipe-images/,
keeping the recipe directory clean and making the purpose of the
file clear from its path.
2026-05-21 21:06:07 -04:00
jbrechtel a509f44300 feat: add recipe image upload with in-place metadata update
Build and Deploy / build-and-deploy (push) Successful in 2m4s
Users can now upload an photo for any recipe directly from the
view page. The upload button appears as either a 'Replace' overlay
on existing images or an empty dashed placeholder for recipes
without one.

Upload flow:
1. Click upload button -> file picker opens (accepts image/*)
2. JavaScript reads the file as base64, POSTs to /upload-image
   with form fields: filename, file-b64, file-name
3. Server decodes the base64, saves to <recipe-dir>/<basename>.<ext>
4. Server updates the .cook file's YAML front matter, adding or
   updating the 'image:' key with a /recipe-images/ URL
5. Server returns JSON success, page reloads to show the image

Server routes added:
- POST /upload-image  — accepts base64-encoded image upload
- GET /recipe-images/<filename> — serves saved recipe images
  (extension-whitelisted to .jpg/.jpeg/.png/.gif/.webp)

Image files are stored alongside .cook files in the recipe directory
and served via the /recipe-images/ path. The fsnotify watcher detects
the .cook metadata change and triggers an SSE reload.
2026-05-21 20:43:58 -04:00
jbrechtel 76fab5c716 fix: save uploaded files to recipe-images/ subdir and inject source URL
Build and Deploy / build-and-deploy (push) Successful in 1m49s
2026-05-21 17:04:34 -04:00
jbrechtel 439f5780c9 feat: show recipe image thumbnail on index page
Build and Deploy / build-and-deploy (push) Successful in 1m43s
2026-05-21 15:19:14 -04:00
jbrechtel 2dd8840569 fix: resolve prompts dir in Docker and script, try multiple locations
Build and Deploy / build-and-deploy (push) Successful in 1m34s
2026-05-21 12:58:52 -04:00
jbrechtel f6040f5445 chore: add convert-to-cooklang and Python deps to Dockerfile
Build and Deploy / build-and-deploy (push) Successful in 4m21s
2026-05-21 11:59:31 -04:00
jbrechtel 5117c9d445 fix: remove relative path fallback in findConvertScript, rely on PATH only
Build and Deploy / build-and-deploy (push) Successful in 1m33s
2026-05-21 11:42:06 -04:00
jbrechtel 16074b0060 fix: resolve convert-to-cooklang script path with makeAbsolute
Build and Deploy / build-and-deploy (push) Successful in 1m46s
2026-05-21 11:15:39 -04:00
jbrechtel 76fb927109 Fixes typo in Dockerfile config
Build and Deploy / build-and-deploy (push) Successful in 1m43s
2026-05-21 11:03:10 -04:00
jbrechtel d9a7f6538e feat: add Import link to index page navbar
Build and Deploy / build-and-deploy (push) Successful in 1m32s
2026-05-21 10:56:35 -04:00
jbrechtel c36e632d25 style: style import form inputs to match search box
Build and Deploy / build-and-deploy (push) Successful in 1m32s
2026-05-21 10:52:34 -04:00