Spaces:
Sleeping
Sleeping
File size: 3,916 Bytes
23b0ad9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | import { useState } from "react";
import type { User } from "firebase/auth";
type AuthMode = "signin" | "signup";
type AuthPanelProps = {
authBusy: boolean;
authEnabled: boolean;
authReady: boolean;
historyReady: boolean;
user: User | null;
onEmailAuth: (
mode: AuthMode,
email: string,
password: string
) => Promise<void>;
onGoogleAuth: () => Promise<void>;
onSignOut: () => Promise<void>;
};
export function AuthPanel({
authBusy,
authEnabled,
authReady,
historyReady,
user,
onEmailAuth,
onGoogleAuth,
onSignOut,
}: AuthPanelProps) {
const [mode, setMode] = useState<AuthMode>("signin");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const submitDisabled =
authBusy || !email.trim() || password.trim().length < 6 || !authReady;
if (!authEnabled) {
return (
<div className="card authCard">
<h2>Save Chat History</h2>
<p className="muted">
Firebase is not configured in the frontend yet. Add the Vite Firebase
variables to enable sign in and saved conversations.
</p>
</div>
);
}
if (user) {
return (
<div className="card authCard">
<h2>Account</h2>
<p className="authUserLabel">{user.email ?? "Signed in with Google"}</p>
<p className="muted">
This account can reopen the saved conversation on the next visit.
</p>
<div className="authActions">
<button
className="primaryBtn wide"
onClick={() => void onSignOut()}
disabled={authBusy}
>
Sign Out
</button>
<div className="authHint">
{historyReady
? "History sync is active."
: "Loading saved conversation..."}
</div>
</div>
</div>
);
}
return (
<div className="card authCard">
<div className="authHeader">
<h2>Save Chat History</h2>
<div className="authToggle">
<button
className={mode === "signin" ? "authTab active" : "authTab"}
onClick={() => setMode("signin")}
type="button"
>
Sign In
</button>
<button
className={mode === "signup" ? "authTab active" : "authTab"}
onClick={() => setMode("signup")}
type="button"
>
Sign Up
</button>
</div>
</div>
<p className="muted">
Guest mode still works. Sign in only if you want the chatbot to remember
your conversation.
</p>
<label className="authField">
<span>Email</span>
<input
type="email"
value={email}
onChange={(event) => setEmail(event.target.value)}
placeholder="name@example.com"
autoComplete="email"
/>
</label>
<label className="authField">
<span>Password</span>
<input
type="password"
value={password}
onChange={(event) => setPassword(event.target.value)}
placeholder="At least 6 characters"
autoComplete={mode === "signup" ? "new-password" : "current-password"}
/>
</label>
<div className="authActions">
<button
className="primaryBtn wide"
onClick={() => void onEmailAuth(mode, email, password)}
disabled={submitDisabled}
type="button"
>
{authBusy
? "Please wait..."
: mode === "signup"
? "Create Account"
: "Sign In"}
</button>
<button
className="ghost wide"
onClick={() => void onGoogleAuth()}
disabled={authBusy || !authReady}
type="button"
>
Continue with Google
</button>
</div>
</div>
);
}
|