From 188211623564af307dee6d0a76fdf4177fe4215c Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Tue, 14 Apr 2026 13:53:54 -0700 Subject: [PATCH] feat: UX polish for Build Your Own tab and default landing - Default app landing changed from Pantry to Recipes tab - Pre-fetch inventory on app mount so Find tab has data immediately - Reorder recipe sub-tabs: Saved > Build Your Own > Community > Find > Browse - Default active sub-tab changed to Saved - Auto-redirect from Saved to Build Your Own when saved list is empty - Add freeform custom ingredient input: typing a non-pantry item now shows "Use X anyway" button so users aren't blocked on unknown ingredients --- frontend/src/App.vue | 7 +++- frontend/src/components/BuildYourOwnTab.vue | 37 ++++++++++++++++----- frontend/src/components/RecipesView.vue | 27 +++++++++++---- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 327b6e3..066830e 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -170,7 +170,7 @@ import { householdAPI } from './services/api' type Tab = 'inventory' | 'receipts' | 'recipes' | 'settings' -const currentTab = ref('inventory') +const currentTab = ref('recipes') const sidebarCollapsed = ref(false) const inventoryStore = useInventoryStore() const { kiwiVisible, kiwiDirection } = useEasterEggs() @@ -198,6 +198,11 @@ async function switchTab(tab: Tab) { } onMounted(async () => { + // Pre-fetch inventory so Recipes tab has data on first load + if (inventoryStore.items.length === 0) { + await inventoryStore.fetchItems() + } + // Handle household invite links: /#/join?household_id=xxx&token=yyy const hash = window.location.hash if (hash.includes('/join')) { diff --git a/frontend/src/components/BuildYourOwnTab.vue b/frontend/src/components/BuildYourOwnTab.vue index d2b8071..108f8b7 100644 --- a/frontend/src/components/BuildYourOwnTab.vue +++ b/frontend/src/components/BuildYourOwnTab.vue @@ -132,14 +132,24 @@ - -

- Nothing in your pantry fits this role yet. You can skip it or - -

+ +
@@ -273,6 +283,17 @@ function toggleIngredient(name: string) { roleOverrides.value = { ...roleOverrides.value, [role]: [...current] } } +function useCustomIngredient() { + const name = filterText.value.trim() + if (!name) return + const role = currentRole.value?.display + if (!role) return + const current = new Set(roleOverrides.value[role] ?? []) + current.add(name) + roleOverrides.value = { ...roleOverrides.value, [role]: [...current] } + filterText.value = '' +} + async function selectTemplate(tmpl: AssemblyTemplateOut) { selectedTemplate.value = tmpl wizardStep.value = 0 diff --git a/frontend/src/components/RecipesView.vue b/frontend/src/components/RecipesView.vue index ab8ca89..0c4f579 100644 --- a/frontend/src/components/RecipesView.vue +++ b/frontend/src/components/RecipesView.vue @@ -595,9 +595,10 @@