profit-planet-frontend/src/app/register/components/RegisterForm.tsx
2026-05-03 22:20:17 +02:00

1005 lines
36 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState, useEffect, useRef } from 'react'
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
import { useRegister } from '../hooks/useRegister'
import { useToast } from '../../components/toast/toastComponent'
import TelephoneInput, { TelephoneInputHandle } from '../../components/phone/telephoneInput'
import { useTranslation } from '../../i18n/useTranslation'
interface RegisterFormProps {
mode: 'personal' | 'company' | 'guest'
setMode: (mode: 'personal' | 'company' | 'guest') => void
refToken: string | null
onRegistered: () => void
referrerEmail?: string
}
interface PersonalFormData {
firstName: string
lastName: string
email: string
confirmEmail: string
password: string
confirmPassword: string
phoneNumber: string
}
interface CompanyFormData {
companyName: string
companyEmail: string
confirmCompanyEmail: string
companyPhone: string
contactPersonName: string
contactPersonPhone: string
password: string
confirmPassword: string
}
export default function RegisterForm({
mode,
setMode,
refToken,
onRegistered,
referrerEmail
}: RegisterFormProps) {
// Personal form state
const [personalForm, setPersonalForm] = useState<PersonalFormData>({
firstName: '',
lastName: '',
email: '',
confirmEmail: '',
password: '',
confirmPassword: '',
phoneNumber: ''
})
// Company form state
const [companyForm, setCompanyForm] = useState<CompanyFormData>({
companyName: '',
companyEmail: '',
confirmCompanyEmail: '',
companyPhone: '',
contactPersonName: '',
contactPersonPhone: '',
password: '',
confirmPassword: ''
})
// UI state
const [showPersonalPassword, setShowPersonalPassword] = useState(false)
const [showCompanyPassword, setShowCompanyPassword] = useState(false)
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const [formFade, setFormFade] = useState('fade-in')
// Phone input refs (to access intl-tel-input via TelephoneInput)
const personalPhoneRef = useRef<TelephoneInputHandle | null>(null)
const companyPhoneRef = useRef<TelephoneInputHandle | null>(null)
const contactPhoneRef = useRef<TelephoneInputHandle | null>(null)
// Hook for backend calls
const { registerPersonalReferral, registerCompanyReferral, registerGuest, error: regError } = useRegister()
const { showToast } = useToast()
const { t } = useTranslation()
// Guest form state
const [guestForm, setGuestForm] = useState({
firstName: '',
lastName: '',
email: '',
confirmEmail: '',
password: '',
confirmPassword: '',
})
// Animate form when mode changes
useEffect(() => {
setFormFade('fade-out')
const timeout = setTimeout(() => {
setFormFade('fade-in')
}, 180)
return () => clearTimeout(timeout)
}, [mode])
// Add fade CSS
useEffect(() => {
const style = document.createElement('style')
style.innerHTML = `
.fade-in {
opacity: 1;
transform: translateY(0);
transition: opacity 180ms, transform 180ms;
}
.fade-out {
opacity: 0;
transform: translateY(20px);
transition: opacity 180ms, transform 180ms;
}
`
document.head.appendChild(style)
return () => {
document.head.removeChild(style)
}
}, [])
// Reset forms when switching modes
useEffect(() => {
setError('')
}, [mode])
// Validation helpers
const validatePersonalForm = (): boolean => {
if (!personalForm.firstName.trim() || !personalForm.lastName.trim() ||
!personalForm.email.trim() || !personalForm.confirmEmail.trim() ||
!personalForm.password.trim() || !personalForm.confirmPassword.trim()
) {
setError(t('register.errorAllRequired'))
return false
}
if (personalForm.email !== personalForm.confirmEmail) {
setError(t('register.errorEmailMismatch'))
return false
}
if (personalForm.password !== personalForm.confirmPassword) {
setError(t('register.errorPasswordMismatch'))
return false
}
if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/.test(personalForm.password)) {
setError(t('register.errorPasswordWeak'))
return false
}
const phoneApi = personalPhoneRef.current
const dialCode = phoneApi?.getDialCode?.()
const intlNumber = phoneApi?.getNumber() || ''
const valid = phoneApi?.isValid() ?? false
if (!dialCode) {
setError(t('register.errorSelectCountryCode'))
return false
}
if (!intlNumber) {
setError(t('register.errorPhoneRequired'))
return false
}
if (!valid) {
setError(t('register.errorPhoneInvalid'))
return false
}
setError('')
return true
}
const validateCompanyForm = (): boolean => {
if (!companyForm.companyName.trim() || !companyForm.companyEmail.trim() ||
!companyForm.confirmCompanyEmail.trim() || !companyForm.contactPersonName.trim() ||
!companyForm.password.trim() || !companyForm.confirmPassword.trim()
) {
setError(t('register.errorAllRequired'))
return false
}
if (companyForm.companyEmail !== companyForm.confirmCompanyEmail) {
setError(t('register.errorEmailMismatch'))
return false
}
if (companyForm.password !== companyForm.confirmPassword) {
setError(t('register.errorPasswordMismatch'))
return false
}
if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/.test(companyForm.password)) {
setError(t('register.errorPasswordWeak'))
return false
}
const companyApi = companyPhoneRef.current
const contactApi = contactPhoneRef.current
const companyDialCode = companyApi?.getDialCode?.()
const contactDialCode = contactApi?.getDialCode?.()
const companyNumber = companyApi?.getNumber() || ''
const contactNumber = contactApi?.getNumber() || ''
const companyValid = companyApi?.isValid() ?? false
const contactValid = contactApi?.isValid() ?? false
if (!companyDialCode || !contactDialCode) {
setError(t('register.errorBothCountryCodes'))
return false
}
if (!companyNumber || !contactNumber) {
setError(t('register.errorBothPhonesRequired'))
return false
}
if (!companyValid || !contactValid) {
setError(t('register.errorBothPhonesInvalid'))
return false
}
setError('')
return true
}
// Submit handlers
const handlePersonalSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (loading) return
if (!validatePersonalForm()) return
setLoading(true)
setError('')
try {
const normalizedPhone =
personalPhoneRef.current?.getNumber() || personalForm.phoneNumber
console.log('[RegisterForm] handlePersonalSubmit normalized phone', {
normalizedPhone,
})
const res = await registerPersonalReferral({
refToken: refToken || '',
firstName: personalForm.firstName,
lastName: personalForm.lastName,
email: personalForm.email,
password: personalForm.password,
phone: normalizedPhone,
})
if (res.ok) {
showToast({
variant: 'success',
title: t('register.successTitle'),
message: t('register.successMessage')
})
onRegistered()
} else {
const msg = res.message || t('register.failedMessage')
setError(msg)
showToast({
variant: 'error',
title: t('register.failedTitle'),
message: msg
})
}
} catch (error) {
const msg = t('register.failedMessage')
setError(msg)
showToast({
variant: 'error',
title: t('register.failedTitle'),
message: msg
})
} finally {
setLoading(false)
}
}
const handleCompanySubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (loading) return
if (!validateCompanyForm()) return
setLoading(true)
setError('')
try {
const normalizedCompanyPhone =
companyPhoneRef.current?.getNumber() || companyForm.companyPhone
const normalizedContactPhone =
contactPhoneRef.current?.getNumber() || companyForm.contactPersonPhone
console.log('[RegisterForm] handleCompanySubmit normalized phones', {
normalizedCompanyPhone,
normalizedContactPhone,
})
const res = await registerCompanyReferral({
refToken: refToken || '',
companyEmail: companyForm.companyEmail,
password: companyForm.password,
companyName: companyForm.companyName,
companyPhone: normalizedCompanyPhone,
contactPersonName: companyForm.contactPersonName,
contactPersonPhone: normalizedContactPhone,
})
if (res.ok) {
showToast({
variant: 'success',
title: t('register.successTitle'),
message: t('register.successCompanyMessage')
})
onRegistered()
} else {
const msg = res.message || t('register.failedMessage')
setError(msg)
showToast({
variant: 'error',
title: t('register.failedTitle'),
message: msg
})
}
} catch (error) {
const msg = t('register.failedMessage')
setError(msg)
showToast({
variant: 'error',
title: t('register.failedTitle'),
message: msg
})
} finally {
setLoading(false)
}
}
// Surface hook error if present and no local error
useEffect(() => {
if (regError && !error) {
setError(regError)
showToast({
variant: 'error',
title: t('register.failedTitle'),
message: regError
})
}
}, [regError]) // eslint-disable-line react-hooks/exhaustive-deps
// Input change handlers
const handlePersonalChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setPersonalForm(prev => ({ ...prev, [name]: value }))
}
const handleCompanyChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setCompanyForm(prev => ({ ...prev, [name]: value }))
}
const handleGuestChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target
setGuestForm(prev => ({ ...prev, [name]: value }))
}
const validateGuestForm = (): boolean => {
if (!guestForm.firstName.trim() || !guestForm.lastName.trim() ||
!guestForm.email.trim() || !guestForm.confirmEmail.trim() ||
!guestForm.password.trim() || !guestForm.confirmPassword.trim()
) {
setError(t('register.errorAllRequired'))
return false
}
if (guestForm.email !== guestForm.confirmEmail) {
setError(t('register.errorEmailMismatch'))
return false
}
if (guestForm.password !== guestForm.confirmPassword) {
setError(t('register.errorPasswordMismatch'))
return false
}
if (!/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/.test(guestForm.password)) {
setError(t('register.errorPasswordWeak'))
return false
}
setError('')
return true
}
const handleGuestSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (loading) return
if (!validateGuestForm()) return
setLoading(true)
setError('')
try {
const res = await registerGuest({
refToken: refToken || '',
firstName: guestForm.firstName,
lastName: guestForm.lastName,
email: guestForm.email,
password: guestForm.password,
})
if (res.ok) {
showToast({
variant: 'success',
title: t('register.successTitle'),
message: t('register.successGuestMessage')
})
onRegistered()
} else {
const msg = res.message || t('register.failedMessage')
setError(msg)
showToast({ variant: 'error', title: t('register.failedTitle'), message: msg })
}
} catch {
const msg = t('register.failedMessage')
setError(msg)
showToast({ variant: 'error', title: t('register.failedTitle'), message: msg })
} finally {
setLoading(false)
}
}
// Password strength indicator
const getPasswordStrength = (password: string) => {
let strength = 0
if (password.length >= 8) strength++
if (/[a-z]/.test(password)) strength++
if (/[A-Z]/.test(password)) strength++
if (/\d/.test(password)) strength++
if (/[\W_]/.test(password)) strength++
return strength
}
const renderPasswordStrength = (password: string) => {
const strength = getPasswordStrength(password)
const rules = [
{ test: password.length >= 8, text: t('register.pwdMinLength') },
{ test: /[a-z]/.test(password), text: t('register.pwdLowercase') },
{ test: /[A-Z]/.test(password), text: t('register.pwdUppercase') },
{ test: /\d/.test(password), text: t('register.pwdDigits') },
{ test: /[\W_]/.test(password), text: t('register.pwdSpecial') }
]
return (
<div className="mt-2">
<div className="text-sm text-slate-700 mb-2">{t('register.passwordRequirements')}</div>
<ul className="text-sm space-y-1">
{rules.map((rule, index) => (
<li
key={index}
className={`flex items-center gap-2 ${rule.test ? 'text-green-600' : 'text-slate-600'}`}
>
<span>{rule.test ? '✓' : '○'}</span>
<span>{rule.text}</span>
</li>
))}
</ul>
</div>
)
}
return (
// softened outer container, no own solid white card parent provides glass card
<div className="w-full">
{/* Header */}
<div className="mb-6 text-center">
<h2 className="text-2xl sm:text-3xl font-extrabold text-[#0F172A] mb-2">
{t('register.formTitle')}
</h2>
{referrerEmail && (
<p className="text-base sm:text-sm text-[#8D6B1D] font-medium">
{t('register.invitedBy')} <span className="font-semibold">{referrerEmail}</span>!
</p>
)}
</div>
{/* Mode Toggle */}
<div className="flex justify-center mb-8">
<div className="bg-white/40 backdrop-blur-[18px] border border-white/35 shadow-sm p-1 rounded-lg">
{mode === 'guest' ? (
<button
className="px-6 py-2 rounded-md font-semibold text-sm bg-[#8D6B1D] text-white shadow-sm cursor-default"
type="button"
>
{t('register.tabGuest')}
</button>
) : (
<>
<button
className={`px-6 py-2 rounded-md font-semibold text-sm transition-all duration-200 ${
mode === 'personal'
? 'bg-[#8D6B1D] text-white shadow-sm'
: 'bg-transparent text-slate-700 hover:text-[#8D6B1D]'
}`}
onClick={() => setMode('personal')}
type="button"
>
{t('register.tabIndividual')}
</button>
<button
className={`px-6 py-2 rounded-md font-semibold text-sm transition-all duration-200 ${
mode === 'company'
? 'bg-[#8D6B1D] text-white shadow-sm'
: 'bg-transparent text-slate-700 hover:text-[#8D6B1D]'
}`}
onClick={() => setMode('company')}
type="button"
>
{t('register.tabCompany')}
</button>
</>
)}
</div>
</div>
{/* Error Message */}
{error && (
<div className="mb-6 p-4 bg-red-50/70 backdrop-blur-[18px] border border-red-200/70 rounded-lg">
<p className="text-red-600 text-sm font-medium">{error}</p>
</div>
)}
{/* Forms */}
<div className={formFade}>
{mode === 'personal' ? (
<form onSubmit={handlePersonalSubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="firstName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.firstName')} *
</label>
<input
type="text"
id="firstName"
name="firstName"
value={personalForm.firstName}
onChange={handlePersonalChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="lastName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.lastName')} *
</label>
<input
type="text"
id="lastName"
name="lastName"
value={personalForm.lastName}
onChange={handlePersonalChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="email" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.email')} *
</label>
<input
type="email"
id="email"
name="email"
value={personalForm.email}
onChange={handlePersonalChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="confirmEmail" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmEmail')} *
</label>
<input
type="email"
id="confirmEmail"
name="confirmEmail"
value={personalForm.confirmEmail}
onChange={handlePersonalChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div>
<label htmlFor="phoneNumber" className="block text-sm font-medium text-[#0F172A] mb-2">{t('autofix.kfb1676b0')}</label>
<TelephoneInput
id="phoneNumber"
name="phoneNumber"
ref={personalPhoneRef}
autoComplete="tel"
placeholder={t('autofix.k9f56d4ac')}
required
onChange={e =>
setPersonalForm(prev => ({ ...prev, phoneNumber: (e.target as HTMLInputElement).value }))
}
/>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="password" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.password')} *
</label>
<div className="relative">
<input
type={showPersonalPassword ? 'text' : 'password'}
id="password"
name="password"
value={personalForm.password}
onChange={handlePersonalChange}
autoComplete="new-password"
className="w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
<button
type="button"
onClick={() => setShowPersonalPassword(!showPersonalPassword)}
className="absolute inset-y-0 right-0 pr-3 flex items-center"
>
{showPersonalPassword ? (
<EyeSlashIcon className="h-4 w-4 text-slate-600" />
) : (
<EyeIcon className="h-4 w-4 text-slate-600" />
)}
</button>
</div>
{personalForm.password && renderPasswordStrength(personalForm.password)}
</div>
<div>
<label htmlFor="confirmPassword" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmPassword')} *
</label>
<input
type={showPersonalPassword ? 'text' : 'password'}
id="confirmPassword"
name="confirmPassword"
value={personalForm.confirmPassword}
onChange={handlePersonalChange}
autoComplete="new-password"
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className={`w-full flex items-center justify-center py-3 px-4 rounded-lg text-white font-semibold transition-colors ${
loading
? 'bg-gray-400 cursor-not-allowed'
: 'bg-[#8D6B1D] hover:bg-[#7A5E1A] focus:ring-2 focus:ring-[#8D6B1D] focus:ring-offset-2'
}`}
>
{loading ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
{t('register.submitting')}
</>
) : (
t('register.registerNow')
)}
</button>
</form>
) : mode === 'company' ? (
<form onSubmit={handleCompanySubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="companyName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.companyName')} *
</label>
<input
type="text"
id="companyName"
name="companyName"
value={companyForm.companyName}
onChange={handleCompanyChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="contactPersonName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.contactPersonName')} *
</label>
<input
type="text"
id="contactPersonName"
name="contactPersonName"
value={companyForm.contactPersonName}
onChange={handleCompanyChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="companyEmail" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.companyEmail')} *
</label>
<input
type="email"
id="companyEmail"
name="companyEmail"
value={companyForm.companyEmail}
onChange={handleCompanyChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="confirmCompanyEmail" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmEmail')} *
</label>
<input
type="email"
id="confirmCompanyEmail"
name="confirmCompanyEmail"
value={companyForm.confirmCompanyEmail}
onChange={handleCompanyChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="companyPhone" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.companyPhone')} *
</label>
<TelephoneInput
id="companyPhone"
name="companyPhone"
ref={companyPhoneRef}
autoComplete="tel"
placeholder={t('autofix.k8eaa7b3b')}
required
onChange={e =>
setCompanyForm(prev => ({ ...prev, companyPhone: (e.target as HTMLInputElement).value }))
}
/>
</div>
<div>
<label htmlFor="contactPersonPhone" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.contactPersonPhone')} *
</label>
<TelephoneInput
id="contactPersonPhone"
name="contactPersonPhone"
ref={contactPhoneRef}
autoComplete="tel"
placeholder={t('autofix.k9f56d4ac')}
required
onChange={e =>
setCompanyForm(prev => ({
...prev,
contactPersonPhone: (e.target as HTMLInputElement).value,
}))
}
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="password" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.password')} *
</label>
<div className="relative">
<input
type={showCompanyPassword ? 'text' : 'password'}
id="password"
name="password"
value={companyForm.password}
onChange={handleCompanyChange}
autoComplete="new-password"
className="w-full px-3 py-2 pr-10 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
<button
type="button"
onClick={() => setShowCompanyPassword(!showCompanyPassword)}
className="absolute inset-y-0 right-0 pr-3 flex items-center"
>
{showCompanyPassword ? (
<EyeSlashIcon className="h-4 w-4 text-slate-600" />
) : (
<EyeIcon className="h-4 w-4 text-slate-600" />
)}
</button>
</div>
{companyForm.password && renderPasswordStrength(companyForm.password)}
</div>
<div>
<label htmlFor="confirmPassword" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmPassword')} *
</label>
<input
type={showCompanyPassword ? 'text' : 'password'}
id="confirmPassword"
name="confirmPassword"
value={companyForm.confirmPassword}
onChange={handleCompanyChange}
autoComplete="new-password"
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className={`w-full flex items-center justify-center py-3 px-4 rounded-lg text-white font-semibold transition-colors ${
loading
? 'bg-gray-400 cursor-not-allowed'
: 'bg-[#8D6B1D] hover:bg-[#7A5E1A] focus:ring-2 focus:ring-[#8D6B1D] focus:ring-offset-2'
}`}
>
{loading ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
{t('register.submitting')}
</>
) : (
t('register.submitCompany')
)}
</button>
</form>
) : (
<form onSubmit={handleGuestSubmit} className="space-y-6">
<div className="p-4 bg-amber-50/70 backdrop-blur-[18px] border border-amber-200/70 rounded-lg mb-2">
<p className="text-amber-800 text-sm font-medium">
{t('register.guestNote')}
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="guestFirstName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.firstName')} *
</label>
<input
type="text"
id="guestFirstName"
name="firstName"
value={guestForm.firstName}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="guestLastName" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.lastName')} *
</label>
<input
type="text"
id="guestLastName"
name="lastName"
value={guestForm.lastName}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="guestEmail" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.email')} *
</label>
<input
type="email"
id="guestEmail"
name="email"
value={guestForm.email}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
<div>
<label htmlFor="guestConfirmEmail" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmEmail')} *
</label>
<input
type="email"
id="guestConfirmEmail"
name="confirmEmail"
value={guestForm.confirmEmail}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label htmlFor="guestPassword" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.password')} *
</label>
<div className="relative">
<input
type={showPersonalPassword ? 'text' : 'password'}
id="guestPassword"
name="password"
value={guestForm.password}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary pr-10"
required
/>
<button
type="button"
onClick={() => setShowPersonalPassword(!showPersonalPassword)}
className="absolute inset-y-0 right-0 px-3 flex items-center text-slate-500 hover:text-[#8D6B1D]"
>
{showPersonalPassword ? (
<EyeSlashIcon className="h-5 w-5" />
) : (
<EyeIcon className="h-5 w-5" />
)}
</button>
</div>
{guestForm.password && renderPasswordStrength(guestForm.password)}
</div>
<div>
<label htmlFor="guestConfirmPassword" className="block text-sm font-medium text-[#0F172A] mb-2">
{t('register.confirmPassword')} *
</label>
<input
type="password"
id="guestConfirmPassword"
name="confirmPassword"
value={guestForm.confirmPassword}
onChange={handleGuestChange}
className="w-full px-3 py-2 border border-gray-300 rounded-lg bg-white/60 focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
required
/>
</div>
</div>
<button
type="submit"
disabled={loading}
className={`w-full flex items-center justify-center py-3 px-4 rounded-lg text-white font-semibold transition-colors ${
loading
? 'bg-gray-400 cursor-not-allowed'
: 'bg-[#8D6B1D] hover:bg-[#7A5E1A] focus:ring-2 focus:ring-[#8D6B1D] focus:ring-offset-2'
}`}
>
{loading ? (
<>
<div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white mr-2"></div>
{t('register.submitting')}
</>
) : (
t('register.submitGuest')
)}
</button>
</form>
)}
</div>
{/* Login Link */}
<div className="mt-8 text-center">
<p className="text-slate-700">
{t('register.alreadyHaveAccount')}{' '}
<a
href="/login"
className="text-[#8D6B1D] hover:text-[#7A5E1A] font-medium transition-colors"
>
{t('register.loginHere')}
</a>
</p>
</div>
</div>
)
}