Files
brief_ai/frontend-BriefAI/src/pages/RegisterPage.tsx
T
Nicolo-Salvafiorita 54ae86a88a feat: Implement subscription management and article saving features
- Added subscriptionPlan and subscriptionExpiresAt fields to UserProfile model.
- Enhanced profile routes to handle subscription state updates and expiration logic.
- Introduced email and password validation during user registration.
- Implemented link stripping for processed articles in the articles route.
- Added save article functionality with appropriate UI feedback in the frontend.
- Updated AccountSettings and FeedContent components to reflect subscription state and saved articles.
- Improved error handling and local storage management for user preferences.
2026-05-07 12:06:26 +02:00

147 lines
4.4 KiB
TypeScript

import type { FormEvent } from 'react'
import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { register } from '../services/authService'
import './RegisterPage.css'
type RegisterPageProps = {
onRegisterSuccess?: () => void
}
function RegisterPage({ onRegisterSuccess }: RegisterPageProps) {
const navigate = useNavigate()
const [username, setUsername] = useState('')
const [email, setEmail] = useState('')
const [newPassword, setNewPassword] = useState('')
const [acceptedTerms, setAcceptedTerms] = useState(false)
const [error, setError] = useState('')
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault()
// Validazione esplicita: se i termini non sono accettati, blocca l'invio.
if (!acceptedTerms) {
setError("Devi accettare i Termini di servizio e l'Informativa sulla privacy.")
return
}
// Recupera preferenze accumulate durante l'onboarding (se presenti)
let macroTopics: string[] | undefined = undefined
let keywords: string[] | undefined = undefined
try {
const raw = localStorage.getItem('briefai-onboarding')
if (raw) {
const parsed = JSON.parse(raw)
macroTopics = parsed.selectedTopics || undefined
keywords = parsed.keywords || undefined
}
} catch (e) {
// ignore parsing errors
}
// Basic email format validation on client
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
if (!emailRegex.test(String(email).toLowerCase())) {
setError('Formato email non valido.')
return
}
try {
await register({
email,
password: newPassword,
username,
preferences: {
macroTopics,
keywords,
},
})
setError('')
// Pulizia locale
setUsername('')
setEmail('')
setNewPassword('')
setAcceptedTerms(false)
if (typeof onRegisterSuccess === 'function') onRegisterSuccess()
// Dopo la registrazione il token è salvato dal servizio; redirige al feed
navigate('/feed')
} catch (err: any) {
// Estrae il messaggio d'errore lanciato dal backend (`throw await res.json()`),
// oppure mostra un fallback se l'API non risponde correttamente.
const errorMessage = err?.error || err?.message || 'Errore nella registrazione'
setError(errorMessage)
}
}
return (
<section className="auth-panel" aria-label="Registrazione BriefAI">
<p className="eyebrow">BriefAI</p>
<h1>Registrati</h1>
<p className="subtitle">Crea il tuo account per iniziare.</p>
<form className="login-form" onSubmit={handleSubmit}>
<label htmlFor="register-username">Utente</label>
<input
id="register-username"
type="text"
value={username}
onChange={(event) => setUsername(event.target.value)}
placeholder="Il tuo username"
autoComplete="username"
required
/>
<label htmlFor="register-email">Email</label>
<input
id="register-email"
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="nome@email.com"
autoComplete="email"
required
/>
<label htmlFor="register-password">Nuova password</label>
<input
id="register-password"
type="password"
value={newPassword}
onChange={(event) => setNewPassword(event.target.value)}
placeholder="Nuova password"
autoComplete="new-password"
required
/>
<label className="checkbox-row" htmlFor="register-terms">
<input
id="register-terms"
type="checkbox"
checked={acceptedTerms}
onChange={(event) => setAcceptedTerms(event.target.checked)}
/>
<span>Accetto i Termini di servizio e l'Informativa sulla privacy</span>
</label>
<button type="submit">Crea account</button>
{error && (
<p className="error" role="alert" aria-live="polite">
{error}
</p>
)}
</form>
<p className="auth-footer">
Se hai gia un account fai <Link className="text-link" to="/login">accesso</Link>
</p>
<p className="auth-footer">
Torna alla <Link className="text-link" to="/">home</Link>
</p>
</section>
)
}
export default RegisterPage