import { useState, useEffect } from 'react'; import { Link, useNavigate, useLocation } from 'react-router-dom'; import { useToast } from '../contexts/ToastContext'; import { motion } from 'framer-motion'; import { useUserStore } from '../store/userStore'; import { Sun, Moon } from 'lucide-react'; import { api } from '../services/api'; export default function AcceptInvite() { const navigate = useNavigate(); const location = useLocation(); const { isDark, toggleTheme } = useUserStore(); const toast = useToast(); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); // Extract token and email from URL const params = new URLSearchParams(location.search); const token = params.get('token'); const email = params.get('email'); useEffect(() => { if (!token || !email) { setError('Invalid or missing invitation link. Please request a new invite.'); } }, [token, email]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!token || !email) return; if (password.length < 8) { setError('Password must be at least 8 characters long'); return; } if (password !== confirmPassword) { setError('Passwords do not match'); return; } setLoading(true); setError(''); try { const res = await api.post('/api/v1/auth/accept-invite', { token, email, password }); toast.success(res.data.message || 'Account activated successfully!'); navigate('/login'); } catch (err: any) { setError(err.response?.data?.detail || 'Failed to accept invitation'); } finally { setLoading(false); } }; return (
{/* Background Orbs for Glass Effect */}
{/* Theme Toggle */} {/* Logo Section */}
DataVision { (e.target as HTMLImageElement).src = '/logo.svg'; }} />
Data Vision
{/* Accept Invite Card */}

Accept Invitation

Set a password for {email} to activate your account

{error && (
{error}
)} {!token || !email ? (
Return to Login
) : (
setPassword(e.target.value)} className="w-full px-4 py-3 rounded-xl bg-black/5 dark:bg-white/5 border border-black/10 dark:border-white/10 focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500" placeholder="••••••••" minLength={8} />
setConfirmPassword(e.target.value)} className="w-full px-4 py-3 rounded-xl bg-black/5 dark:bg-white/5 border border-black/10 dark:border-white/10 focus:ring-2 focus:ring-emerald-500 focus:border-emerald-500 outline-none transition-all placeholder:text-gray-400 dark:placeholder:text-gray-500" placeholder="••••••••" />

Already have an account?{' '} Sign In

)}
); }