/** * InvitePage * * Public page for accepting invitations. * URL: /invite/:token * * Handles both: * - Existing users (shows login or auto-accepts if already logged in) * - New users (shows registration form) */ import React, { useState, useEffect } from 'react'; import { useParams, useNavigate, Link } from 'react-router-dom'; import { useInvitations, type InvitationValidation, type RegisterAndAcceptData } from '../hooks/useInvitations'; // Note: useAuth not needed for InvitePage import { FaCheckCircle, FaTimesCircle, FaSpinner, FaEnvelope, FaUser, FaLock } from 'react-icons/fa'; import styles from './InvitePage.module.css'; export const InvitePage: React.FC = () => { const { token } = useParams<{ token: string }>(); const navigate = useNavigate(); const { validateInvitation, acceptInvitation, registerAndAccept } = useInvitations(); // Check if user has auth token (simplified check) const isAuthenticated = !!sessionStorage.getItem('auth_authority'); // State const [validation, setValidation] = useState(null); const [validating, setValidating] = useState(true); const [accepting, setAccepting] = useState(false); const [success, setSuccess] = useState(false); const [error, setError] = useState(null); // Registration form state const [formData, setFormData] = useState({ token: token || '', username: '', email: '', password: '', firstname: '', lastname: '', }); const [confirmPassword, setConfirmPassword] = useState(''); // Validate token on mount useEffect(() => { const validate = async () => { if (!token) { setError('Kein Einladungs-Token angegeben'); setValidating(false); return; } const result = await validateInvitation(token); setValidation(result); setValidating(false); // Update form with token setFormData(prev => ({ ...prev, token })); }; validate(); }, [token, validateInvitation]); // Auto-accept if already logged in const handleAccept = async () => { if (!token) return; setAccepting(true); setError(null); const result = await acceptInvitation(token); if (result.success) { setSuccess(true); // Redirect to dashboard after 2 seconds setTimeout(() => { navigate('/'); }, 2000); } else { setError(result.error || 'Fehler beim Annehmen der Einladung'); } setAccepting(false); }; // Handle registration form submission const handleRegister = async (e: React.FormEvent) => { e.preventDefault(); setError(null); // Validate passwords match if (formData.password !== confirmPassword) { setError('Die Passwörter stimmen nicht überein'); return; } // Validate password length if (formData.password.length < 8) { setError('Das Passwort muss mindestens 8 Zeichen lang sein'); return; } setAccepting(true); const result = await registerAndAccept(formData); if (result.success) { setSuccess(true); // Redirect to login after 3 seconds setTimeout(() => { navigate('/login'); }, 3000); } else { setError(result.error || 'Fehler bei der Registrierung'); } setAccepting(false); }; // Handle form field changes const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; // Loading state if (validating) { return (

Einladung wird überprüft...

); } // Invalid invitation if (!validation?.valid) { return (

Ungültige Einladung

{validation?.reason || 'Diese Einladung ist nicht gültig.'}

Zur Anmeldung
); } // Success state if (success) { return (

Erfolgreich!

{isAuthenticated ? 'Sie wurden erfolgreich zum Mandanten hinzugefügt.' : 'Ihr Konto wurde erstellt. Sie werden zur Anmeldeseite weitergeleitet...'}

); } // Already authenticated - show accept button if (isAuthenticated) { return (

Einladung annehmen

Sie wurden eingeladen, einem Mandanten beizutreten.

Status: Angemeldet
{validation.roleLabels && validation.roleLabels.length > 0 && (
Zugewiesene Rollen: {validation.roleLabels.join(', ')}
)}
{error && (
{error}
)}
Abbrechen
); } // Not authenticated - show registration form or login option return (

Einladung annehmen

Erstellen Sie ein Konto, um die Einladung anzunehmen.

{error && (
{error}
)}
setConfirmPassword(e.target.value)} placeholder="••••••••" required />
oder

Sie haben bereits ein Konto?

Anmelden und Einladung annehmen
); }; export default InvitePage;