import { useState } from 'react'; import type { FormEvent } from 'react'; import PocketBase from 'pocketbase'; import { Input } from "./ui/input"; import { Button } from "./ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "./ui/card"; import { Eye, EyeOff, Loader2 } from "lucide-react"; import { Separator } from "./ui/separator"; import { Label } from "./ui/label"; import { useIsLoggedIn } from '../lib/isLoggedIn'; import Loader from "./ui/loader"; interface AuthStatus { message: string; isError: boolean; } interface UserRecord { id: string; email: string; name?: string; type?: string; avatar?: string; [key: string]: any; } interface AuthResponse { token: string; record: UserRecord; } const SignupPage = () => { const [email, setEmail] = useState(''); const [name, setName] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [passwordVisible, setPasswordVisible] = useState(false); const [confirmPasswordVisible, setConfirmPasswordVisible] = useState(false); const [status, setStatus] = useState({ message: '', isError: false }); const [isLoading, setIsLoading] = useState(false); const pb = new PocketBase("https://tst-pb.s38.siliconpin.com"); const handleSubmit = async (e: FormEvent) => { e.preventDefault(); setIsLoading(true); setStatus({ message: '', isError: false }); if (password !== confirmPassword) { setStatus({ message: 'Passwords do not match', isError: true }); setIsLoading(false); return; } try { // Create the user const userData = { email, name, password, passwordConfirm: confirmPassword, emailVisibility: true, }; const record = await pb.collection('users').create(userData); // Automatically login after signup const authData = await pb.collection('users').authWithPassword(email, password); if (!authData?.token || !authData?.record) { throw new Error("Authentication failed after signup"); } const avatarUrl = authData.record.avatar ? pb.files.getUrl(authData.record, authData.record.avatar) : ''; const authResponse: AuthResponse = { token: authData.token, record: { id: authData.record.id, email: authData.record.email, name: authData.record.name || authData.record.email.split('@')[0], type: authData.record.type || 'user', avatar: authData.record.avatar || '', } }; await syncSessionWithBackend(authResponse, avatarUrl); window.location.href = '/profile'; } catch (error: any) { console.error("Signup failed:", error); setStatus({ message: error.message || "Signup failed. Please try again.", isError: true }); } finally { setIsLoading(false); } }; const signupWithOAuth2 = async (provider: 'google' | 'facebook' | 'github') => { try { setIsLoading(true); setStatus({ message: '', isError: false }); const authData = await pb.collection('users').authWithOAuth2({ provider }); if (!authData?.record) { throw new Error("No user record found"); } const avatarUrl = authData.record.avatar ? pb.files.getUrl(authData.record, authData.record.avatar) : ''; const authResponse: AuthResponse = { token: authData.token, record: { id: authData.record.id, email: authData.record.email || '', name: authData.record.name || '', type: authData.record.type || '', avatar: authData.record.avatar || '' } }; await syncSessionWithBackend(authResponse, avatarUrl); window.location.href = '/profile'; } catch (error) { console.error(`${provider} Signup failed:`, error); setStatus({ message: `${provider} signup failed. Please try again.`, isError: true }); } finally { setIsLoading(false); } }; const syncSessionWithBackend = async (authData: AuthResponse, avatarUrl: string) => { try { const response = await fetch('https://host-api.cs1.hz.siliconpin.com/v1/users/?query=login', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: 'new', accessToken: authData.token, email: authData.record.email, name: authData.record.name, type: authData.record.type, avatar: avatarUrl, isAuthenticated: true, id: authData.record.id }) }); if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.message || `HTTP error! status: ${response.status}`); } const data = await response.json(); console.log('Session synced with backend:', data); return data; } catch (error: any) { console.error('Error syncing session:', error); throw new Error(`Session sync failed: ${error.message}`); } }; const { isLoggedIn, loading, error } = useIsLoggedIn(); if (loading) { return ; } if (isLoggedIn) { window.location.href = '/'; return null; } return (
Create an Account Join us to get started {status.message && (
{status.message}
)}
setName(e.target.value)} placeholder="Your Name" required className="focus:ring-2 focus:ring-blue-500" />
setEmail(e.target.value)} placeholder="you@example.com" required className="focus:ring-2 focus:ring-blue-500" />
setPassword(e.target.value)} placeholder="••••••••" required minLength={8} className="focus:ring-2 focus:ring-blue-500 pr-10" />
setConfirmPassword(e.target.value)} placeholder="••••••••" required minLength={8} className="focus:ring-2 focus:ring-blue-500 pr-10" />
Or sign up with
Already have an account?{' '} Sign in
); }; export default SignupPage;