Add new frontend - fix 20
This commit is contained in:
@@ -61,7 +61,7 @@ export class AuthService {
|
|||||||
*/
|
*/
|
||||||
async getCurrentUser(): Promise<UserProfile> {
|
async getCurrentUser(): Promise<UserProfile> {
|
||||||
const response = await apiClient.get<UserProfile>('/users/me');
|
const response = await apiClient.get<UserProfile>('/users/me');
|
||||||
return response.data!;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
async register(userData: RegisterRequest): Promise<TokenResponse> {
|
async register(userData: RegisterRequest): Promise<TokenResponse> {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export type {
|
|||||||
TenantStats,
|
TenantStats,
|
||||||
TenantUser,
|
TenantUser,
|
||||||
InviteUser,
|
InviteUser,
|
||||||
|
TenantInfo
|
||||||
} from './tenantService';
|
} from './tenantService';
|
||||||
|
|
||||||
// Create a unified API object for convenience
|
// Create a unified API object for convenience
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
// src/api/services/NotificationService.ts
|
// src/api/services/NotificationService.ts
|
||||||
import { apiClient } from '../base/apiClient';
|
import { apiClient } from '../base/apiClient';
|
||||||
import {
|
import {
|
||||||
ApiResponse,
|
ApiResponse
|
||||||
NotificationSettings
|
|
||||||
} from '@/api/services';
|
} from '@/api/services';
|
||||||
|
|
||||||
export interface NotificationCreate {
|
export interface NotificationCreate {
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export class TenantService {
|
|||||||
*/
|
*/
|
||||||
async registerBakery(bakeryData: TenantCreate): Promise<TenantInfo> {
|
async registerBakery(bakeryData: TenantCreate): Promise<TenantInfo> {
|
||||||
const response = await apiClient.post<TenantInfo>('/api/v1/tenants/register', bakeryData);
|
const response = await apiClient.post<TenantInfo>('/api/v1/tenants/register', bakeryData);
|
||||||
return response.data!;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -4,10 +4,6 @@ import {
|
|||||||
ApiResponse
|
ApiResponse
|
||||||
} from '../types/api';
|
} from '../types/api';
|
||||||
|
|
||||||
import {
|
|
||||||
ApiResponse
|
|
||||||
} from '@/api/services';
|
|
||||||
|
|
||||||
export interface TrainingJobStatus {
|
export interface TrainingJobStatus {
|
||||||
id: string;
|
id: string;
|
||||||
tenant_id: string;
|
tenant_id: string;
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ import {
|
|||||||
XMarkIcon
|
XMarkIcon
|
||||||
} from '@heroicons/react/24/outline';
|
} from '@heroicons/react/24/outline';
|
||||||
|
|
||||||
// Real API services imports
|
// Updated imports in onboarding.tsx
|
||||||
import {
|
import {
|
||||||
TenantUser,
|
TenantUser,
|
||||||
} from '@/api/services';
|
TenantCreate,
|
||||||
|
TenantInfo
|
||||||
|
} from '@/api/services';
|
||||||
|
|
||||||
import api from '@/api/services';
|
import api from '@/api/services';
|
||||||
|
|
||||||
@@ -30,14 +31,27 @@ const OnboardingPage = () => {
|
|||||||
const [notification, setNotification] = useState(null);
|
const [notification, setNotification] = useState(null);
|
||||||
const [currentTenantId, setCurrentTenantId] = useState(null);
|
const [currentTenantId, setCurrentTenantId] = useState(null);
|
||||||
const [formData, setFormData] = useState({
|
const [formData, setFormData] = useState({
|
||||||
|
// User registration fields
|
||||||
full_name: '',
|
full_name: '',
|
||||||
email: '',
|
email: '',
|
||||||
password: '',
|
password: '',
|
||||||
confirm_password: '',
|
confirm_password: '',
|
||||||
|
|
||||||
|
// Bakery/Tenant fields - matching TenantCreate interface
|
||||||
bakery_name: '',
|
bakery_name: '',
|
||||||
address: '',
|
address: '',
|
||||||
city: 'Madrid',
|
city: 'Madrid',
|
||||||
postal_code: '',
|
postal_code: '',
|
||||||
|
phone: '', // Will use default if empty
|
||||||
|
business_type: 'individual_bakery' as 'individual_bakery' | 'central_workshop',
|
||||||
|
|
||||||
|
// Optional fields
|
||||||
|
latitude: undefined as number | undefined,
|
||||||
|
longitude: undefined as number | undefined,
|
||||||
|
subscription_plan: undefined as string | undefined,
|
||||||
|
settings: undefined as Record<string, any> | undefined,
|
||||||
|
|
||||||
|
// Additional form fields
|
||||||
has_nearby_schools: false,
|
has_nearby_schools: false,
|
||||||
has_nearby_offices: false,
|
has_nearby_offices: false,
|
||||||
selected_products: ['Pan de molde', 'Croissants', 'Magdalenas'],
|
selected_products: ['Pan de molde', 'Croissants', 'Magdalenas'],
|
||||||
@@ -45,7 +59,6 @@ const OnboardingPage = () => {
|
|||||||
trainingStatus: 'pending',
|
trainingStatus: 'pending',
|
||||||
trainingTaskId: null,
|
trainingTaskId: null,
|
||||||
trainingProgress: 0,
|
trainingProgress: 0,
|
||||||
business_type: 'bakery'
|
|
||||||
});
|
});
|
||||||
const [errors, setErrors] = useState({});
|
const [errors, setErrors] = useState({});
|
||||||
const [uploadValidation, setUploadValidation] = useState(null);
|
const [uploadValidation, setUploadValidation] = useState(null);
|
||||||
@@ -138,6 +151,17 @@ const OnboardingPage = () => {
|
|||||||
if (!formData.bakery_name.trim()) newErrors.bakery_name = 'Nombre de panadería requerido';
|
if (!formData.bakery_name.trim()) newErrors.bakery_name = 'Nombre de panadería requerido';
|
||||||
if (!formData.address.trim()) newErrors.address = 'Dirección requerida';
|
if (!formData.address.trim()) newErrors.address = 'Dirección requerida';
|
||||||
if (!formData.postal_code.trim()) newErrors.postal_code = 'Código postal requerido';
|
if (!formData.postal_code.trim()) newErrors.postal_code = 'Código postal requerido';
|
||||||
|
if (!formData.email.trim()) newErrors.email = 'Email requerido'; // Email is required for TenantCreate
|
||||||
|
|
||||||
|
// Validate business_type is one of the allowed values
|
||||||
|
if (!['individual_bakery', 'central_workshop'].includes(formData.business_type)) {
|
||||||
|
newErrors.business_type = 'Tipo de negocio inválido';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional: Validate phone format if provided (will use default if empty)
|
||||||
|
if (formData.phone && !formData.phone.match(/^(\+34|34)?[67][0-9]{8}$/)) {
|
||||||
|
newErrors.phone = 'Formato de teléfono inválido';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if (!formData.salesFile) newErrors.salesFile = 'Archivo de ventas requerido';
|
if (!formData.salesFile) newErrors.salesFile = 'Archivo de ventas requerido';
|
||||||
@@ -165,21 +189,26 @@ const OnboardingPage = () => {
|
|||||||
const user = await api.auth.register(userData);
|
const user = await api.auth.register(userData);
|
||||||
showNotification('success', 'Usuario creado', 'Cuenta registrada exitosamente.');
|
showNotification('success', 'Usuario creado', 'Cuenta registrada exitosamente.');
|
||||||
|
|
||||||
} else if (currentStep === 2) {
|
} else if (currentStep === 2) {
|
||||||
// Register bakery using real tenant service
|
// Register bakery using real tenant service with proper TenantCreate interface
|
||||||
const bakeryData = {
|
const bakeryData: TenantCreate = {
|
||||||
name: formData.bakery_name,
|
name: formData.bakery_name,
|
||||||
business_type: formData.business_type,
|
email: formData.email, // Required field from TenantCreate interface
|
||||||
address: formData.address,
|
phone: formData.phone || '+34600000000', // Required field with default
|
||||||
city: formData.city,
|
address: formData.address,
|
||||||
postal_code: formData.postal_code,
|
business_type: formData.business_type as 'individual_bakery' | 'central_workshop',
|
||||||
phone: formData.phone || '+34600000000' // Default phone if not provided
|
// Optional fields that could be added based on form data
|
||||||
};
|
latitude: formData.latitude, // if you have coordinates
|
||||||
|
longitude: formData.longitude, // if you have coordinates
|
||||||
const tenant = await api.tenant.registerBakery(bakeryData);
|
subscription_plan: formData.subscription_plan, // if selected
|
||||||
setCurrentTenantId(tenant.id);
|
settings: formData.settings // if any initial settings
|
||||||
showNotification('success', 'Panadería registrada', 'Información guardada correctamente.');
|
};
|
||||||
|
|
||||||
|
// The response will be typed as TenantInfo
|
||||||
|
const tenant: TenantInfo = await api.tenant.registerBakery(bakeryData);
|
||||||
|
setCurrentTenantId(tenant.id);
|
||||||
|
showNotification('success', 'Panadería registrada', 'Información guardada correctamente.');
|
||||||
|
|
||||||
} else if (currentStep === 3) {
|
} else if (currentStep === 3) {
|
||||||
// Upload and validate sales data using real data service
|
// Upload and validate sales data using real data service
|
||||||
if (formData.salesFile) {
|
if (formData.salesFile) {
|
||||||
|
|||||||
Reference in New Issue
Block a user