feat: private accounts, explore/people merge, meal-plan fixes, i18n and theme cleanup

- Private accounts: users.isPrivate hides a user from search and their
  recipes from search/trending/for-you discovery surfaces (follow-aware
  where the route already has session context, blanket exclusion where it
  doesn't); existing followers and direct links are unaffected, no
  follow-request approval flow was built (explicit scope limit)
- Merged /people into the Explore tab (tab=people query param); the old
  standalone route now redirects there
- "Get Ideas" vs "Surprise Me" were doing the same empty-prompt call;
  Surprise Me now injects a real random constraint (5-ingredient, one-pot,
  etc.), matching the existing pattern in the AI recipe-generate dialog
- Meal-plan day cells now link to their recipe (was dead text) and gained
  a one-click "mark as cooked" action
- Theme toggle is now a real three-way light/dark/system control instead
  of a binary flip
- Nutrition goals form had zero i18n wiring; fully localized now

New migration 0027 (users.is_private) generated, 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:
Arnaud
2026-07-10 09:26:03 +02:00
parent 36e7698096
commit 9c545a5bb3
20 changed files with 4804 additions and 82 deletions
+24 -4
View File
@@ -19,7 +19,8 @@
"notifications": "Notifications",
"viewProfile": "View profile",
"lightMode": "Light mode",
"darkMode": "Dark mode"
"darkMode": "Dark mode",
"systemMode": "System"
},
"notifications": {
"title": "Notifications",
@@ -305,7 +306,19 @@
"nutritionGoals": {
"title": "Daily Nutrition Goals",
"description": "Set your daily targets. These are shown as progress bars on your meal plan.",
"viewDiaryCta": "View nutrition diary"
"viewDiaryCta": "View nutrition diary",
"caloriesLabel": "Calories (kcal/day)",
"proteinLabel": "Protein (g/day)",
"carbsLabel": "Carbs (g/day)",
"fatLabel": "Fat (g/day)",
"caloriesPlaceholder": "e.g. 2000",
"proteinPlaceholder": "e.g. 50",
"carbsPlaceholder": "e.g. 250",
"fatPlaceholder": "e.g. 70",
"saveButton": "Save goals",
"saving": "Saving...",
"saveSuccess": "Nutrition goals saved",
"saveError": "Failed to save nutrition goals"
},
"webhooksPage": {
"title": "Webhooks",
@@ -423,6 +436,8 @@
},
"explore": {
"title": "Explore",
"tabRecipes": "Recipes",
"tabPeople": "People",
"searchPlaceholder": "Search public recipes…",
"maxMinutes": "Max minutes",
"aiSearchPlaceholder": "e.g. quick weeknight dinners, Italian comfort food…",
@@ -689,7 +704,10 @@
"listCreate": "Create",
"pickRecipe": "Pick recipe",
"addEntry": "+ Add",
"removeEntry": "Remove meal"
"removeEntry": "Remove meal",
"markCooked": "Mark as cooked",
"markCookedSuccess": "Marked as cooked",
"markCookedFailed": "Failed to mark as cooked"
},
"pantry": {
"title": "Pantry",
@@ -1026,7 +1044,9 @@
"publicBioPlaceholder": "Tell other cooks about yourself…",
"privateBio": "AI context (private)",
"privateBioDescription": "Never shown publicly. Injected into AI prompts to personalise suggestions — add your dietary preferences, kitchen equipment, cooking skill level, allergies, etc.",
"privateBioPlaceholder": "e.g. I'm vegetarian, have a stand mixer and an air fryer, intermediate cook, allergic to tree nuts, prefer Mediterranean flavours…"
"privateBioPlaceholder": "e.g. I'm vegetarian, have a stand mixer and an air fryer, intermediate cook, allergic to tree nuts, prefer Mediterranean flavours…",
"privateAccount": "Private account",
"privateAccountDescription": "When on, your profile and recipes won't appear in search or discovery (Explore, Trending, For You). People who already follow you keep seeing your recipes."
},
"profilePage": {
"tabRecipes": "Recipes",