https://altly.madebydanny.uk
1import { useState, useEffect } from "react";
2import { useNavigate } from "react-router-dom";
3import { Eye, Loader2 } from "lucide-react";
4import { Button } from "@/components/ui/button";
5import { Input } from "@/components/ui/input";
6import { Label } from "@/components/ui/label";
7import { Card } from "@/components/ui/card";
8import { useToast } from "@/hooks/use-toast";
9import { supabase } from "@/integrations/supabase/client";
10
11export default function Auth() {
12 const [email, setEmail] = useState("");
13 const [password, setPassword] = useState("");
14 const [isLogin, setIsLogin] = useState(true);
15 const [isLoading, setIsLoading] = useState(false);
16 const navigate = useNavigate();
17 const { toast } = useToast();
18
19 useEffect(() => {
20 // Check if user is already logged in
21 supabase.auth.getSession().then(({ data: { session } }) => {
22 if (session) {
23 navigate("/app");
24 }
25 });
26
27 const { data: { subscription } } = supabase.auth.onAuthStateChange((event, session) => {
28 if (session) {
29 navigate("/app");
30 }
31 });
32
33 return () => subscription.unsubscribe();
34 }, [navigate]);
35
36 const handleSubmit = async (e: React.FormEvent) => {
37 e.preventDefault();
38 setIsLoading(true);
39
40 try {
41 if (isLogin) {
42 const { error } = await supabase.auth.signInWithPassword({
43 email,
44 password,
45 });
46
47 if (error) throw error;
48
49 toast({
50 title: "Welcome back!",
51 description: "You've successfully signed in.",
52 });
53 } else {
54 const { error } = await supabase.auth.signUp({
55 email,
56 password,
57 options: {
58 emailRedirectTo: `${window.location.origin}/`,
59 },
60 });
61
62 if (error) throw error;
63
64 toast({
65 title: "Account created!",
66 description: "You've successfully signed up.",
67 });
68 }
69 } catch (error: any) {
70 toast({
71 title: "Error",
72 description: error.message || "An error occurred during authentication",
73 variant: "destructive",
74 });
75 } finally {
76 setIsLoading(false);
77 }
78 };
79
80 return (
81 <div className="min-h-screen bg-background flex items-center justify-center px-4">
82 <div className="w-full max-w-md">
83 <div className="text-center mb-8">
84 <div className="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-primary/20 mb-4">
85 <Eye className="w-8 h-8 text-primary" />
86 </div>
87 <h1 className="text-3xl font-bold text-foreground mb-2">ALTly</h1>
88 <p className="text-muted-foreground">
89 {isLogin ? "Sign in to continue" : "Create your account"}
90 </p>
91 </div>
92
93 <Card className="p-6">
94 <form onSubmit={handleSubmit} className="space-y-4">
95 <div className="space-y-2">
96 <Label htmlFor="email">Email</Label>
97 <Input
98 id="email"
99 type="email"
100 placeholder="you@example.com"
101 value={email}
102 onChange={(e) => setEmail(e.target.value)}
103 required
104 disabled={isLoading}
105 />
106 </div>
107
108 <div className="space-y-2">
109 <Label htmlFor="password">Password</Label>
110 <Input
111 id="password"
112 type="password"
113 placeholder="••••••••"
114 value={password}
115 onChange={(e) => setPassword(e.target.value)}
116 required
117 disabled={isLoading}
118 minLength={6}
119 />
120 </div>
121
122 <Button
123 type="submit"
124 className="w-full"
125 disabled={isLoading}
126 >
127 {isLoading ? (
128 <>
129 <Loader2 className="w-4 h-4 mr-2 animate-spin" />
130 {isLogin ? "Signing in..." : "Creating account..."}
131 </>
132 ) : (
133 <>{isLogin ? "Sign In" : "Sign Up"}</>
134 )}
135 </Button>
136
137 <div className="text-center text-sm">
138 <button
139 type="button"
140 onClick={() => setIsLogin(!isLogin)}
141 className="text-primary hover:underline"
142 disabled={isLoading}
143 >
144 {isLogin
145 ? "Don't have an account? Sign up"
146 : "Already have an account? Sign in"}
147 </button>
148 </div>
149 </form>
150 </Card>
151 </div>
152 </div>
153 );
154}