'use client' import { useState, FormEvent } from 'react' import { tenantService } from '../services/tenant.service' import type { TenantCreateRequest, TenantCreateResponse } from '../types/tenant' interface TenantCreateFormProps { onSuccess: (response: TenantCreateResponse) => void onCancel?: () => void } interface FormData { code: string name: string name_eng: string tax_id: string prefix: string tel: string add: string url: string plan_id: string max_users: number storage_quota_gb: number admin_username: string admin_email: string admin_name: string admin_temp_password: string } interface FormErrors { [key: string]: string } export default function TenantCreateForm({ onSuccess, onCancel }: TenantCreateFormProps) { const [formData, setFormData] = useState({ code: '', name: '', name_eng: '', tax_id: '', prefix: '', tel: '', add: '', url: '', plan_id: 'starter', max_users: 5, storage_quota_gb: 100, admin_username: '', admin_email: '', admin_name: '', admin_temp_password: '', }) const [errors, setErrors] = useState({}) const [loading, setLoading] = useState(false) const [apiError, setApiError] = useState(null) const validateForm = (): boolean => { const newErrors: FormErrors = {} // Required fields if (!formData.code.trim()) { newErrors.code = 'Tenant code is required' } if (!formData.name.trim()) { newErrors.name = 'Company name is required' } if (!formData.prefix.trim()) { newErrors.prefix = 'Employee prefix is required' } if (!formData.admin_username.trim()) { newErrors.admin_username = 'Admin username is required' } if (!formData.admin_email.trim()) { newErrors.admin_email = 'Admin email is required' } else if (!formData.admin_email.includes('@')) { // Email format validation (only if not empty) newErrors.admin_email = 'Invalid email format' } if (!formData.admin_name.trim()) { newErrors.admin_name = 'Admin name is required' } if (!formData.admin_temp_password.trim()) { newErrors.admin_temp_password = 'Admin password is required' } else if (formData.admin_temp_password.length < 8) { // Password length validation (only if not empty) newErrors.admin_temp_password = 'Password must be at least 8 characters' } // Tax ID validation (8 digits if provided) if (formData.tax_id && !/^\d{8}$/.test(formData.tax_id)) { newErrors.tax_id = 'Tax ID must be 8 digits' } setErrors(newErrors) return Object.keys(newErrors).length === 0 } const handleSubmit = async (e: FormEvent) => { e.preventDefault() setApiError(null) if (!validateForm()) { return } setLoading(true) try { const requestData: TenantCreateRequest = { code: formData.code, name: formData.name, name_eng: formData.name_eng || '', tax_id: formData.tax_id || undefined, prefix: formData.prefix, tel: formData.tel || '', add: formData.add || '', url: formData.url || '', plan_id: formData.plan_id, max_users: formData.max_users, storage_quota_gb: formData.storage_quota_gb, admin_username: formData.admin_username, admin_email: formData.admin_email, admin_name: formData.admin_name, admin_temp_password: formData.admin_temp_password, } const response = await tenantService.createTenant(requestData) // Reset form setFormData({ code: '', name: '', name_eng: '', tax_id: '', prefix: '', tel: '', add: '', url: '', plan_id: 'starter', max_users: 5, storage_quota_gb: 100, admin_username: '', admin_email: '', admin_name: '', admin_temp_password: '', }) onSuccess(response) } catch (error: any) { const errorMessage = error?.response?.data?.detail || 'Failed to create tenant. Please try again.' setApiError(errorMessage) } finally { setLoading(false) } } const handleChange = (field: keyof FormData, value: string | number) => { setFormData((prev) => ({ ...prev, [field]: value, })) // Clear error when user starts typing if (errors[field]) { setErrors((prev) => { const newErrors = { ...prev } delete newErrors[field] return newErrors }) } } return (
{/* API Error Display */} {apiError && (

{apiError}

)} {/* Basic Information Section */}

Basic Information

handleChange('code', e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" /> {errors.code &&

{errors.code}

}
handleChange('name', e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" /> {errors.name &&

{errors.name}

}
handleChange('name_eng', e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />
handleChange('tax_id', e.target.value)} placeholder="8 digits" className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" /> {errors.tax_id &&

{errors.tax_id}

}
handleChange('prefix', e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" /> {errors.prefix &&

{errors.prefix}

}
{/* Contact Information Section */}

Contact Information

handleChange('tel', e.target.value)} className="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500" />