chore(login): simplify to login-only, remove register/reset tabs
The /login page previously had three tabs (Login / Register / Reset Password) wired through useAuth(). The Register and Reset handlers were removed in this pass — only the Login form remains, plus a small UI/styling cleanup that was collateral. - Drop Tabs imports + the active-tab state plumbing - Drop regName/regEmail/regPassword/regConfirm + resetEmail state - Drop handleRegister + handleReset handlers (login-only now) - Drop useAuth().register / useAuth().requestPasswordReset destructuring - Trim the local stylesheet comments that referenced the Base UI tabs triggers (no longer applicable) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
bd328d40dc
commit
742010a9a9
1 changed files with 42 additions and 211 deletions
|
|
@ -7,7 +7,6 @@ import { Button } from "@/components/ui/button";
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import { toast } from "sonner";
|
||||
import { Loader2 } from "lucide-react";
|
||||
|
||||
|
|
@ -66,20 +65,13 @@ const primaryButtonStyle = {
|
|||
const labelStyle = { color: BRAND.textSecondary };
|
||||
|
||||
export default function AuthPage() {
|
||||
const { login, register, requestPasswordReset } = useAuth();
|
||||
const { login } = useAuth();
|
||||
const router = useRouter();
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const [loginEmail, setLoginEmail] = useState("");
|
||||
const [loginPassword, setLoginPassword] = useState("");
|
||||
|
||||
const [regName, setRegName] = useState("");
|
||||
const [regEmail, setRegEmail] = useState("");
|
||||
const [regPassword, setRegPassword] = useState("");
|
||||
const [regConfirm, setRegConfirm] = useState("");
|
||||
|
||||
const [resetEmail, setResetEmail] = useState("");
|
||||
|
||||
const handleLogin = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
|
|
@ -95,61 +87,15 @@ export default function AuthPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleRegister = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (regPassword !== regConfirm) {
|
||||
toast.error("Passwords do not match");
|
||||
return;
|
||||
}
|
||||
setLoading(true);
|
||||
try {
|
||||
await register(regEmail, regPassword, regConfirm, regName);
|
||||
toast.success("Account created successfully");
|
||||
router.push("/dashboard");
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : "Registration failed";
|
||||
toast.error(message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
try {
|
||||
await requestPasswordReset(resetEmail);
|
||||
toast.success("Password reset email sent");
|
||||
} catch (err: unknown) {
|
||||
const message = err instanceof Error ? err.message : "Reset failed";
|
||||
toast.error(message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative min-h-screen w-full overflow-hidden flex items-center justify-center px-4 py-4 sm:py-10"
|
||||
style={{ background: BRAND.inkNavy }}
|
||||
>
|
||||
{/* === Local stylesheet — scoped to this card via the wrapper class
|
||||
so they never bleed into the rest of the app. Targets the
|
||||
Base UI tabs triggers (data-active toggles on the active tab)
|
||||
and the input focus ring so the form reads as a single
|
||||
branded surface. */}
|
||||
so they never bleed into the rest of the app. Targets the input
|
||||
focus ring so the form reads as a single branded surface. */}
|
||||
<style>{`
|
||||
.wfdash-login [data-slot="tabs-trigger"] {
|
||||
color: ${BRAND.textSecondary};
|
||||
}
|
||||
.wfdash-login [data-slot="tabs-trigger"]:hover:not([data-active]) {
|
||||
color: ${BRAND.textPrimary};
|
||||
}
|
||||
.wfdash-login [data-slot="tabs-trigger"][data-active] {
|
||||
background: linear-gradient(180deg, ${BRAND.brandBlue} 0%, ${BRAND.brandBlueDeep} 100%) !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: 0 4px 12px -2px rgba(55, 125, 207, 0.45) !important;
|
||||
}
|
||||
.wfdash-login [data-slot="input"]:focus-visible {
|
||||
border-color: ${BRAND.brandBlue} !important;
|
||||
box-shadow: 0 0 0 3px rgba(55, 125, 207, 0.25) !important;
|
||||
|
|
@ -237,161 +183,46 @@ export default function AuthPage() {
|
|||
</CardHeader>
|
||||
|
||||
<CardContent className="pt-1 pb-4 sm:pt-2 sm:pb-7">
|
||||
<Tabs defaultValue="login">
|
||||
<TabsList
|
||||
className="grid w-full grid-cols-3 h-8 text-xs p-1 sm:h-10 sm:text-sm"
|
||||
style={{
|
||||
background: BRAND.inkNavyDeep,
|
||||
border: `1px solid ${BRAND.hairline}`,
|
||||
}}
|
||||
<form onSubmit={handleLogin} className="space-y-3 mt-3 sm:space-y-4 sm:mt-5">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-email" style={labelStyle}>
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="login-email"
|
||||
type="email"
|
||||
value={loginEmail}
|
||||
onChange={(e) => setLoginEmail(e.target.value)}
|
||||
required
|
||||
placeholder="you@example.com"
|
||||
className="h-9 sm:h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-password" style={labelStyle}>
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
id="login-password"
|
||||
type="password"
|
||||
value={loginPassword}
|
||||
onChange={(e) => setLoginPassword(e.target.value)}
|
||||
required
|
||||
className="h-9 sm:h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full h-9 text-sm font-semibold mt-1 sm:h-11 sm:mt-2"
|
||||
disabled={loading}
|
||||
style={primaryButtonStyle}
|
||||
>
|
||||
<TabsTrigger value="login">Login</TabsTrigger>
|
||||
<TabsTrigger value="register">Register</TabsTrigger>
|
||||
<TabsTrigger value="reset">Reset</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="login">
|
||||
<form onSubmit={handleLogin} className="space-y-3 mt-3 sm:space-y-4 sm:mt-5">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-email" style={labelStyle}>
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="login-email"
|
||||
type="email"
|
||||
value={loginEmail}
|
||||
onChange={(e) => setLoginEmail(e.target.value)}
|
||||
required
|
||||
placeholder="you@example.com"
|
||||
className="h-9 sm:h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="login-password" style={labelStyle}>
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
id="login-password"
|
||||
type="password"
|
||||
value={loginPassword}
|
||||
onChange={(e) => setLoginPassword(e.target.value)}
|
||||
required
|
||||
className="h-9 sm:h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full h-9 text-sm font-semibold mt-1 sm:h-11 sm:mt-2"
|
||||
disabled={loading}
|
||||
style={primaryButtonStyle}
|
||||
>
|
||||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
Sign In
|
||||
</Button>
|
||||
</form>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="register">
|
||||
<form onSubmit={handleRegister} className="space-y-4 mt-5">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-name" style={labelStyle}>
|
||||
Name
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-name"
|
||||
value={regName}
|
||||
onChange={(e) => setRegName(e.target.value)}
|
||||
required
|
||||
className="h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-email" style={labelStyle}>
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-email"
|
||||
type="email"
|
||||
value={regEmail}
|
||||
onChange={(e) => setRegEmail(e.target.value)}
|
||||
required
|
||||
className="h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-password" style={labelStyle}>
|
||||
Password
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-password"
|
||||
type="password"
|
||||
value={regPassword}
|
||||
onChange={(e) => setRegPassword(e.target.value)}
|
||||
required
|
||||
minLength={8}
|
||||
className="h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reg-confirm" style={labelStyle}>
|
||||
Confirm Password
|
||||
</Label>
|
||||
<Input
|
||||
id="reg-confirm"
|
||||
type="password"
|
||||
value={regConfirm}
|
||||
onChange={(e) => setRegConfirm(e.target.value)}
|
||||
required
|
||||
minLength={8}
|
||||
className="h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full h-11 text-sm font-semibold mt-2"
|
||||
disabled={loading}
|
||||
style={primaryButtonStyle}
|
||||
>
|
||||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
Create Account
|
||||
</Button>
|
||||
</form>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="reset">
|
||||
<form onSubmit={handleReset} className="space-y-4 mt-5">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="reset-email" style={labelStyle}>
|
||||
Email
|
||||
</Label>
|
||||
<Input
|
||||
id="reset-email"
|
||||
type="email"
|
||||
value={resetEmail}
|
||||
onChange={(e) => setResetEmail(e.target.value)}
|
||||
required
|
||||
className="h-11"
|
||||
style={inputStyle}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full h-11 text-sm font-semibold mt-2"
|
||||
disabled={loading}
|
||||
style={primaryButtonStyle}
|
||||
>
|
||||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
Send Reset Email
|
||||
</Button>
|
||||
</form>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
{loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
|
||||
Sign In
|
||||
</Button>
|
||||
</form>
|
||||
</CardContent>
|
||||
|
||||
{/* === Brand-tinted footer dots — a tiny echo of the three logo
|
||||
|
|
|
|||
Loading…
Reference in a new issue