Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
import React, { useState, useMemo } from 'react';
|
|
|
|
|
import { ChefHat } from 'lucide-react';
|
|
|
|
|
import { WizardModal, WizardStep } from '../../../ui/WizardModal/WizardModal';
|
|
|
|
|
import { RecipeProductStep } from './RecipeProductStep';
|
|
|
|
|
import { RecipeIngredientsStep } from './RecipeIngredientsStep';
|
|
|
|
|
import { RecipeProductionStep } from './RecipeProductionStep';
|
|
|
|
|
import { RecipeReviewStep } from './RecipeReviewStep';
|
Implement Phase 3: Advanced post-onboarding features (JTBD-driven UX)
Complete JTBD implementation with 4 advanced features to reduce friction and accelerate configuration for non-technical bakery owners.
**1. Recipe Templates Library:**
- Add RecipeTemplateSelector modal with searchable template gallery
- Pre-built templates: Baguette, Pan de Molde, Medialunas, Facturas, Bizcochuelo, Galletas
- Smart ingredient matching between templates and user's inventory
- Category filtering (Panes, Facturas, Tortas, Galletitas)
- One-click template loading with pre-filled wizard data
- "Create from scratch" option for custom recipes
- Integrated as pre-wizard step in RecipeWizardModal
**2. Bulk Supplier CSV Import:**
- Add BulkSupplierImportModal with CSV upload & parsing
- Downloadable CSV template with examples
- Live validation with error detection
- Preview table showing valid/invalid rows
- Multi-column support (15+ fields: name, type, email, phone, payment terms, address, etc.)
- Batch import with progress tracking
- Success/error notifications
**3. Configuration Recovery (Auto-save):**
- Add useWizardDraft hook with localStorage persistence
- Auto-save wizard progress every 30 seconds
- 7-day draft expiration (configurable TTL)
- DraftRecoveryPrompt component for restore/discard choice
- Shows "saved X time ago" with human-friendly formatting
- Prevents data loss from accidental browser closes
**4. Milestone Notifications (Feature Unlocks):**
- Add Toast notification system (ToastNotification, ToastContainer, useToast hook)
- Support for success, error, info, and milestone toast types
- Animated slide-in/slide-out transitions
- Auto-dismiss with configurable duration
- useFeatureUnlocks hook to track when features are unlocked
- Visual feedback for configuration milestones
**Benefits:**
- Templates: Reduce recipe creation time from 10+ min to <2 min
- Bulk Import: Add 50+ suppliers in seconds vs hours
- Auto-save: Zero data loss from accidental exits
- Notifications: Clear feedback on progress and unlocked capabilities
Files:
- RecipeTemplateSelector: Template library UI
- BulkSupplierImportModal: CSV import system
- useWizardDraft + DraftRecoveryPrompt: Auto-save infrastructure
- Toast system + useToast + useFeatureUnlocks: Notification framework
Part of 3-phase JTBD implementation (Phase 1: Progress Widget, Phase 2: Wizards, Phase 3: Advanced Features).
2025-11-06 18:07:54 +00:00
|
|
|
import { RecipeTemplateSelector } from './RecipeTemplateSelector';
|
Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
import type { RecipeCreate, RecipeIngredientCreate, MeasurementUnit } from '../../../../api/types/recipes';
|
|
|
|
|
import { useIngredients } from '../../../../api/hooks/inventory';
|
|
|
|
|
import { useCurrentTenant } from '../../../../stores/tenant.store';
|
|
|
|
|
|
|
|
|
|
interface RecipeWizardModalProps {
|
|
|
|
|
isOpen: boolean;
|
|
|
|
|
onClose: () => void;
|
|
|
|
|
onCreateRecipe: (recipeData: RecipeCreate) => Promise<void>;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const RecipeWizardModal: React.FC<RecipeWizardModalProps> = ({
|
|
|
|
|
isOpen,
|
|
|
|
|
onClose,
|
|
|
|
|
onCreateRecipe
|
|
|
|
|
}) => {
|
Implement Phase 3: Advanced post-onboarding features (JTBD-driven UX)
Complete JTBD implementation with 4 advanced features to reduce friction and accelerate configuration for non-technical bakery owners.
**1. Recipe Templates Library:**
- Add RecipeTemplateSelector modal with searchable template gallery
- Pre-built templates: Baguette, Pan de Molde, Medialunas, Facturas, Bizcochuelo, Galletas
- Smart ingredient matching between templates and user's inventory
- Category filtering (Panes, Facturas, Tortas, Galletitas)
- One-click template loading with pre-filled wizard data
- "Create from scratch" option for custom recipes
- Integrated as pre-wizard step in RecipeWizardModal
**2. Bulk Supplier CSV Import:**
- Add BulkSupplierImportModal with CSV upload & parsing
- Downloadable CSV template with examples
- Live validation with error detection
- Preview table showing valid/invalid rows
- Multi-column support (15+ fields: name, type, email, phone, payment terms, address, etc.)
- Batch import with progress tracking
- Success/error notifications
**3. Configuration Recovery (Auto-save):**
- Add useWizardDraft hook with localStorage persistence
- Auto-save wizard progress every 30 seconds
- 7-day draft expiration (configurable TTL)
- DraftRecoveryPrompt component for restore/discard choice
- Shows "saved X time ago" with human-friendly formatting
- Prevents data loss from accidental browser closes
**4. Milestone Notifications (Feature Unlocks):**
- Add Toast notification system (ToastNotification, ToastContainer, useToast hook)
- Support for success, error, info, and milestone toast types
- Animated slide-in/slide-out transitions
- Auto-dismiss with configurable duration
- useFeatureUnlocks hook to track when features are unlocked
- Visual feedback for configuration milestones
**Benefits:**
- Templates: Reduce recipe creation time from 10+ min to <2 min
- Bulk Import: Add 50+ suppliers in seconds vs hours
- Auto-save: Zero data loss from accidental exits
- Notifications: Clear feedback on progress and unlocked capabilities
Files:
- RecipeTemplateSelector: Template library UI
- BulkSupplierImportModal: CSV import system
- useWizardDraft + DraftRecoveryPrompt: Auto-save infrastructure
- Toast system + useToast + useFeatureUnlocks: Notification framework
Part of 3-phase JTBD implementation (Phase 1: Progress Widget, Phase 2: Wizards, Phase 3: Advanced Features).
2025-11-06 18:07:54 +00:00
|
|
|
// Template selector state
|
|
|
|
|
const [showTemplateSelector, setShowTemplateSelector] = useState(true);
|
|
|
|
|
const [wizardStarted, setWizardStarted] = useState(false);
|
|
|
|
|
|
Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
// Recipe state
|
|
|
|
|
const [recipeData, setRecipeData] = useState<Partial<RecipeCreate>>({
|
|
|
|
|
difficulty_level: 1,
|
|
|
|
|
yield_quantity: 1,
|
|
|
|
|
yield_unit: 'units' as MeasurementUnit,
|
|
|
|
|
serves_count: 1,
|
|
|
|
|
prep_time_minutes: 0,
|
|
|
|
|
cook_time_minutes: 0,
|
|
|
|
|
rest_time_minutes: 0,
|
|
|
|
|
target_margin_percentage: 30,
|
|
|
|
|
batch_size_multiplier: 1.0,
|
|
|
|
|
is_seasonal: false,
|
|
|
|
|
is_signature_item: false,
|
|
|
|
|
ingredients: [{
|
|
|
|
|
ingredient_id: '',
|
|
|
|
|
quantity: 1,
|
|
|
|
|
unit: 'grams' as MeasurementUnit,
|
|
|
|
|
ingredient_order: 1,
|
|
|
|
|
is_optional: false
|
|
|
|
|
}]
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Get tenant and fetch data
|
|
|
|
|
const currentTenant = useCurrentTenant();
|
|
|
|
|
const tenantId = currentTenant?.id || '';
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
data: inventoryItems = [],
|
|
|
|
|
isLoading: inventoryLoading
|
|
|
|
|
} = useIngredients(tenantId, {});
|
|
|
|
|
|
|
|
|
|
// Separate finished products and ingredients
|
|
|
|
|
const finishedProducts = useMemo(() =>
|
|
|
|
|
(inventoryItems || [])
|
|
|
|
|
.filter(item => item.product_type === 'finished_product')
|
|
|
|
|
.map(product => ({
|
|
|
|
|
value: product.id,
|
|
|
|
|
label: `${product.name} (${product.category || 'Sin categoría'})`
|
|
|
|
|
})),
|
|
|
|
|
[inventoryItems]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const availableIngredients = useMemo(() =>
|
|
|
|
|
(inventoryItems || [])
|
|
|
|
|
.filter(item => item.product_type !== 'finished_product')
|
|
|
|
|
.map(ingredient => ({
|
|
|
|
|
value: ingredient.id,
|
|
|
|
|
label: `${ingredient.name} (${ingredient.category || 'Sin categoría'})`
|
|
|
|
|
})),
|
|
|
|
|
[inventoryItems]
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Create map of ingredient IDs to names for display
|
|
|
|
|
const ingredientNames = useMemo(() => {
|
|
|
|
|
const map = new Map<string, string>();
|
|
|
|
|
inventoryItems.forEach(item => {
|
|
|
|
|
map.set(item.id, item.name);
|
|
|
|
|
});
|
|
|
|
|
return map;
|
|
|
|
|
}, [inventoryItems]);
|
|
|
|
|
|
|
|
|
|
// Options
|
|
|
|
|
const categoryOptions = [
|
|
|
|
|
{ value: 'bread', label: 'Pan' },
|
|
|
|
|
{ value: 'pastry', label: 'Bollería' },
|
|
|
|
|
{ value: 'cake', label: 'Tarta' },
|
|
|
|
|
{ value: 'cookie', label: 'Galleta' },
|
|
|
|
|
{ value: 'muffin', label: 'Muffin' },
|
|
|
|
|
{ value: 'savory', label: 'Salado' },
|
|
|
|
|
{ value: 'desserts', label: 'Postres' },
|
|
|
|
|
{ value: 'specialty', label: 'Especialidad' },
|
|
|
|
|
{ value: 'other', label: 'Otro' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const cuisineTypeOptions = [
|
|
|
|
|
{ value: 'french', label: 'Francés' },
|
|
|
|
|
{ value: 'spanish', label: 'Español' },
|
|
|
|
|
{ value: 'italian', label: 'Italiano' },
|
|
|
|
|
{ value: 'german', label: 'Alemán' },
|
|
|
|
|
{ value: 'american', label: 'Americano' },
|
|
|
|
|
{ value: 'artisanal', label: 'Artesanal' },
|
|
|
|
|
{ value: 'traditional', label: 'Tradicional' },
|
|
|
|
|
{ value: 'modern', label: 'Moderno' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const unitOptions = [
|
|
|
|
|
{ value: 'units' as MeasurementUnit, label: 'Unidades' },
|
|
|
|
|
{ value: 'pieces' as MeasurementUnit, label: 'Piezas' },
|
|
|
|
|
{ value: 'grams' as MeasurementUnit, label: 'Gramos' },
|
|
|
|
|
{ value: 'kilograms' as MeasurementUnit, label: 'Kilogramos' },
|
|
|
|
|
{ value: 'milliliters' as MeasurementUnit, label: 'Mililitros' },
|
|
|
|
|
{ value: 'liters' as MeasurementUnit, label: 'Litros' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const handleUpdate = (data: Partial<RecipeCreate>) => {
|
|
|
|
|
setRecipeData(data);
|
|
|
|
|
};
|
|
|
|
|
|
Implement Phase 3: Advanced post-onboarding features (JTBD-driven UX)
Complete JTBD implementation with 4 advanced features to reduce friction and accelerate configuration for non-technical bakery owners.
**1. Recipe Templates Library:**
- Add RecipeTemplateSelector modal with searchable template gallery
- Pre-built templates: Baguette, Pan de Molde, Medialunas, Facturas, Bizcochuelo, Galletas
- Smart ingredient matching between templates and user's inventory
- Category filtering (Panes, Facturas, Tortas, Galletitas)
- One-click template loading with pre-filled wizard data
- "Create from scratch" option for custom recipes
- Integrated as pre-wizard step in RecipeWizardModal
**2. Bulk Supplier CSV Import:**
- Add BulkSupplierImportModal with CSV upload & parsing
- Downloadable CSV template with examples
- Live validation with error detection
- Preview table showing valid/invalid rows
- Multi-column support (15+ fields: name, type, email, phone, payment terms, address, etc.)
- Batch import with progress tracking
- Success/error notifications
**3. Configuration Recovery (Auto-save):**
- Add useWizardDraft hook with localStorage persistence
- Auto-save wizard progress every 30 seconds
- 7-day draft expiration (configurable TTL)
- DraftRecoveryPrompt component for restore/discard choice
- Shows "saved X time ago" with human-friendly formatting
- Prevents data loss from accidental browser closes
**4. Milestone Notifications (Feature Unlocks):**
- Add Toast notification system (ToastNotification, ToastContainer, useToast hook)
- Support for success, error, info, and milestone toast types
- Animated slide-in/slide-out transitions
- Auto-dismiss with configurable duration
- useFeatureUnlocks hook to track when features are unlocked
- Visual feedback for configuration milestones
**Benefits:**
- Templates: Reduce recipe creation time from 10+ min to <2 min
- Bulk Import: Add 50+ suppliers in seconds vs hours
- Auto-save: Zero data loss from accidental exits
- Notifications: Clear feedback on progress and unlocked capabilities
Files:
- RecipeTemplateSelector: Template library UI
- BulkSupplierImportModal: CSV import system
- useWizardDraft + DraftRecoveryPrompt: Auto-save infrastructure
- Toast system + useToast + useFeatureUnlocks: Notification framework
Part of 3-phase JTBD implementation (Phase 1: Progress Widget, Phase 2: Wizards, Phase 3: Advanced Features).
2025-11-06 18:07:54 +00:00
|
|
|
const handleSelectTemplate = (templateData: Partial<RecipeCreate>) => {
|
|
|
|
|
setRecipeData({
|
|
|
|
|
...recipeData,
|
|
|
|
|
...templateData
|
|
|
|
|
});
|
|
|
|
|
setShowTemplateSelector(false);
|
|
|
|
|
setWizardStarted(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleStartFromScratch = () => {
|
|
|
|
|
setShowTemplateSelector(false);
|
|
|
|
|
setWizardStarted(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleCloseWizard = () => {
|
|
|
|
|
setShowTemplateSelector(true);
|
|
|
|
|
setWizardStarted(false);
|
|
|
|
|
setRecipeData({
|
|
|
|
|
difficulty_level: 1,
|
|
|
|
|
yield_quantity: 1,
|
|
|
|
|
yield_unit: 'units' as MeasurementUnit,
|
|
|
|
|
serves_count: 1,
|
|
|
|
|
prep_time_minutes: 0,
|
|
|
|
|
cook_time_minutes: 0,
|
|
|
|
|
rest_time_minutes: 0,
|
|
|
|
|
target_margin_percentage: 30,
|
|
|
|
|
batch_size_multiplier: 1.0,
|
|
|
|
|
is_seasonal: false,
|
|
|
|
|
is_signature_item: false,
|
|
|
|
|
ingredients: [{
|
|
|
|
|
ingredient_id: '',
|
|
|
|
|
quantity: 1,
|
|
|
|
|
unit: 'grams' as MeasurementUnit,
|
|
|
|
|
ingredient_order: 1,
|
|
|
|
|
is_optional: false
|
|
|
|
|
}]
|
|
|
|
|
});
|
|
|
|
|
onClose();
|
|
|
|
|
};
|
|
|
|
|
|
Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
const handleComplete = async () => {
|
|
|
|
|
try {
|
|
|
|
|
// Generate recipe code if not provided
|
|
|
|
|
const recipeCode = recipeData.recipe_code ||
|
|
|
|
|
(recipeData.name?.substring(0, 3).toUpperCase() || 'RCP') +
|
|
|
|
|
String(Date.now()).slice(-3);
|
|
|
|
|
|
|
|
|
|
// Calculate total time
|
|
|
|
|
const totalTime = (recipeData.prep_time_minutes || 0) +
|
|
|
|
|
(recipeData.cook_time_minutes || 0) +
|
|
|
|
|
(recipeData.rest_time_minutes || 0);
|
|
|
|
|
|
|
|
|
|
// Filter and validate ingredients
|
|
|
|
|
const validIngredients = (recipeData.ingredients || [])
|
|
|
|
|
.filter((ing: RecipeIngredientCreate) => ing.ingredient_id && ing.ingredient_id.trim() !== '')
|
|
|
|
|
.map((ing: RecipeIngredientCreate, index: number) => ({
|
|
|
|
|
...ing,
|
|
|
|
|
ingredient_order: index + 1
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
if (validIngredients.length === 0) {
|
|
|
|
|
throw new Error('Debe agregar al menos un ingrediente válido');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Build final recipe data
|
|
|
|
|
const finalRecipeData: RecipeCreate = {
|
|
|
|
|
name: recipeData.name!,
|
|
|
|
|
recipe_code: recipeCode,
|
|
|
|
|
version: recipeData.version || '1.0',
|
|
|
|
|
finished_product_id: recipeData.finished_product_id!,
|
|
|
|
|
description: recipeData.description || '',
|
|
|
|
|
category: recipeData.category!,
|
|
|
|
|
cuisine_type: recipeData.cuisine_type || '',
|
|
|
|
|
difficulty_level: recipeData.difficulty_level!,
|
|
|
|
|
yield_quantity: recipeData.yield_quantity!,
|
|
|
|
|
yield_unit: recipeData.yield_unit!,
|
|
|
|
|
prep_time_minutes: recipeData.prep_time_minutes || 0,
|
|
|
|
|
cook_time_minutes: recipeData.cook_time_minutes || 0,
|
|
|
|
|
total_time_minutes: totalTime,
|
|
|
|
|
rest_time_minutes: recipeData.rest_time_minutes || 0,
|
|
|
|
|
target_margin_percentage: recipeData.target_margin_percentage || 30,
|
|
|
|
|
instructions: null,
|
|
|
|
|
preparation_notes: recipeData.preparation_notes || '',
|
|
|
|
|
storage_instructions: recipeData.storage_instructions || '',
|
|
|
|
|
quality_check_configuration: null,
|
|
|
|
|
serves_count: recipeData.serves_count || 1,
|
|
|
|
|
is_seasonal: recipeData.is_seasonal || false,
|
|
|
|
|
season_start_month: recipeData.is_seasonal ? recipeData.season_start_month : undefined,
|
|
|
|
|
season_end_month: recipeData.is_seasonal ? recipeData.season_end_month : undefined,
|
|
|
|
|
is_signature_item: recipeData.is_signature_item || false,
|
|
|
|
|
batch_size_multiplier: recipeData.batch_size_multiplier || 1.0,
|
|
|
|
|
minimum_batch_size: recipeData.minimum_batch_size,
|
|
|
|
|
maximum_batch_size: recipeData.maximum_batch_size,
|
|
|
|
|
optimal_production_temperature: recipeData.optimal_production_temperature,
|
|
|
|
|
optimal_humidity: recipeData.optimal_humidity,
|
|
|
|
|
allergen_info: recipeData.allergen_info || null,
|
|
|
|
|
dietary_tags: recipeData.dietary_tags || null,
|
|
|
|
|
nutritional_info: recipeData.nutritional_info || null,
|
|
|
|
|
ingredients: validIngredients
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await onCreateRecipe(finalRecipeData);
|
|
|
|
|
|
|
|
|
|
// Reset state
|
Implement Phase 3: Advanced post-onboarding features (JTBD-driven UX)
Complete JTBD implementation with 4 advanced features to reduce friction and accelerate configuration for non-technical bakery owners.
**1. Recipe Templates Library:**
- Add RecipeTemplateSelector modal with searchable template gallery
- Pre-built templates: Baguette, Pan de Molde, Medialunas, Facturas, Bizcochuelo, Galletas
- Smart ingredient matching between templates and user's inventory
- Category filtering (Panes, Facturas, Tortas, Galletitas)
- One-click template loading with pre-filled wizard data
- "Create from scratch" option for custom recipes
- Integrated as pre-wizard step in RecipeWizardModal
**2. Bulk Supplier CSV Import:**
- Add BulkSupplierImportModal with CSV upload & parsing
- Downloadable CSV template with examples
- Live validation with error detection
- Preview table showing valid/invalid rows
- Multi-column support (15+ fields: name, type, email, phone, payment terms, address, etc.)
- Batch import with progress tracking
- Success/error notifications
**3. Configuration Recovery (Auto-save):**
- Add useWizardDraft hook with localStorage persistence
- Auto-save wizard progress every 30 seconds
- 7-day draft expiration (configurable TTL)
- DraftRecoveryPrompt component for restore/discard choice
- Shows "saved X time ago" with human-friendly formatting
- Prevents data loss from accidental browser closes
**4. Milestone Notifications (Feature Unlocks):**
- Add Toast notification system (ToastNotification, ToastContainer, useToast hook)
- Support for success, error, info, and milestone toast types
- Animated slide-in/slide-out transitions
- Auto-dismiss with configurable duration
- useFeatureUnlocks hook to track when features are unlocked
- Visual feedback for configuration milestones
**Benefits:**
- Templates: Reduce recipe creation time from 10+ min to <2 min
- Bulk Import: Add 50+ suppliers in seconds vs hours
- Auto-save: Zero data loss from accidental exits
- Notifications: Clear feedback on progress and unlocked capabilities
Files:
- RecipeTemplateSelector: Template library UI
- BulkSupplierImportModal: CSV import system
- useWizardDraft + DraftRecoveryPrompt: Auto-save infrastructure
- Toast system + useToast + useFeatureUnlocks: Notification framework
Part of 3-phase JTBD implementation (Phase 1: Progress Widget, Phase 2: Wizards, Phase 3: Advanced Features).
2025-11-06 18:07:54 +00:00
|
|
|
handleCloseWizard();
|
Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Error creating recipe:', error);
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Define wizard steps
|
|
|
|
|
const steps: WizardStep[] = [
|
|
|
|
|
{
|
|
|
|
|
id: 'product',
|
|
|
|
|
title: 'Información del Producto',
|
|
|
|
|
description: 'Configura los datos básicos de la receta',
|
|
|
|
|
component: (props) => (
|
|
|
|
|
<RecipeProductStep
|
|
|
|
|
{...props}
|
|
|
|
|
recipeData={recipeData}
|
|
|
|
|
onUpdate={handleUpdate}
|
|
|
|
|
finishedProducts={finishedProducts}
|
|
|
|
|
categoryOptions={categoryOptions}
|
|
|
|
|
cuisineTypeOptions={cuisineTypeOptions}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
validate: () => {
|
|
|
|
|
return !!(
|
|
|
|
|
recipeData.name &&
|
|
|
|
|
recipeData.name.trim().length >= 2 &&
|
|
|
|
|
recipeData.finished_product_id &&
|
|
|
|
|
recipeData.category
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'ingredients',
|
|
|
|
|
title: 'Ingredientes',
|
|
|
|
|
description: 'Agrega los ingredientes necesarios',
|
|
|
|
|
component: (props) => (
|
|
|
|
|
<RecipeIngredientsStep
|
|
|
|
|
{...props}
|
|
|
|
|
recipeData={recipeData}
|
|
|
|
|
onUpdate={handleUpdate}
|
|
|
|
|
availableIngredients={availableIngredients}
|
|
|
|
|
unitOptions={unitOptions}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
validate: () => {
|
|
|
|
|
const ingredients = recipeData.ingredients || [];
|
|
|
|
|
return ingredients.length > 0 &&
|
|
|
|
|
ingredients.some(ing => ing.ingredient_id && ing.ingredient_id.trim() !== '' && ing.quantity > 0);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'production',
|
|
|
|
|
title: 'Detalles de Producción',
|
|
|
|
|
description: 'Define tiempos y parámetros',
|
|
|
|
|
component: (props) => (
|
|
|
|
|
<RecipeProductionStep
|
|
|
|
|
{...props}
|
|
|
|
|
recipeData={recipeData}
|
|
|
|
|
onUpdate={handleUpdate}
|
|
|
|
|
unitOptions={unitOptions}
|
|
|
|
|
/>
|
|
|
|
|
),
|
|
|
|
|
validate: () => {
|
|
|
|
|
return !!(recipeData.yield_quantity && Number(recipeData.yield_quantity) > 0 && recipeData.yield_unit);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'review',
|
|
|
|
|
title: 'Instrucciones y Revisión',
|
|
|
|
|
description: 'Completa las instrucciones y revisa',
|
|
|
|
|
component: (props) => (
|
|
|
|
|
<RecipeReviewStep
|
|
|
|
|
{...props}
|
|
|
|
|
recipeData={recipeData}
|
|
|
|
|
onUpdate={handleUpdate}
|
|
|
|
|
ingredientNames={ingredientNames}
|
|
|
|
|
/>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
Implement Phase 3: Advanced post-onboarding features (JTBD-driven UX)
Complete JTBD implementation with 4 advanced features to reduce friction and accelerate configuration for non-technical bakery owners.
**1. Recipe Templates Library:**
- Add RecipeTemplateSelector modal with searchable template gallery
- Pre-built templates: Baguette, Pan de Molde, Medialunas, Facturas, Bizcochuelo, Galletas
- Smart ingredient matching between templates and user's inventory
- Category filtering (Panes, Facturas, Tortas, Galletitas)
- One-click template loading with pre-filled wizard data
- "Create from scratch" option for custom recipes
- Integrated as pre-wizard step in RecipeWizardModal
**2. Bulk Supplier CSV Import:**
- Add BulkSupplierImportModal with CSV upload & parsing
- Downloadable CSV template with examples
- Live validation with error detection
- Preview table showing valid/invalid rows
- Multi-column support (15+ fields: name, type, email, phone, payment terms, address, etc.)
- Batch import with progress tracking
- Success/error notifications
**3. Configuration Recovery (Auto-save):**
- Add useWizardDraft hook with localStorage persistence
- Auto-save wizard progress every 30 seconds
- 7-day draft expiration (configurable TTL)
- DraftRecoveryPrompt component for restore/discard choice
- Shows "saved X time ago" with human-friendly formatting
- Prevents data loss from accidental browser closes
**4. Milestone Notifications (Feature Unlocks):**
- Add Toast notification system (ToastNotification, ToastContainer, useToast hook)
- Support for success, error, info, and milestone toast types
- Animated slide-in/slide-out transitions
- Auto-dismiss with configurable duration
- useFeatureUnlocks hook to track when features are unlocked
- Visual feedback for configuration milestones
**Benefits:**
- Templates: Reduce recipe creation time from 10+ min to <2 min
- Bulk Import: Add 50+ suppliers in seconds vs hours
- Auto-save: Zero data loss from accidental exits
- Notifications: Clear feedback on progress and unlocked capabilities
Files:
- RecipeTemplateSelector: Template library UI
- BulkSupplierImportModal: CSV import system
- useWizardDraft + DraftRecoveryPrompt: Auto-save infrastructure
- Toast system + useToast + useFeatureUnlocks: Notification framework
Part of 3-phase JTBD implementation (Phase 1: Progress Widget, Phase 2: Wizards, Phase 3: Advanced Features).
2025-11-06 18:07:54 +00:00
|
|
|
<>
|
|
|
|
|
{/* Template Selector */}
|
|
|
|
|
<RecipeTemplateSelector
|
|
|
|
|
isOpen={isOpen && showTemplateSelector && !wizardStarted}
|
|
|
|
|
onClose={handleCloseWizard}
|
|
|
|
|
onSelectTemplate={handleSelectTemplate}
|
|
|
|
|
onStartFromScratch={handleStartFromScratch}
|
|
|
|
|
availableIngredients={availableIngredients.map(ing => ({ id: ing.value, name: ing.label }))}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Wizard Modal */}
|
|
|
|
|
<WizardModal
|
|
|
|
|
isOpen={isOpen && !showTemplateSelector && wizardStarted}
|
|
|
|
|
onClose={handleCloseWizard}
|
|
|
|
|
onComplete={handleComplete}
|
|
|
|
|
title="Nueva Receta"
|
|
|
|
|
steps={steps}
|
|
|
|
|
icon={<ChefHat className="w-6 h-6" />}
|
|
|
|
|
size="2xl"
|
|
|
|
|
/>
|
|
|
|
|
</>
|
Implement Phase 2: Recipe & Supplier wizard modals (JTBD-driven UX)
Following Jobs-To-Be-Done analysis, break down complex forms into multi-step wizards to reduce cognitive load for non-technical bakery owners.
**Core Infrastructure:**
- Add reusable WizardModal component with progress tracking, validation, and navigation
- Multi-step progress bar with clickable previous steps
- Per-step validation with clear error messaging
- Back/Next/Complete navigation with loading states
- Optional step skipping support
- Responsive modal design (sm/md/lg/xl/2xl sizes)
**Recipe Wizard (4 steps):**
- Step 1 (Product): Name, category, finished product, cuisine type, difficulty, description
- Step 2 (Ingredients): Dynamic ingredient list with add/remove, quantities, units, optional flags
- Step 3 (Production): Times (prep/cook/rest), yield, batch sizes, temperature, humidity, special flags
- Step 4 (Review): Instructions, storage, nutritional info, allergens, final summary
**Supplier Wizard (3 steps):**
- Step 1 (Basic): Name, type, status, contact person, email, phone, tax ID, registration
- Step 2 (Delivery): Payment terms, lead time, minimum order, delivery schedule, address
- Step 3 (Review): Certifications, sustainability practices, notes, summary
**Benefits:**
- Reduces form overwhelm from 8 sections to 4 sequential steps (recipes) and 3 steps (suppliers)
- Clear progress indication and next actions
- Validation feedback per step instead of at end
- Summary review before final submission
- Matches mental model of "configure then review" workflow
Files:
- WizardModal: Reusable wizard infrastructure
- RecipeWizard: 4-step recipe creation (Product → Ingredients → Production → Review)
- SupplierWizard: 3-step supplier creation (Basic → Delivery → Review)
Related to Phase 1 (ConfigurationProgressWidget) for post-onboarding guidance.
2025-11-06 18:01:11 +00:00
|
|
|
);
|
|
|
|
|
};
|