1 import { useState, useEffect } from "react";
2 import { useAuth } from "@/hooks/useAuth";
3 import { useLocation } from "wouter";
4 import { Button } from "@/components/ui/button";
5 import { Input } from "@/components/ui/input";
6 import { Card, CardContent } from "@/components/ui/card";
7 import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
8 import { Wrench, Mail, Lock, User, ArrowRight, ShieldCheck, Zap, KeyRound } from "lucide-react";
9 import { motion } from "framer-motion";
10
11 export default function AuthPage() {
12 const { user, loginMutation, registerMutation, quickLoginMutation } = useAuth();
13 const [, setLocation] = useLocation();
14 const [email, setEmail] = useState("");
15 const [password, setPassword] = useState("");
16 const [firstName, setFirstName] = useState("");
17 const [lastName, setLastName] = useState("");
18
19 useEffect(() => {
20 if (user) {
21 setLocation("/");
22 }
23 }, [user, setLocation]);
24
25 if (user) {
26 return null;
27 }
28
29 const handleLogin = (e: React.FormEvent) => {
30 e.preventDefault();
31 loginMutation.mutate({ email, password });
32 };
33
34 const handleRegister = (e: React.FormEvent) => {
35 e.preventDefault();
36 registerMutation.mutate({ email, password, firstName, lastName, role: "user" });
37 };
38
39 const handleAutofill = (techEmail: string, techPass: string = "password123") => {
40 setEmail(techEmail);
41 setPassword(techPass);
42 };
43
44 const handleQuickConnect = (techEmail: string) => {
45 quickLoginMutation.mutate({ email: techEmail });
46 };
47
48 const isPending = loginMutation.isPending || registerMutation.isPending || quickLoginMutation.isPending;
49
50 return (
51 <div className="min-h-screen bg-background flex items-center justify-center p-4 relative overflow-hidden">
52 {/* Background blobs */}
53 <div className="absolute top-0 left-0 w-full h-full -z-10">
54 <div className="absolute top-1/4 left-1/4 w-96 h-96 bg-primary/10 rounded-full blur-[100px] animate-pulse" />
55 <div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-indigo-500/10 rounded-full blur-[100px] animate-pulse delay-700" />
56 </div>
57
58 <motion.div
59 initial={{ opacity: 0, scale: 0.95 }}
60 animate={{ opacity: 1, scale: 1 }}
61 transition={{ duration: 0.5 }}
62 className="w-full max-w-md"
63 >
64 <div className="flex flex-col items-center mb-6">
65 <div className="h-16 w-16 rounded-2xl bg-primary flex items-center justify-center mb-4 shadow-glass">
66 <Wrench className="h-8 w-8 text-white" />
67 </div>
68 <h1 className="text-3xl font-black tracking-tight">JCRGuru</h1>
69 <p className="text-muted-foreground font-medium">Professional Technician & Diagnostic Hub</p>
70 </div>
71
72 {/* Quick Demo Access Bar */}
73 <div className="mb-4 bg-muted/40 backdrop-blur-md rounded-2xl p-3 border border-border/40">
74 <div className="flex items-center gap-1.5 text-xs font-semibold text-muted-foreground mb-2">
75 <Zap className="h-3.5 w-3.5 text-amber-500" />
76 <span>1-Click Technician Access</span>
77 </div>
78 <div className="grid grid-cols-3 gap-2">
79 <Button
80 type="button"
81 variant="outline"
82 size="sm"
83 disabled={isPending}
84 onClick={() => handleQuickConnect("Jhustle44@gmail.com")}
85 className="text-xs h-9 rounded-xl border-primary/30 hover:bg-primary/10 hover:text-primary transition-all flex flex-col items-center justify-center py-1"
86 >
87 <span className="font-bold text-[11px] leading-tight">Master Tech</span>
88 <span className="text-[9px] text-muted-foreground opacity-80">Jhustle44</span>
89 </Button>
90 <Button
91 type="button"
92 variant="outline"
93 size="sm"
94 disabled={isPending}
95 onClick={() => handleQuickConnect("tech@jcrguru.com")}
96 className="text-xs h-9 rounded-xl border-border/60 hover:bg-primary/10 hover:text-primary transition-all flex flex-col items-center justify-center py-1"
97 >
98 <span className="font-bold text-[11px] leading-tight">Field Tech</span>
99 <span className="text-[9px] text-muted-foreground opacity-80">tech@jcr</span>
100 </Button>
101 <Button
102 type="button"
103 variant="outline"
104 size="sm"
105 disabled={isPending}
106 onClick={() => handleQuickConnect("admin@jcrguru.com")}
107 className="text-xs h-9 rounded-xl border-border/60 hover:bg-primary/10 hover:text-primary transition-all flex flex-col items-center justify-center py-1"
108 >
109 <span className="font-bold text-[11px] leading-tight">Workshop</span>
110 <span className="text-[9px] text-muted-foreground opacity-80">admin</span>
111 </Button>
112 </div>
113 </div>
114
115 <Card className="border-border/40 shadow-glass rounded-[2rem] overflow-hidden bg-card/40 backdrop-blur-2xl">
116 <Tabs defaultValue="login" className="w-full">
117 <TabsList className="grid grid-cols-2 bg-muted/20 p-1 rounded-none border-b border-border/40">
118 <TabsTrigger value="login" className="rounded-none py-3 data-[state=active]:bg-transparent data-[state=active]:border-b-2 data-[state=active]:border-primary font-bold transition-all">Sign In</TabsTrigger>
119 <TabsTrigger value="register" className="rounded-none py-3 data-[state=active]:bg-transparent data-[state=active]:border-b-2 data-[state=active]:border-primary font-bold transition-all">Register</TabsTrigger>
120 </TabsList>
121
122 <CardContent className="p-6 sm:p-8">
123 <TabsContent value="login" className="mt-0 space-y-4">
124 <form onSubmit={handleLogin} className="space-y-4">
125 <div className="space-y-2">
126 <div className="flex items-center justify-between">
127 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">Email Address</label>
128 <button
129 type="button"
130 onClick={() => handleAutofill("Jhustle44@gmail.com", "password123")}
131 className="text-[11px] text-primary hover:underline flex items-center gap-1"
132 >
133 <KeyRound className="h-3 w-3" />
134 Autofill
135 </button>
136 </div>
137 <div className="relative">
138 <Mail className="absolute left-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
139 <Input
140 type="email"
141 placeholder="Jhustle44@gmail.com"
142 value={email}
143 onChange={(e) => setEmail(e.target.value)}
144 className="pl-12 h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
145 required
146 />
147 </div>
148 </div>
149 <div className="space-y-2">
150 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">Password</label>
151 <div className="relative">
152 <Lock className="absolute left-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
153 <Input
154 type="password"
155 placeholder="password123"
156 value={password}
157 onChange={(e) => setPassword(e.target.value)}
158 className="pl-12 h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
159 required
160 />
161 </div>
162 </div>
163 <Button
164 type="submit"
165 className="w-full h-12 rounded-2xl bg-primary hover:bg-primary/90 text-white font-bold shadow-lg shadow-primary/20 transition-all mt-4"
166 disabled={isPending}
167 >
168 {loginMutation.isPending ? "Authenticating..." : "Sign In to Repair Hub"}
169 {!loginMutation.isPending && <ArrowRight className="ml-2 h-4 w-4" />}
170 </Button>
171 </form>
172
173 <div className="pt-2 text-center">
174 <p className="text-xs text-muted-foreground">
175 Default credentials: <code className="bg-muted px-1.5 py-0.5 rounded text-foreground font-mono">password123</code>
176 </p>
177 </div>
178 </TabsContent>
179
180 <TabsContent value="register" className="mt-0">
181 <form onSubmit={handleRegister} className="space-y-4">
182 <div className="grid grid-cols-2 gap-3">
183 <div className="space-y-2">
184 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">First Name</label>
185 <Input
186 placeholder="John"
187 value={firstName}
188 onChange={(e) => setFirstName(e.target.value)}
189 className="h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
190 required
191 />
192 </div>
193 <div className="space-y-2">
194 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">Last Name</label>
195 <Input
196 placeholder="Hustle"
197 value={lastName}
198 onChange={(e) => setLastName(e.target.value)}
199 className="h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
200 required
201 />
202 </div>
203 </div>
204 <div className="space-y-2">
205 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">Email</label>
206 <div className="relative">
207 <Mail className="absolute left-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
208 <Input
209 type="email"
210 placeholder="tech@example.com"
211 value={email}
212 onChange={(e) => setEmail(e.target.value)}
213 className="pl-12 h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
214 required
215 />
216 </div>
217 </div>
218 <div className="space-y-2">
219 <label className="text-xs font-bold uppercase tracking-widest text-muted-foreground ml-1">Password</label>
220 <div className="relative">
221 <Lock className="absolute left-4 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
222 <Input
223 type="password"
224 placeholder="••••••••"
225 value={password}
226 onChange={(e) => setPassword(e.target.value)}
227 className="pl-12 h-12 rounded-2xl bg-muted/30 border-border/40 focus-visible:ring-primary/20"
228 required
229 />
230 </div>
231 </div>
232 <Button
233 type="submit"
234 className="w-full h-12 rounded-2xl bg-primary hover:bg-primary/90 text-white font-bold shadow-lg shadow-primary/20 transition-all mt-4"
235 disabled={isPending}
236 >
237 {registerMutation.isPending ? "Creating Account..." : "Create Technician Profile"}
238 {!registerMutation.isPending && <User className="ml-2 h-4 w-4" />}
239 </Button>
240 </form>
241 </TabsContent>
242 </CardContent>
243 </Tabs>
244 </Card>
245
246 <div className="flex items-center justify-center gap-2 mt-6 text-xs text-muted-foreground">
247 <ShieldCheck className="h-4 w-4 text-emerald-500" />
248 <span>Encrypted Session & Technical Access Control</span>
249 </div>
250 </motion.div>
251 </div>
252 );
253 }