feat: shopping list rename/delete, item reorder+categories+search, ingredient-quantity parsing fix
- Fixed a real i18n bug: the checked-count line called the wrong translation namespace and rendered the literal key on screen - Shopping lists can now be renamed and deleted from both the list index and detail pages (API already supported delete; rename was net new) - Root-caused "long list UI is off": meal-plan-generated lists never set an aisle, so every item fell into one undifferentiated "Other" bucket despite the grouping UI existing. Added a keyword-based aisle guesser wired into list generation (fallback only, never overrides an explicit aisle) plus a one-click "auto-categorize" for existing lists - Items can now be reordered by drag-and-drop within a category (dnd-kit), recategorized via a dropdown, deleted, searched, and sorted (category / alphabetical / unchecked-first); searching flattens the grouped view - Fixed a separate bug: AI-generated ingredients sometimes embedded the quantity/unit in the name itself (e.g. "2 cups flour" as one string). Added extractIngredientQuantity() as a Zod transform at both recipe create/update routes (the choke point every creation path funnels through) to split it back out, plus schema descriptions on the AI ingredient schemas as a prevention layer New migration 0028 (shopping_list_items.sort_order), left unapplied like the others. Verified with typecheck, lint, and a clean --no-cache docker build. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -654,6 +654,16 @@
|
||||
"aisleOther": "Other",
|
||||
"listEmptyState": "This list is empty.",
|
||||
"checkedCount": "{checked}/{total} checked",
|
||||
"searchItemsPlaceholder": "Search items…",
|
||||
"sortByCategory": "By category",
|
||||
"sortByAlpha": "Alphabetical",
|
||||
"sortByUnchecked": "Unchecked first",
|
||||
"noSearchResults": "No items match your search.",
|
||||
"autoCategorize": "Auto-categorize",
|
||||
"autoCategorizeSuccess": "{count, plural, one {1 item categorized} other {{count} items categorized}}",
|
||||
"autoCategorizeNoneFound": "Couldn't guess a category for the remaining items",
|
||||
"removeItemConfirmTitle": "Remove item?",
|
||||
"removeItemConfirmDescription": "Remove \"{name}\" from this list?",
|
||||
"moveToPantry": "Move {count} to pantry",
|
||||
"listCreated": "List created",
|
||||
"days": {
|
||||
@@ -803,7 +813,20 @@
|
||||
"ingredientsWillBeAdded": "{count, plural, one {1 ingredient will be added.} other {{count} ingredients will be added.}}",
|
||||
"adding": "Adding…",
|
||||
"addIngredients": "Add ingredients",
|
||||
"addedCount": "{count} ingredients added to list"
|
||||
"addedCount": "{count} ingredients added to list",
|
||||
"actionsMenuLabel": "List actions",
|
||||
"rename": "Rename",
|
||||
"renameListTitle": "Rename list",
|
||||
"renameListLabel": "List name",
|
||||
"renaming": "Saving…",
|
||||
"listRenamed": "List renamed",
|
||||
"listRenameFailed": "Failed to rename list",
|
||||
"deleteListConfirmTitle": "Delete list?",
|
||||
"deleteListConfirmDescription": "This action cannot be undone. The list and all its items will be permanently deleted.",
|
||||
"listDeleted": "List deleted",
|
||||
"listDeleteFailed": "Failed to delete list",
|
||||
"changeCategory": "Change category",
|
||||
"deleteItem": "Delete item"
|
||||
},
|
||||
"collections": {
|
||||
"title": "Collections",
|
||||
|
||||
Reference in New Issue
Block a user