Skip to content

Add recipe-to-grocery-list integration#84

Merged
spe1020 merged 6 commits intomainfrom
feature/grocery-recipe-integration
Jan 11, 2026
Merged

Add recipe-to-grocery-list integration#84
spe1020 merged 6 commits intomainfrom
feature/grocery-recipe-integration

Conversation

@spe1020
Copy link
Copy Markdown
Contributor

@spe1020 spe1020 commented Jan 11, 2026

Summary

  • Adds ability to add ingredients from any recipe directly to grocery lists
  • Automatic ingredient parsing with quantity/unit extraction
  • Auto-categorizes ingredients (produce, protein, dairy, pantry, frozen, other)
  • Links recipe to grocery list for traceability

Features

  • Ingredient Parser: Extracts and parses ingredient lines from recipe markdown
    • Handles quantities like "2 cups", "1/2 teaspoon", fractions (½, ¼)
    • Strips preparation notes ("2 onions, diced" → "2 onions")
    • Auto-categorizes based on ingredient name
  • AddToListModal: Clean UI for selecting/creating grocery lists
    • Preview of parsed ingredients with categories
    • Create new list inline
    • Success feedback before auto-close
  • Recipe Integration: "Add to Grocery List" in recipe menu (logged-in only)

New Files

  • src/lib/utils/ingredientParser.ts - Parsing utilities
  • src/components/grocery/AddToListModal.svelte - Selection modal

Modified Files

  • src/components/Recipe/Recipe.svelte - Added menu option + modal
  • src/lib/services/groceryService.ts - Added buildRecipeAddress helper

Test plan

  • Open any recipe while logged in
  • Click ⋮ menu → "Add to Grocery List"
  • Verify ingredients are parsed and categorized correctly
  • Select an existing list or create new one
  • Click "Add X Items" button
  • Verify ingredients appear in the grocery list with recipe link
  • Test with various recipe formats (bullets, numbered, fractions)

spe1020 added 2 commits January 11, 2026 11:08
Implements a private grocery list feature using NIP-78 (kind 30078) for
application-specific data storage with NIP-44 self-encryption.

Features:
- Create, edit, and delete private grocery lists
- Add/remove items with categories (produce, dairy, meat, etc.)
- Track checked/unchecked items with progress indicator
- Link lists to recipes (for future integration)
- Debounced auto-save with explicit title editing
- Mobile-friendly responsive UI

Technical details:
- groceryService.ts: Handles Nostr event fetching, encryption, and publishing
- groceryStore.ts: Svelte store with reactive state management
- Local-first design preserves lists during navigation
- Falls back to window.nostr for NIP-07 extension encryption support

UI components:
- /grocery route with list overview and creation
- /grocery/[id] route for list details and item management
- Navigation link added to user side panel menu
Allows users to add ingredients from any recipe directly to their
grocery lists with automatic parsing and categorization.

New features:
- Ingredient parser extracts items from recipe markdown
- Parses quantities, units, and ingredient names
- Auto-categorizes (produce, protein, dairy, pantry, frozen, other)
- Modal to select or create grocery list
- Recipe link stored for traceability
- "Add to Grocery List" option in recipe menu (logged-in users)

New files:
- src/lib/utils/ingredientParser.ts
- src/components/grocery/AddToListModal.svelte

Modified:
- src/components/Recipe/Recipe.svelte - Added menu option
- src/lib/services/groceryService.ts - Added buildRecipeAddress helper
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jan 11, 2026

Deploying frontend with  Cloudflare Pages  Cloudflare Pages

Latest commit: 94d2fee
Status: ✅  Deploy successful!
Preview URL: https://8d08f09c.frontend-hvd.pages.dev
Branch Preview URL: https://feature-grocery-recipe-integ.frontend-hvd.pages.dev

View logs

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a comprehensive recipe-to-grocery-list integration feature that allows users to automatically extract ingredients from recipes and add them to encrypted, private grocery lists stored on Nostr.

Changes:

  • Adds ingredient parsing utilities with quantity/unit extraction and automatic categorization
  • Implements encrypted grocery list storage using NIP-78 and NIP-44 encryption
  • Creates a complete grocery list management UI with CRUD operations and recipe linking

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
src/lib/utils/ingredientParser.ts New utility for parsing recipe ingredients with quantity/unit extraction and category inference
src/lib/stores/groceryStore.ts Svelte store managing grocery list state with debounced saves and reactive access
src/lib/services/groceryService.ts Core service handling encrypted grocery list storage on Nostr using NIP-78/NIP-44
src/components/grocery/AddToListModal.svelte Modal UI for selecting/creating grocery lists and previewing parsed ingredients
src/components/grocery/GroceryListCard.svelte Card component displaying grocery list summary with progress tracking
src/components/grocery/GroceryItemRow.svelte Individual item row with checkbox and delete functionality
src/components/grocery/AddItemForm.svelte Form for manually adding items to grocery lists with auto-categorization
src/routes/grocery/+page.svelte Main grocery lists page with list overview and creation
src/routes/grocery/[id]/+page.svelte Individual grocery list detail page with item management
src/components/Recipe/Recipe.svelte Adds "Add to Grocery List" menu option for logged-in users
src/components/UserSidePanel.svelte Adds navigation link to grocery lists section
src/lib/encryptionService.ts Improves encryption fallback logic for better NIP-07 extension support

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/lib/utils/ingredientParser.ts
Comment thread src/lib/services/groceryService.ts
Comment thread src/lib/encryptionService.ts
Comment thread src/components/grocery/AddToListModal.svelte
Comment thread src/lib/utils/ingredientParser.ts Outdated
Comment thread src/components/grocery/AddToListModal.svelte
Comment thread src/lib/utils/ingredientParser.ts
Comment thread src/lib/services/groceryService.ts Outdated
Comment thread src/components/grocery/AddToListModal.svelte
Comment thread src/components/grocery/AddToListModal.svelte
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jan 11, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
frontend 94d2fee Jan 11 2026, 05:36 PM

spe1020 and others added 2 commits January 11, 2026 11:50
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 11, 2026

@spe1020 I've opened a new pull request, #85, to work on those changes. Once the pull request is ready, I'll request review from you.

spe1020 and others added 2 commits January 11, 2026 11:58
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 11, 2026

@spe1020 I've opened a new pull request, #86, to work on those changes. Once the pull request is ready, I'll request review from you.

@spe1020 spe1020 merged commit ac946c1 into main Jan 11, 2026
2 checks passed
spe1020 added a commit that referenced this pull request May 1, 2026
* security: bump vite to ^5.4.21 [closes #235 #236]

Made-with: Cursor

* security: bump @sveltejs/kit [closes #106]

Made-with: Cursor

* chore: bump @sveltejs/adapter-cloudflare for vite 6 compat

Made-with: Cursor

* security: bump wrangler [closes #74]

Made-with: Cursor

* security: bump markdown-it to ^14.1.1 [refs #84 #86 — defensive timeout in follow-up]

Made-with: Cursor

* security: override js-yaml to patched line [closes #51]

Made-with: Cursor

* security: bump @sveltejs/adapter-vercel [closes #95]

Made-with: Cursor

* chore: migrate _routes.json config to adapter-cloudflare 7.x format

Made-with: Cursor

---------

Co-authored-by: spe1020 <sethsager@Seths-MacBook-Air.local>
spe1020 added a commit that referenced this pull request May 1, 2026
* security(dompurify): sanitize DM bubble output [refs #213]

Made-with: Cursor

* security(dompurify): sanitize mention composer output [refs #213]

Made-with: Cursor

* security(dompurify): bump dompurify [closes #213 #243 #245 #247]

Made-with: Cursor

* security(dompurify): add sanitizer regression tests [refs #213 #243 #245 #247]

Made-with: Cursor

* test(security): fix sanitize regression test typecheck harness

Made-with: Cursor

* test(security): address copilot review on sanitizer regression tests

- Import sanitizeHTML at top of file for the 7 tests that don't need a
  fresh module evaluation. Down from 8 module re-imports + hook
  registrations per file run to 2, addressing the hook-accumulation
  concern raised in PR #371 review.
- Preserve original Object.prototype descriptors for tagNameCheck /
  attributeNameCheck via getOwnPropertyDescriptor and restore them
  exactly (or Reflect.deleteProperty when originally absent), instead
  of unconditionally `delete`-ing in finally.
- Same pattern for the SSR test's globalThis.window override: capture
  the full original descriptor and restore it precisely.
- Inline rationale on why the prototype-pollution test does NOT need
  module re-evaluation (dompurify resolves CUSTOM_ELEMENT_HANDLING
  config at sanitize-call time, not at module init).

* security: rewrite pnpm.overrides to use range floors [closes GHSA-2mjp-6q6p-2qxm GHSA-34x7-hfp2-rc4v GHSA-3v7f-55p6-f55p GHSA-4992-7rv2-5pvq GHSA-737v-mqg7-c878 GHSA-83g3-92jg-28cx GHSA-8qm3-746x-r74r GHSA-8qq5-rm4j-mr97 GHSA-9ppj-qmqm-q256 GHSA-cfw5-2vxh-hr84 GHSA-f23m-r3pf-42rh GHSA-f269-vfmq-vjvj GHSA-mwv9-gp5h-frr4 GHSA-qffp-2rhf-9h96 GHSA-qx2v-qp2m-jg93 GHSA-r5fr-rjxr-66jc GHSA-r6q2-hw4h-h46w GHSA-xxjr-mmjv-4gpg]

Made-with: Cursor

* security(overrides): tighten range floors to caret-bounded majors

Address PR #372 copilot review:

1. Open-ended `>=X.Y.Z` floors could allow a future major release to
   resolve in during a lockfile regen, potentially breaking builds or
   runtime behavior. Convert all `pnpm.overrides` to `^X.Y.Z` to keep
   the security floor while pinning to the current major. Resolved
   versions in pnpm-lock.yaml are unchanged (tar@7.5.13, dompurify@3.4.2,
   picomatch@4.0.4, minimatch@10.2.5, etc.).

2. Aligns the dompurify override (`^3.4.2`) with the direct
   devDependency declaration so the lockfile importer specifier and
   package.json declaration are consistent — addresses the confusing
   `>=3.4.2` vs `^3.4.2` mismatch flagged on pnpm-lock.yaml.

Verified: pnpm install clean, pnpm test 85/85 pass, pnpm run check 0
errors, pnpm run build succeeds, audit shows no regression.

* security: bump vite to ^5.4.21 [closes #235 #236]

Made-with: Cursor

* security: bump @sveltejs/kit [closes #106]

Made-with: Cursor

* chore: bump @sveltejs/adapter-cloudflare for vite 6 compat

Made-with: Cursor

* security: bump wrangler [closes #74]

Made-with: Cursor

* security: bump markdown-it to ^14.1.1 [refs #84 #86 — defensive timeout in follow-up]

Made-with: Cursor

* security: override js-yaml to patched line [closes #51]

Made-with: Cursor

* security: bump @sveltejs/adapter-vercel [closes #95]

Made-with: Cursor

* chore: migrate _routes.json config to adapter-cloudflare 7.x format

Made-with: Cursor

---------

Co-authored-by: spe1020 <sethsager@Seths-MacBook-Air.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants