Imporve onboarding UI
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Button, Input } from '../../../ui';
|
||||
import { AddressAutocomplete } from '../../../ui/AddressAutocomplete';
|
||||
import { useRegisterBakery } from '../../../../api/hooks/tenant';
|
||||
import { BakeryRegistration } from '../../../../api/types/tenant';
|
||||
import { useRegisterBakery, useTenant, useUpdateTenant } from '../../../../api/hooks/tenant';
|
||||
import { BakeryRegistration, TenantUpdate } from '../../../../api/types/tenant';
|
||||
import { AddressResult } from '../../../../services/api/geocodingApi';
|
||||
import { useWizardContext } from '../context';
|
||||
import { poiContextApi } from '../../../../services/api/poiContextApi';
|
||||
@@ -34,6 +34,7 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
isFirstStep
|
||||
}) => {
|
||||
const wizardContext = useWizardContext();
|
||||
const tenantId = wizardContext.state.tenantId;
|
||||
|
||||
// Check if user is enterprise tier for conditional labels
|
||||
const subscriptionTier = localStorage.getItem('subscription_tier');
|
||||
@@ -52,8 +53,31 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
business_model: businessModel
|
||||
});
|
||||
|
||||
// Fetch existing tenant data if we have a tenantId (persistence)
|
||||
const { data: existingTenant, isLoading: isLoadingTenant } = useTenant(tenantId || '');
|
||||
|
||||
// Update formData when existing tenant data is fetched
|
||||
useEffect(() => {
|
||||
if (existingTenant) {
|
||||
console.log('🔄 Populating RegisterTenantStep with existing data:', existingTenant);
|
||||
setFormData({
|
||||
name: existingTenant.name,
|
||||
address: existingTenant.address,
|
||||
postal_code: existingTenant.postal_code,
|
||||
phone: existingTenant.phone || '',
|
||||
city: existingTenant.city,
|
||||
business_type: existingTenant.business_type,
|
||||
business_model: existingTenant.business_model || businessModel
|
||||
});
|
||||
|
||||
// Update location in context if available from tenant
|
||||
// Note: Backend might not store lat/lon directly in Tenant table in all versions,
|
||||
// but if we had them or if we want to re-trigger geocoding, we'd handle it here.
|
||||
}
|
||||
}, [existingTenant, businessModel]);
|
||||
|
||||
// Update business_model when bakeryType changes in context
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
const newBusinessModel = getBakeryBusinessModel(wizardContext.state.bakeryType);
|
||||
if (newBusinessModel !== formData.business_model) {
|
||||
setFormData(prev => ({
|
||||
@@ -65,6 +89,7 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
|
||||
const [errors, setErrors] = useState<Record<string, string>>({});
|
||||
const registerBakery = useRegisterBakery();
|
||||
const updateTenant = useUpdateTenant();
|
||||
|
||||
const handleInputChange = (field: keyof BakeryRegistration, value: string) => {
|
||||
setFormData(prev => ({
|
||||
@@ -143,14 +168,31 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('📝 Registering tenant with data:', {
|
||||
console.log('📝 Submitting tenant data:', {
|
||||
isUpdate: !!tenantId,
|
||||
bakeryType: wizardContext.state.bakeryType,
|
||||
business_model: formData.business_model,
|
||||
formData
|
||||
});
|
||||
|
||||
try {
|
||||
const tenant = await registerBakery.mutateAsync(formData);
|
||||
let tenant;
|
||||
if (tenantId) {
|
||||
// Update existing tenant
|
||||
const updateData: TenantUpdate = {
|
||||
name: formData.name,
|
||||
address: formData.address,
|
||||
phone: formData.phone,
|
||||
business_type: formData.business_type,
|
||||
business_model: formData.business_model
|
||||
};
|
||||
tenant = await updateTenant.mutateAsync({ tenantId, updateData });
|
||||
console.log('✅ Tenant updated successfully:', tenant.id);
|
||||
} else {
|
||||
// Create new tenant
|
||||
tenant = await registerBakery.mutateAsync(formData);
|
||||
console.log('✅ Tenant registered successfully:', tenant.id);
|
||||
}
|
||||
|
||||
// Trigger POI detection in the background (non-blocking)
|
||||
// This replaces the removed POI Detection step
|
||||
@@ -203,29 +245,51 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4 md:space-y-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-6">
|
||||
<Input
|
||||
label={isEnterprise ? "Nombre del Obrador Central" : "Nombre de la Panadería"}
|
||||
placeholder={isEnterprise ? "Ingresa el nombre de tu obrador central" : "Ingresa el nombre de tu panadería"}
|
||||
value={formData.name}
|
||||
onChange={(e) => handleInputChange('name', e.target.value)}
|
||||
error={errors.name}
|
||||
isRequired
|
||||
/>
|
||||
<div className="space-y-6 md:space-y-8">
|
||||
{/* Informational header */}
|
||||
<div className="bg-gradient-to-r from-[var(--color-primary)]/10 to-[var(--color-primary)]/5 border-l-4 border-[var(--color-primary)] rounded-lg p-4 md:p-5">
|
||||
<div className="flex items-start gap-3">
|
||||
<div className="text-2xl flex-shrink-0">{isEnterprise ? '🏭' : '🏪'}</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-[var(--text-primary)] mb-1">
|
||||
{isEnterprise ? 'Registra tu Obrador Central' : 'Registra tu Panadería'}
|
||||
</h3>
|
||||
<p className="text-sm text-[var(--text-secondary)]">
|
||||
{isEnterprise
|
||||
? 'Ingresa los datos de tu obrador principal. Después podrás agregar las sucursales.'
|
||||
: 'Completa la información básica de tu panadería para comenzar.'}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
label="Teléfono"
|
||||
type="tel"
|
||||
placeholder="+34 123 456 789"
|
||||
value={formData.phone}
|
||||
onChange={(e) => handleInputChange('phone', e.target.value)}
|
||||
error={errors.phone}
|
||||
isRequired
|
||||
/>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-5 md:gap-6">
|
||||
<div className="transform transition-all duration-200 hover:scale-[1.01]">
|
||||
<Input
|
||||
label={isEnterprise ? "Nombre del Obrador Central" : "Nombre de la Panadería"}
|
||||
placeholder={isEnterprise ? "Ingresa el nombre de tu obrador central" : "Ingresa el nombre de tu panadería"}
|
||||
value={formData.name}
|
||||
onChange={(e) => handleInputChange('name', e.target.value)}
|
||||
error={errors.name}
|
||||
isRequired
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-2">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
<div className="transform transition-all duration-200 hover:scale-[1.01]">
|
||||
<Input
|
||||
label="Teléfono"
|
||||
type="tel"
|
||||
placeholder="+34 123 456 789"
|
||||
value={formData.phone}
|
||||
onChange={(e) => handleInputChange('phone', e.target.value)}
|
||||
error={errors.phone}
|
||||
isRequired
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-2 transform transition-all duration-200 hover:scale-[1.01] relative z-20">
|
||||
<label className="block text-sm font-semibold text-[var(--text-primary)] mb-2 flex items-center gap-2">
|
||||
<span className="text-lg">📍</span>
|
||||
Dirección <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<AddressAutocomplete
|
||||
@@ -240,45 +304,60 @@ export const RegisterTenantStep: React.FC<RegisterTenantStepProps> = ({
|
||||
required
|
||||
/>
|
||||
{errors.address && (
|
||||
<div className="mt-1 text-sm text-red-600">
|
||||
<div className="mt-2 text-sm text-red-600 flex items-center gap-1.5 animate-shake">
|
||||
<span>⚠️</span>
|
||||
{errors.address}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Input
|
||||
label="Código Postal"
|
||||
placeholder="28001"
|
||||
value={formData.postal_code}
|
||||
onChange={(e) => handleInputChange('postal_code', e.target.value)}
|
||||
error={errors.postal_code}
|
||||
isRequired
|
||||
maxLength={5}
|
||||
/>
|
||||
<div className="transform transition-all duration-200 hover:scale-[1.01]">
|
||||
<Input
|
||||
label="Código Postal"
|
||||
placeholder="28001"
|
||||
value={formData.postal_code}
|
||||
onChange={(e) => handleInputChange('postal_code', e.target.value)}
|
||||
error={errors.postal_code}
|
||||
isRequired
|
||||
maxLength={5}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Input
|
||||
label="Ciudad (Opcional)"
|
||||
placeholder="Madrid"
|
||||
value={formData.city}
|
||||
onChange={(e) => handleInputChange('city', e.target.value)}
|
||||
error={errors.city}
|
||||
/>
|
||||
<div className="transform transition-all duration-200 hover:scale-[1.01]">
|
||||
<Input
|
||||
label="Ciudad (Opcional)"
|
||||
placeholder="Madrid"
|
||||
value={formData.city}
|
||||
onChange={(e) => handleInputChange('city', e.target.value)}
|
||||
error={errors.city}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{errors.submit && (
|
||||
<div className="text-[var(--color-error)] text-sm bg-[var(--color-error)]/10 p-3 rounded-lg">
|
||||
{errors.submit}
|
||||
<div className="bg-gradient-to-r from-[var(--color-error)]/10 to-[var(--color-error)]/5 border-l-4 border-[var(--color-error)] rounded-lg p-4 animate-shake">
|
||||
<div className="flex items-start gap-3">
|
||||
<span className="text-2xl flex-shrink-0">⚠️</span>
|
||||
<div>
|
||||
<h4 className="font-semibold text-[var(--color-error)] mb-1">Error al registrar</h4>
|
||||
<p className="text-sm text-[var(--text-secondary)]">{errors.submit}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end">
|
||||
<div className="flex justify-end pt-4 border-t-2 border-[var(--border-color)]/50">
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
isLoading={registerBakery.isPending}
|
||||
loadingText={isEnterprise ? "Registrando obrador..." : "Registrando..."}
|
||||
isLoading={registerBakery.isPending || updateTenant.isPending}
|
||||
loadingText={tenantId ? "Actualizando obrador..." : (isEnterprise ? "Registrando obrador..." : "Registrando...")}
|
||||
size="lg"
|
||||
className="w-full sm:w-auto sm:min-w-[280px] text-base font-semibold transform transition-all duration-300 hover:scale-105 shadow-lg"
|
||||
>
|
||||
{isEnterprise ? "Crear Obrador Central y Continuar" : "Crear Panadería y Continuar"}
|
||||
{tenantId
|
||||
? (isEnterprise ? "Actualizar Obrador Central y Continuar →" : "Actualizar Panadería y Continuar →")
|
||||
: (isEnterprise ? "Crear Obrador Central y Continuar →" : "Crear Panadería y Continuar →")
|
||||
}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user