From 330e4a06b1ed874c8f237be7b6d929f7913571c6 Mon Sep 17 00:00:00 2001 From: Urtzi Alfaro Date: Mon, 1 Sep 2025 08:13:01 +0200 Subject: [PATCH] Add onboarding pages --- .../components/domain/auth/RegisterForm.tsx | 54 +- frontend/src/config/mock.config.ts | 37 ++ .../analysis/OnboardingAnalysisPage.tsx | 16 + .../review/OnboardingReviewPage.tsx | 33 +- .../onboarding/setup/OnboardingSetupPage.tsx | 465 ++++++++++++++---- .../upload/OnboardingUploadPage.tsx | 16 + frontend/src/pages/public/RegisterPage.tsx | 2 +- frontend/src/router/ProtectedRoute.tsx | 8 + 8 files changed, 518 insertions(+), 113 deletions(-) create mode 100644 frontend/src/config/mock.config.ts diff --git a/frontend/src/components/domain/auth/RegisterForm.tsx b/frontend/src/components/domain/auth/RegisterForm.tsx index 679ea4b3..74ba20f9 100644 --- a/frontend/src/components/domain/auth/RegisterForm.tsx +++ b/frontend/src/components/domain/auth/RegisterForm.tsx @@ -3,6 +3,7 @@ import { Button, Input, Card } from '../../ui'; import { useAuth } from '../../../hooks/api/useAuth'; import { UserRegistration } from '../../../types/auth.types'; import { useToast } from '../../../hooks/ui/useToast'; +import { isMockRegistration } from '../../../config/mock.config'; interface RegisterFormProps { onSuccess?: () => void; @@ -36,7 +37,7 @@ export const RegisterForm: React.FC = ({ const [showConfirmPassword, setShowConfirmPassword] = useState(false); const { register, isLoading, error } = useAuth(); - const { showToast } = useToast(); + const { success: showSuccessToast, error: showErrorToast } = useToast(); const validateForm = (): boolean => { const newErrors: Partial = {}; @@ -75,6 +76,35 @@ export const RegisterForm: React.FC = ({ const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); + console.log('Form submitted, mock mode:', isMockRegistration()); + + // FORCED MOCK MODE FOR TESTING - Always bypass for now + const FORCE_MOCK = true; + if (FORCE_MOCK || isMockRegistration()) { + console.log('Mock registration triggered, showing toast and calling onSuccess'); + // Show immediate success notification + try { + showSuccessToast('¡Bienvenido! Tu cuenta ha sido creada correctamente.', { + title: 'Cuenta creada exitosamente' + }); + console.log('Toast shown, calling onSuccess callback'); + } catch (error) { + console.error('Error showing toast:', error); + // Fallback: show browser alert if toast fails + alert('¡Cuenta creada exitosamente! Redirigiendo al onboarding...'); + } + + // Call success immediately (removing delay for easier testing) + try { + onSuccess?.(); + console.log('onSuccess called'); + } catch (error) { + console.error('Error calling onSuccess:', error); + // Fallback: direct redirect if callback fails + window.location.href = '/app/onboarding/setup'; + } + return; + } if (!validateForm()) { return; @@ -92,24 +122,18 @@ export const RegisterForm: React.FC = ({ const success = await register(registrationData); if (success) { - showToast({ - type: 'success', - title: 'Cuenta creada exitosamente', - message: '¡Bienvenido! Tu cuenta ha sido creada correctamente.' + showSuccessToast('¡Bienvenido! Tu cuenta ha sido creada correctamente.', { + title: 'Cuenta creada exitosamente' }); onSuccess?.(); } else { - showToast({ - type: 'error', - title: 'Error al crear la cuenta', - message: error || 'No se pudo crear la cuenta. Verifica que el email no esté en uso.' + showErrorToast(error || 'No se pudo crear la cuenta. Verifica que el email no esté en uso.', { + title: 'Error al crear la cuenta' }); } } catch (err) { - showToast({ - type: 'error', - title: 'Error de conexión', - message: 'No se pudo conectar con el servidor. Verifica tu conexión a internet.' + showErrorToast('No se pudo conectar con el servidor. Verifica tu conexión a internet.', { + title: 'Error de conexión' }); } }; @@ -270,6 +294,10 @@ export const RegisterForm: React.FC = ({ loadingText="Creando cuenta..." disabled={isLoading} className="w-full" + onClick={(e) => { + console.log('Button clicked!'); + // Let form submit handle it naturally + }} > Crear Cuenta diff --git a/frontend/src/config/mock.config.ts b/frontend/src/config/mock.config.ts new file mode 100644 index 00000000..95810efb --- /dev/null +++ b/frontend/src/config/mock.config.ts @@ -0,0 +1,37 @@ +/** + * Mock configuration for testing the complete onboarding flow + * Set MOCK_MODE to false for production + */ + +export const MOCK_CONFIG = { + // Global mock mode toggle + MOCK_MODE: true, + + // Component-specific toggles + MOCK_REGISTRATION: true, + MOCK_AUTHENTICATION: true, + MOCK_ONBOARDING_FLOW: true, + + // Mock user data + MOCK_USER: { + full_name: 'María García López', + email: 'maria.garcia@elbuenpan.com', + role: 'admin', + tenant_name: 'Panadería Artesanal El Buen Pan' + }, + + // Mock bakery data + MOCK_BAKERY: { + name: 'Panadería Artesanal El Buen Pan', + type: 'artisan', + location: 'Av. Principal 123, Centro Histórico', + phone: '+1 234 567 8900', + email: 'info@elbuenpan.com' + } +}; + +// Helper function to check if mock mode is enabled +export const isMockMode = () => MOCK_CONFIG.MOCK_MODE; +export const isMockRegistration = () => MOCK_CONFIG.MOCK_MODE && MOCK_CONFIG.MOCK_REGISTRATION; +export const isMockAuthentication = () => MOCK_CONFIG.MOCK_MODE && MOCK_CONFIG.MOCK_AUTHENTICATION; +export const isMockOnboardingFlow = () => MOCK_CONFIG.MOCK_MODE && MOCK_CONFIG.MOCK_ONBOARDING_FLOW; \ No newline at end of file diff --git a/frontend/src/pages/app/onboarding/analysis/OnboardingAnalysisPage.tsx b/frontend/src/pages/app/onboarding/analysis/OnboardingAnalysisPage.tsx index 83b383cb..fe865b30 100644 --- a/frontend/src/pages/app/onboarding/analysis/OnboardingAnalysisPage.tsx +++ b/frontend/src/pages/app/onboarding/analysis/OnboardingAnalysisPage.tsx @@ -428,6 +428,22 @@ const OnboardingAnalysisPage: React.FC = () => { ))} + + {/* Navigation */} +
+ + + +
); }; diff --git a/frontend/src/pages/app/onboarding/review/OnboardingReviewPage.tsx b/frontend/src/pages/app/onboarding/review/OnboardingReviewPage.tsx index 44a715da..907ca35e 100644 --- a/frontend/src/pages/app/onboarding/review/OnboardingReviewPage.tsx +++ b/frontend/src/pages/app/onboarding/review/OnboardingReviewPage.tsx @@ -560,7 +560,13 @@ const OnboardingReviewPage: React.FC = () => { y el sistema está preparado para comenzar a operar.

- @@ -572,6 +578,31 @@ const OnboardingReviewPage: React.FC = () => {
)} + + {/* Overall Navigation - Always visible */} +
+ + +
+

Último paso del onboarding

+
+ + +
); }; diff --git a/frontend/src/pages/app/onboarding/setup/OnboardingSetupPage.tsx b/frontend/src/pages/app/onboarding/setup/OnboardingSetupPage.tsx index 1d74243e..7fb99bc8 100644 --- a/frontend/src/pages/app/onboarding/setup/OnboardingSetupPage.tsx +++ b/frontend/src/pages/app/onboarding/setup/OnboardingSetupPage.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { ChevronRight, ChevronLeft, Check, Store, Users, Settings, Zap } from 'lucide-react'; +import { ChevronRight, ChevronLeft, Check, Store, Users, Settings, Zap, Upload } from 'lucide-react'; import { Button, Card, Input } from '../../../../components/ui'; import { PageHeader } from '../../../../components/layout'; @@ -7,31 +7,38 @@ const OnboardingSetupPage: React.FC = () => { const [currentStep, setCurrentStep] = useState(1); const [formData, setFormData] = useState({ bakery: { - name: '', - type: 'traditional', + name: 'Panadería Artesanal El Buen Pan', + type: 'artisan', size: 'medium', - location: '', - phone: '', - email: '' + location: 'Av. Principal 123, Centro Histórico', + phone: '+1 234 567 8900', + email: 'info@elbuenpan.com' }, team: { - ownerName: '', + ownerName: 'María García López', teamSize: '5-10', roles: [], - experience: 'intermediate' + experience: 'experienced' }, operations: { openingHours: { - start: '07:00', + start: '06:00', end: '20:00' }, daysOpen: 6, - specialties: [], + specialties: ['bread', 'pastries', 'cakes'], dailyProduction: 'medium' }, + upload: { + salesData: null, + inventoryData: null, + recipeData: null, + useTemplates: true, + skipUpload: false + }, goals: { - primaryGoals: [], - expectedRevenue: '', + primaryGoals: ['increase-sales', 'reduce-waste', 'improve-efficiency'], + expectedRevenue: '15000-30000', timeline: '6months' } }); @@ -60,6 +67,13 @@ const OnboardingSetupPage: React.FC = () => { }, { id: 4, + title: 'Carga de Datos', + description: 'Importa tus datos existentes para acelerar la configuración inicial', + icon: Upload, + fields: ['files', 'templates', 'validation'] + }, + { + id: 5, title: 'Objetivos', description: 'Metas y expectativas para tu panadería', icon: Zap, @@ -135,7 +149,8 @@ const OnboardingSetupPage: React.FC = () => { const handleFinish = () => { console.log('Onboarding completed:', formData); - // Handle completion logic + // Navigate to dashboard - onboarding is complete + window.location.href = '/app/dashboard'; }; const isStepComplete = (stepId: number) => { @@ -148,6 +163,9 @@ const OnboardingSetupPage: React.FC = () => { case 3: return formData.operations.specialties.length > 0; case 4: + return formData.upload.useTemplates || formData.upload.skipUpload || + (formData.upload.salesData || formData.upload.inventoryData || formData.upload.recipeData); + case 5: return formData.goals.primaryGoals.length > 0; default: return false; @@ -158,34 +176,76 @@ const OnboardingSetupPage: React.FC = () => { switch (currentStep) { case 1: return ( -
-
-