import { useState, useEffect, useCallback, CSSProperties } from "react"; import { useNavigate } from "react-router-dom"; import { useAuth } from "../../lib/authContext"; type Role = "STUDENT" | "SHEIKH"; type StatusType = "waiting" | "success" | "error"; interface Status { text: string; type: StatusType; } declare global { interface Window { google: { accounts: { id: { initialize: (config: { client_id: string; callback: (response: { credential: string }) => void; }) => void; renderButton: ( element: HTMLElement | null, options: object ) => void; }; }; }; } } const CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID as string; const STATUS_COLORS: Record = { waiting: { bg: "#fff3cd", color: "#856404" }, success: { bg: "#d4edda", color: "#155724" }, error: { bg: "#f8d7da", color: "#721c24" }, }; export default function GoogleAuth() { const navigate = useNavigate(); const { signInWithGoogle } = useAuth(); const [selectedRole, setSelectedRole] = useState("STUDENT"); const [status, setStatus] = useState({ text: "⏳ Waiting for sign-in", type: "waiting" }); const handleCredentialResponse = useCallback( async (googleResponse: { credential: string }): Promise => { const idToken = googleResponse.credential; setStatus({ text: "⏳ Signing in...", type: "waiting" }); try { const user = await signInWithGoogle(idToken, selectedRole); setStatus({ text: "✅ Success! Redirecting...", type: "success" }); // Navigate based on role and profile completion status const role = user.role.toLowerCase(); if (role === "admin") { navigate("/admin/dashboard", { replace: true }); } else if (role === "sheikh") { const approvalStatus = user.sheikhApprovalStatus?.toUpperCase(); if (approvalStatus === "REJECTED") { navigate("/sheikh/dashboard", { replace: true }); } else if (!user.profileCompleted) { navigate("/complete-profile/sheikh", { replace: true }); } else { const approvalStatus = user.sheikhApprovalStatus?.toUpperCase(); if (approvalStatus === "APPROVED") { navigate("/sheikh/dashboard", { replace: true }); } else { navigate("/sheikh/interview", { replace: true }); } } } else { // student if (!user.profileCompleted) { navigate("/complete-profile/student", { replace: true }); } else { navigate("/student/dashboard", { replace: true }); } } } catch (err: unknown) { const message = err instanceof Error ? err.message : "Sign-in failed"; setStatus({ text: `❌ ${message}`, type: "error" }); } }, [selectedRole, signInWithGoogle, navigate] ); useEffect(() => { const script = document.createElement("script"); script.src = "https://accounts.google.com/gsi/client"; script.async = true; script.defer = true; script.onload = () => { window.google.accounts.id.initialize({ client_id: CLIENT_ID, callback: handleCredentialResponse, }); window.google.accounts.id.renderButton( document.getElementById("googleBtn"), { theme: "outline", size: "large", text: "sign_in_with", shape: "rectangular", width: 300 } ); }; document.body.appendChild(script); return () => { document.body.removeChild(script); }; }, [handleCredentialResponse]); return (
📖

Quran App — Sign In

Sign in with Google to continue

{(["STUDENT", "SHEIKH"] as Role[]).map((role) => ( ))}

Click the button below to sign in with Google

{status.text}
); } const styles: Record = { page: { fontFamily: "'Segoe UI', sans-serif", background: "#f0f4f8", minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center" }, container: { background: "white", borderRadius: 16, padding: 40, width: 600, boxShadow: "0 4px 24px rgba(0,0,0,0.10)" }, header: { textAlign: "center", marginBottom: 32 }, icon: { fontSize: 48, marginBottom: 12 }, h1: { color: "#1a6b3c", fontSize: 24, marginBottom: 6 }, subtitle: { color: "#777", fontSize: 14 }, roleSelect: { display: "flex", gap: 12, marginBottom: 24 }, roleBtn: { flex: 1, padding: 10, border: "2px solid #ddd", borderRadius: 8, background: "white", cursor: "pointer", fontSize: 14, fontWeight: 600, color: "#555" }, roleBtnActive: { borderColor: "#1a6b3c", background: "#e8f5e9", color: "#1a6b3c" }, signinSection: { textAlign: "center", marginBottom: 24 }, signinHint: { color: "#888", fontSize: 13, marginBottom: 16 }, statusBadge: { display: "inline-block", padding: "6px 16px", borderRadius: 20, fontSize: 12, fontWeight: 600, marginBottom: 16 }, infoRow: { display: "flex", justifyContent: "flex-end", fontSize: 12, color: "#888", marginTop: 16 }, };