Skip to content

Commit dfe93d1

Browse files
authored
Add files via upload
1 parent c704836 commit dfe93d1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+9134
-0
lines changed

Frontend/app/auth/login/page.tsx

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"use client"
2+
3+
import type React from "react"
4+
5+
import { useState } from "react"
6+
import Link from "next/link"
7+
import { useRouter } from "next/navigation"
8+
import { Button } from "@/components/ui/button"
9+
import { Input } from "@/components/ui/input"
10+
import { Label } from "@/components/ui/label"
11+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
12+
import { Calendar, Loader2 } from "lucide-react"
13+
import { useAuth } from "@/hooks/use-auth"
14+
import { useToast } from "@/hooks/use-toast"
15+
16+
export default function LoginPage() {
17+
const [email, setEmail] = useState("")
18+
const [password, setPassword] = useState("")
19+
const [isLoading, setIsLoading] = useState(false)
20+
const { signIn, signInWithGoogle } = useAuth()
21+
const { toast } = useToast()
22+
const router = useRouter()
23+
24+
const handleSubmit = async (e: React.FormEvent) => {
25+
e.preventDefault()
26+
setIsLoading(true)
27+
28+
try {
29+
await signIn(email, password)
30+
toast({
31+
title: "Success!",
32+
description: "You have successfully logged in.",
33+
})
34+
} catch (error) {
35+
toast({
36+
title: "Error",
37+
description: "Invalid email or password. Please try again.",
38+
variant: "destructive",
39+
})
40+
} finally {
41+
setIsLoading(false)
42+
}
43+
}
44+
45+
const handleGoogleSignIn = async () => {
46+
try {
47+
await signInWithGoogle()
48+
toast({
49+
title: "Success!",
50+
description: "You have successfully logged in with Google.",
51+
})
52+
} catch (error) {
53+
toast({
54+
title: "Error",
55+
description: "Failed to sign in with Google. Please try again.",
56+
variant: "destructive",
57+
})
58+
}
59+
}
60+
61+
return (
62+
<div className="container flex items-center justify-center min-h-[calc(100vh-8rem)] py-12">
63+
<Card className="w-full max-w-md">
64+
<CardHeader className="space-y-1">
65+
<div className="flex justify-center mb-4">
66+
<Calendar className="h-12 w-12 text-purple-600" />
67+
</div>
68+
<CardTitle className="text-2xl font-bold text-center">Sign in</CardTitle>
69+
<CardDescription className="text-center">
70+
Enter your email and password to access your account
71+
</CardDescription>
72+
</CardHeader>
73+
<CardContent className="space-y-4">
74+
<form onSubmit={handleSubmit} className="space-y-4">
75+
<div className="space-y-2">
76+
<Label htmlFor="email">Email</Label>
77+
<Input
78+
id="email"
79+
type="email"
80+
placeholder="[email protected]"
81+
value={email}
82+
onChange={(e) => setEmail(e.target.value)}
83+
required
84+
/>
85+
</div>
86+
<div className="space-y-2">
87+
<div className="flex items-center justify-between">
88+
<Label htmlFor="password">Password</Label>
89+
<Link href="/auth/forgot-password" className="text-sm text-purple-600 hover:text-purple-700">
90+
Forgot password?
91+
</Link>
92+
</div>
93+
<Input
94+
id="password"
95+
type="password"
96+
placeholder="••••••••"
97+
value={password}
98+
onChange={(e) => setPassword(e.target.value)}
99+
required
100+
/>
101+
</div>
102+
<Button type="submit" className="w-full" disabled={isLoading}>
103+
{isLoading ? (
104+
<>
105+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
106+
Signing in...
107+
</>
108+
) : (
109+
"Sign in"
110+
)}
111+
</Button>
112+
</form>
113+
<div className="relative">
114+
<div className="absolute inset-0 flex items-center">
115+
<span className="w-full border-t" />
116+
</div>
117+
<div className="relative flex justify-center text-xs uppercase">
118+
<span className="bg-background px-2 text-muted-foreground">Or continue with</span>
119+
</div>
120+
</div>
121+
<Button variant="outline" type="button" className="w-full" onClick={handleGoogleSignIn}>
122+
<svg className="mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
123+
<path
124+
fill="currentColor"
125+
d="M12 22q-2.05 0-3.875-.788t-3.188-2.15-2.137-3.175T2 12q0-2.075.788-3.887t2.15-3.175 3.175-2.138T12 2q2.075 0 3.887.788t3.175 2.15 2.138 3.175T22 12q0 2.05-.788 3.875t-2.15 3.188-3.175 2.137T12 22Z"
126+
/>
127+
</svg>
128+
Google
129+
</Button>
130+
</CardContent>
131+
<CardFooter className="flex flex-col space-y-4">
132+
<div className="text-center text-sm">
133+
Don&apos;t have an account?{" "}
134+
<Link href="/auth/register" className="text-purple-600 hover:text-purple-700 font-medium">
135+
Sign up
136+
</Link>
137+
</div>
138+
</CardFooter>
139+
</Card>
140+
</div>
141+
)
142+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
"use client"
2+
3+
import type React from "react"
4+
5+
import { useState } from "react"
6+
import Link from "next/link"
7+
import { Button } from "@/components/ui/button"
8+
import { Input } from "@/components/ui/input"
9+
import { Label } from "@/components/ui/label"
10+
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
11+
import { Calendar, Loader2 } from "lucide-react"
12+
import { useAuth } from "@/hooks/use-auth"
13+
import { useToast } from "@/hooks/use-toast"
14+
15+
export default function RegisterPage() {
16+
const [name, setName] = useState("")
17+
const [email, setEmail] = useState("")
18+
const [password, setPassword] = useState("")
19+
const [confirmPassword, setConfirmPassword] = useState("")
20+
const [isLoading, setIsLoading] = useState(false)
21+
const { signUp, signInWithGoogle } = useAuth()
22+
const { toast } = useToast()
23+
24+
const handleSubmit = async (e: React.FormEvent) => {
25+
e.preventDefault()
26+
27+
if (password !== confirmPassword) {
28+
toast({
29+
title: "Error",
30+
description: "Passwords do not match. Please try again.",
31+
variant: "destructive",
32+
})
33+
return
34+
}
35+
36+
setIsLoading(true)
37+
38+
try {
39+
await signUp(name, email, password)
40+
toast({
41+
title: "Success!",
42+
description: "Your account has been created.",
43+
})
44+
} catch (error) {
45+
toast({
46+
title: "Error",
47+
description: "Failed to create account. Please try again.",
48+
variant: "destructive",
49+
})
50+
} finally {
51+
setIsLoading(false)
52+
}
53+
}
54+
55+
return (
56+
<div className="container flex items-center justify-center min-h-[calc(100vh-8rem)] py-12">
57+
<Card className="w-full max-w-md">
58+
<CardHeader className="space-y-1">
59+
<div className="flex justify-center mb-4">
60+
<Calendar className="h-12 w-12 text-purple-600" />
61+
</div>
62+
<CardTitle className="text-2xl font-bold text-center">Create an account</CardTitle>
63+
<CardDescription className="text-center">Enter your information to create your account</CardDescription>
64+
</CardHeader>
65+
<CardContent className="space-y-4">
66+
<form onSubmit={handleSubmit} className="space-y-4">
67+
<div className="space-y-2">
68+
<Label htmlFor="name">Name</Label>
69+
<Input id="name" placeholder="John Doe" value={name} onChange={(e) => setName(e.target.value)} required />
70+
</div>
71+
<div className="space-y-2">
72+
<Label htmlFor="email">Email</Label>
73+
<Input
74+
id="email"
75+
type="email"
76+
placeholder="[email protected]"
77+
value={email}
78+
onChange={(e) => setEmail(e.target.value)}
79+
required
80+
/>
81+
</div>
82+
<div className="space-y-2">
83+
<Label htmlFor="password">Password</Label>
84+
<Input
85+
id="password"
86+
type="password"
87+
placeholder="••••••••"
88+
value={password}
89+
onChange={(e) => setPassword(e.target.value)}
90+
required
91+
/>
92+
</div>
93+
<div className="space-y-2">
94+
<Label htmlFor="confirm-password">Confirm Password</Label>
95+
<Input
96+
id="confirm-password"
97+
type="password"
98+
placeholder="••••••••"
99+
value={confirmPassword}
100+
onChange={(e) => setConfirmPassword(e.target.value)}
101+
required
102+
/>
103+
</div>
104+
<Button type="submit" className="w-full" disabled={isLoading}>
105+
{isLoading ? (
106+
<>
107+
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
108+
Creating account...
109+
</>
110+
) : (
111+
"Create account"
112+
)}
113+
</Button>
114+
</form>
115+
<div className="relative">
116+
<div className="absolute inset-0 flex items-center">
117+
<span className="w-full border-t" />
118+
</div>
119+
<div className="relative flex justify-center text-xs uppercase">
120+
<span className="bg-background px-2 text-muted-foreground">Or continue with</span>
121+
</div>
122+
</div>
123+
<Button variant="outline" type="button" className="w-full" onClick={signInWithGoogle}>
124+
<svg className="mr-2 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
125+
<path
126+
fill="currentColor"
127+
d="M12 22q-2.05 0-3.875-.788t-3.188-2.15-2.137-3.175T2 12q0-2.075.788-3.887t2.15-3.175 3.175-2.138T12 2q2.075 0 3.887.788t3.175 2.15 2.138 3.175T22 12q0 2.05-.788 3.875t-2.15 3.188-3.175 2.137T12 22Z"
128+
/>
129+
</svg>
130+
Google
131+
</Button>
132+
</CardContent>
133+
<CardFooter className="flex flex-col space-y-4">
134+
<div className="text-center text-sm">
135+
Already have an account?{" "}
136+
<Link href="/auth/login" className="text-purple-600 hover:text-purple-700 font-medium">
137+
Sign in
138+
</Link>
139+
</div>
140+
</CardFooter>
141+
</Card>
142+
</div>
143+
)
144+
}

0 commit comments

Comments
 (0)