feat: register Backend link
This commit is contained in:
parent
943079d94f
commit
604556ca06
@ -2,6 +2,7 @@
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
|
||||
import { useRegister } from '../hooks/useRegister'
|
||||
|
||||
interface RegisterFormProps {
|
||||
mode: 'personal' | 'company'
|
||||
@ -69,6 +70,9 @@ export default function RegisterForm({
|
||||
const [error, setError] = useState('')
|
||||
const [formFade, setFormFade] = useState('fade-in')
|
||||
|
||||
// Hook for backend calls
|
||||
const { registerPersonalReferral, registerCompanyReferral, error: regError } = useRegister()
|
||||
|
||||
// Animate form when mode changes
|
||||
useEffect(() => {
|
||||
setFormFade('fade-out')
|
||||
@ -108,7 +112,9 @@ export default function RegisterForm({
|
||||
const validatePersonalForm = (): boolean => {
|
||||
if (!personalForm.firstName.trim() || !personalForm.lastName.trim() ||
|
||||
!personalForm.email.trim() || !personalForm.confirmEmail.trim() ||
|
||||
!personalForm.password.trim() || !personalForm.confirmPassword.trim()) {
|
||||
!personalForm.password.trim() || !personalForm.confirmPassword.trim() ||
|
||||
!personalForm.phoneNumber.trim() // now required by backend
|
||||
) {
|
||||
setError('Alle Felder sind erforderlich')
|
||||
return false
|
||||
}
|
||||
@ -135,7 +141,9 @@ export default function RegisterForm({
|
||||
const validateCompanyForm = (): boolean => {
|
||||
if (!companyForm.companyName.trim() || !companyForm.companyEmail.trim() ||
|
||||
!companyForm.confirmCompanyEmail.trim() || !companyForm.contactPersonName.trim() ||
|
||||
!companyForm.password.trim() || !companyForm.confirmPassword.trim()) {
|
||||
!companyForm.password.trim() || !companyForm.confirmPassword.trim() ||
|
||||
!companyForm.companyPhone.trim() || !companyForm.contactPersonPhone.trim() // now required
|
||||
) {
|
||||
setError('Alle Felder sind erforderlich')
|
||||
return false
|
||||
}
|
||||
@ -167,16 +175,22 @@ export default function RegisterForm({
|
||||
if (!validatePersonalForm()) return
|
||||
|
||||
setLoading(true)
|
||||
setError('')
|
||||
|
||||
try {
|
||||
// TODO: Implement API call
|
||||
console.log('Personal registration:', { ...personalForm, refToken })
|
||||
|
||||
// Simulate API delay
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
|
||||
// For now, just call onRegistered
|
||||
const res = await registerPersonalReferral({
|
||||
refToken: refToken || '',
|
||||
firstName: personalForm.firstName,
|
||||
lastName: personalForm.lastName,
|
||||
email: personalForm.email,
|
||||
password: personalForm.password,
|
||||
phone: personalForm.phoneNumber,
|
||||
})
|
||||
if (res.ok) {
|
||||
onRegistered()
|
||||
} else {
|
||||
setError(res.message || 'Registrierung fehlgeschlagen. Bitte versuche es erneut.')
|
||||
}
|
||||
} catch (error) {
|
||||
setError('Registrierung fehlgeschlagen. Bitte versuche es erneut.')
|
||||
} finally {
|
||||
@ -191,16 +205,23 @@ export default function RegisterForm({
|
||||
if (!validateCompanyForm()) return
|
||||
|
||||
setLoading(true)
|
||||
setError('')
|
||||
|
||||
try {
|
||||
// TODO: Implement API call
|
||||
console.log('Company registration:', { ...companyForm, refToken })
|
||||
|
||||
// Simulate API delay
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
|
||||
// For now, just call onRegistered
|
||||
const res = await registerCompanyReferral({
|
||||
refToken: refToken || '',
|
||||
companyEmail: companyForm.companyEmail,
|
||||
password: companyForm.password,
|
||||
companyName: companyForm.companyName,
|
||||
companyPhone: companyForm.companyPhone,
|
||||
contactPersonName: companyForm.contactPersonName,
|
||||
contactPersonPhone: companyForm.contactPersonPhone,
|
||||
})
|
||||
if (res.ok) {
|
||||
onRegistered()
|
||||
} else {
|
||||
setError(res.message || 'Registrierung fehlgeschlagen. Bitte versuche es erneut.')
|
||||
}
|
||||
} catch (error) {
|
||||
setError('Registrierung fehlgeschlagen. Bitte versuche es erneut.')
|
||||
} finally {
|
||||
@ -208,6 +229,11 @@ export default function RegisterForm({
|
||||
}
|
||||
}
|
||||
|
||||
// Surface hook error if present and no local error
|
||||
useEffect(() => {
|
||||
if (regError && !error) setError(regError)
|
||||
}, [regError]) // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Input change handlers
|
||||
const handlePersonalChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target
|
||||
@ -375,7 +401,7 @@ export default function RegisterForm({
|
||||
|
||||
<div>
|
||||
<label htmlFor="phoneNumber" className="block text-sm font-medium text-[#0F172A] mb-2">
|
||||
Telefonnummer
|
||||
Telefonnummer *
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
@ -385,6 +411,7 @@ export default function RegisterForm({
|
||||
onChange={handlePersonalChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
|
||||
placeholder="+49 123 456 7890"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -522,7 +549,7 @@ export default function RegisterForm({
|
||||
<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">
|
||||
Firmen-Telefon
|
||||
Firmen-Telefon *
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
@ -532,12 +559,13 @@ export default function RegisterForm({
|
||||
onChange={handleCompanyChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
|
||||
placeholder="+49 123 456 7890"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label htmlFor="contactPersonPhone" className="block text-sm font-medium text-[#0F172A] mb-2">
|
||||
Ansprechpartner-Telefon
|
||||
Ansprechpartner-Telefon *
|
||||
</label>
|
||||
<input
|
||||
type="tel"
|
||||
@ -547,6 +575,7 @@ export default function RegisterForm({
|
||||
onChange={handleCompanyChange}
|
||||
className="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-[#8D6B1D] focus:border-transparent transition-colors text-primary"
|
||||
placeholder="+49 123 456 7890"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
154
src/app/register/hooks/useRegister.ts
Normal file
154
src/app/register/hooks/useRegister.ts
Normal file
@ -0,0 +1,154 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
|
||||
export type PersonalReferralPayload = {
|
||||
refToken: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
email: string
|
||||
password: string
|
||||
phone: string
|
||||
lang?: 'de' | 'en'
|
||||
}
|
||||
|
||||
export type CompanyReferralPayload = {
|
||||
refToken: string
|
||||
companyEmail: string
|
||||
password: string
|
||||
companyName: string
|
||||
companyPhone: string
|
||||
contactPersonName: string
|
||||
contactPersonPhone: string
|
||||
lang?: 'de' | 'en'
|
||||
}
|
||||
|
||||
type RegisterResult<T = any> = {
|
||||
ok: boolean
|
||||
status: number
|
||||
data?: T | null
|
||||
message?: string
|
||||
}
|
||||
|
||||
function detectLang(): 'de' | 'en' {
|
||||
if (typeof navigator !== 'undefined') {
|
||||
const n = navigator.language || ''
|
||||
if (n.toLowerCase().startsWith('de')) return 'de'
|
||||
}
|
||||
return 'en'
|
||||
}
|
||||
|
||||
function mapError(status: number): string {
|
||||
switch (status) {
|
||||
case 404:
|
||||
return 'Referral token not found.'
|
||||
case 410:
|
||||
return 'Referral token expired or exhausted.'
|
||||
case 403:
|
||||
return 'Referral token is inactive.'
|
||||
case 400:
|
||||
return 'Invalid registration data or token validation failed.'
|
||||
default:
|
||||
return 'Registration failed. Please try again later.'
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: read ?ref from the URL as a fallback
|
||||
function getRefTokenFromUrl(): string | null {
|
||||
if (typeof window === 'undefined') return null
|
||||
try {
|
||||
const u = new URL(window.location.href)
|
||||
return u.searchParams.get('ref')
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function useRegister() {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [error, setError] = useState<string>('')
|
||||
|
||||
const base = process.env.NEXT_PUBLIC_API_BASE_URL || ''
|
||||
|
||||
const registerPersonalReferral = async (payload: PersonalReferralPayload): Promise<RegisterResult> => {
|
||||
setError('')
|
||||
setLoading(true)
|
||||
|
||||
// Resolve token: prefer payload, fallback to URL
|
||||
const finalRefToken = (payload.refToken || '').trim() || getRefTokenFromUrl() || ''
|
||||
const body = { ...payload, refToken: finalRefToken, lang: payload.lang || detectLang() }
|
||||
|
||||
// NOTE: align with other endpoints using /api prefix
|
||||
const url = `${base}/api/register/personal-referral`
|
||||
console.log('🌐 useRegister: POST personal-referral', { url, refToken: finalRefToken ? `${finalRefToken.slice(0, 6)}…${finalRefToken.slice(-6)}` : null })
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
const json = await res.json().catch(() => null)
|
||||
console.log('📡 useRegister: personal status:', res.status, 'body:', json)
|
||||
if (!res.ok) {
|
||||
const msg = json?.message || mapError(res.status)
|
||||
setError(msg)
|
||||
return { ok: false, status: res.status, data: json, message: msg }
|
||||
}
|
||||
return { ok: true, status: res.status, data: json, message: json?.message }
|
||||
} catch (e) {
|
||||
console.error('❌ useRegister: personal error:', e)
|
||||
const msg = 'Network error. Please try again later.'
|
||||
setError(msg)
|
||||
return { ok: false, status: 0, data: null, message: msg }
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
const registerCompanyReferral = async (payload: CompanyReferralPayload): Promise<RegisterResult> => {
|
||||
setError('')
|
||||
setLoading(true)
|
||||
|
||||
// Resolve token: prefer payload, fallback to URL
|
||||
const finalRefToken = (payload.refToken || '').trim() || getRefTokenFromUrl() || ''
|
||||
const body = { ...payload, refToken: finalRefToken, lang: payload.lang || detectLang() }
|
||||
|
||||
// NOTE: align with other endpoints using /api prefix
|
||||
const url = `${base}/api/register/company-referral`
|
||||
console.log('🌐 useRegister: POST company-referral', { url, refToken: finalRefToken ? `${finalRefToken.slice(0, 6)}…${finalRefToken.slice(-6)}` : null })
|
||||
|
||||
try {
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
const json = await res.json().catch(() => null)
|
||||
console.log('📡 useRegister: company status:', res.status, 'body:', json)
|
||||
if (!res.ok) {
|
||||
const msg = json?.message || mapError(res.status)
|
||||
setError(msg)
|
||||
return { ok: false, status: res.status, data: json, message: msg }
|
||||
}
|
||||
return { ok: true, status: res.status, data: json, message: json?.message }
|
||||
} catch (e) {
|
||||
console.error('❌ useRegister: company error:', e)
|
||||
const msg = 'Network error. Please try again later.'
|
||||
setError(msg)
|
||||
return { ok: false, status: 0, data: null, message: msg }
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
loading,
|
||||
error,
|
||||
setError,
|
||||
registerPersonalReferral,
|
||||
registerCompanyReferral,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user