Skip to content

Commit 672142d

Browse files
committed
fix: update title in index.html and enhance Auth component for email confirmation
1 parent 6feb191 commit 672142d

3 files changed

Lines changed: 147 additions & 110 deletions

File tree

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Typing Learning Website</title>
7+
<title>Typing Master</title>
88
<meta name="twitter:card" content="summary_large_image" />
99
</head>
1010
<body>

src/components/Auth.tsx

Lines changed: 144 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,33 @@
11
import { useState } from 'react';
22
import { useAuth } from '../contexts/AuthContext';
3-
import { Keyboard, Mail, Lock, AlertCircle, Github } from 'lucide-react';
3+
import { Keyboard, Mail, Lock, AlertCircle, CheckCircle, Github } from 'lucide-react'; // Added CheckCircle
44

55
export default function Auth() {
66
const [isLogin, setIsLogin] = useState(true);
77
const [email, setEmail] = useState('');
88
const [password, setPassword] = useState('');
99
const [error, setError] = useState('');
10+
const [successMessage, setSuccessMessage] = useState('');
11+
const [isConfirmationSent, setIsConfirmationSent] = useState(false); // New state
1012
const [loading, setLoading] = useState(false);
1113
const { signIn, signUp, signInWithGithub } = useAuth();
1214

1315
const handleSubmit = async (e: React.FormEvent) => {
1416
e.preventDefault();
1517
setError('');
18+
setSuccessMessage('');
1619
setLoading(true);
1720

18-
const { error } = isLogin
21+
const result = isLogin
1922
? await signIn(email, password)
2023
: await signUp(email, password);
2124

22-
if (error) {
23-
setError(error.message);
25+
if (result.error) {
26+
setError(result.error.message);
27+
setIsConfirmationSent(false);
28+
} else {
29+
setSuccessMessage('');
30+
setIsConfirmationSent(true); // Set flag for confirmation UI
2431
}
2532

2633
setLoading(false);
@@ -48,111 +55,144 @@ export default function Auth() {
4855
</div>
4956

5057
<div className="bg-white rounded-2xl shadow-xl p-8">
51-
<div className="flex gap-2 mb-6">
52-
<button
53-
onClick={() => setIsLogin(true)}
54-
className={`flex-1 py-2 rounded-lg font-medium transition-all ${
55-
isLogin
56-
? 'bg-blue-600 text-white'
57-
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
58-
}`}
59-
>
60-
Login
61-
</button>
62-
<button
63-
onClick={() => setIsLogin(false)}
64-
className={`flex-1 py-2 rounded-lg font-medium transition-all ${
65-
!isLogin
66-
? 'bg-blue-600 text-white'
67-
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
68-
}`}
69-
>
70-
Sign Up
71-
</button>
72-
</div>
73-
74-
{error && (
75-
<div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg flex items-center gap-2 text-red-700 text-sm">
76-
<AlertCircle className="w-4 h-4 flex-shrink-0" />
77-
<span>{error}</span>
78-
</div>
79-
)}
80-
81-
{/* GitHub Sign-In Button */}
82-
<button
83-
onClick={handleGithubSignIn}
84-
disabled={loading}
85-
className="w-full py-3 mb-4 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors font-medium disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
86-
>
87-
<Github className="w-5 h-5" />
88-
Sign in with GitHub
89-
</button>
90-
91-
<div className="relative mb-4">
92-
<div className="absolute inset-0 flex items-center">
93-
<div className="w-full border-t border-gray-300"></div>
94-
</div>
95-
<div className="relative flex justify-center text-sm">
96-
<span className="px-2 bg-white text-gray-500">
97-
Or continue with email
98-
</span>
58+
{isConfirmationSent ? (
59+
// Confirmation UI
60+
<div className="text-center">
61+
<CheckCircle className="w-16 h-16 text-green-500 mx-auto mb-4" />
62+
<h2 className="text-2xl font-bold text-gray-800 mb-2">Check Your Email</h2>
63+
<p className="text-gray-600 mb-4">
64+
We've sent a confirmation link to <strong>{email}</strong>.
65+
</p>
66+
<ul className="text-left text-sm text-gray-600 mb-6 space-y-2">
67+
<li>1. Open your email inbox.</li>
68+
<li>2. Click the confirmation link.</li>
69+
<li>3. Return here and log in.</li>
70+
</ul>
71+
<button
72+
onClick={() => {
73+
setIsConfirmationSent(false);
74+
setSuccessMessage('');
75+
setIsLogin(true);
76+
}}
77+
className="w-full py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium"
78+
>
79+
Back to Login
80+
</button>
9981
</div>
100-
</div>
101-
102-
<form onSubmit={handleSubmit} className="space-y-4">
103-
<div>
104-
<label className="block text-sm font-medium text-gray-700 mb-2">
105-
Email
106-
</label>
107-
<div className="relative">
108-
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
109-
<input
110-
type="email"
111-
value={email}
112-
onChange={(e) => setEmail(e.target.value)}
113-
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
114-
placeholder="you@example.com"
115-
required
116-
/>
82+
) : (
83+
// Normal Auth UI
84+
<>
85+
<div className="flex gap-2 mb-6">
86+
<button
87+
onClick={() => setIsLogin(true)}
88+
className={`flex-1 py-2 rounded-lg font-medium transition-all ${
89+
isLogin
90+
? 'bg-blue-600 text-white'
91+
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
92+
}`}
93+
>
94+
Login
95+
</button>
96+
<button
97+
onClick={() => setIsLogin(false)}
98+
className={`flex-1 py-2 rounded-lg font-medium transition-all ${
99+
!isLogin
100+
? 'bg-blue-600 text-white'
101+
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
102+
}`}
103+
>
104+
Sign Up
105+
</button>
117106
</div>
118-
</div>
119107

120-
<div>
121-
<label className="block text-sm font-medium text-gray-700 mb-2">
122-
Password
123-
</label>
124-
<div className="relative">
125-
<Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
126-
<input
127-
type="password"
128-
value={password}
129-
onChange={(e) => setPassword(e.target.value)}
130-
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
131-
placeholder="••••••••"
132-
required
133-
minLength={6}
134-
/>
108+
{error && (
109+
<div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg flex items-center gap-2 text-red-700 text-sm">
110+
<AlertCircle className="w-4 h-4 flex-shrink-0" />
111+
<span>{error}</span>
112+
</div>
113+
)}
114+
115+
{successMessage && (
116+
<div className="mb-4 p-3 bg-green-50 border border-green-200 rounded-lg flex items-center gap-2 text-green-700 text-sm">
117+
<CheckCircle className="w-4 h-4 flex-shrink-0" />
118+
<span>{successMessage}</span>
119+
</div>
120+
)}
121+
122+
<button
123+
onClick={handleGithubSignIn}
124+
disabled={loading}
125+
className="w-full py-3 mb-4 bg-gray-900 text-white rounded-lg hover:bg-gray-800 transition-colors font-medium disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
126+
>
127+
<Github className="w-5 h-5" />
128+
Sign in with GitHub
129+
</button>
130+
131+
<div className="relative mb-4">
132+
<div className="absolute inset-0 flex items-center">
133+
<div className="w-full border-t border-gray-300"></div>
134+
</div>
135+
<div className="relative flex justify-center text-sm">
136+
<span className="px-2 bg-white text-gray-500">Or continue with email</span>
137+
</div>
135138
</div>
136-
</div>
137139

138-
<button
139-
type="submit"
140-
disabled={loading}
141-
className="w-full py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium disabled:opacity-50 disabled:cursor-not-allowed"
142-
>
143-
{loading ? 'Loading...' : isLogin ? 'Login' : 'Sign Up'}
144-
</button>
145-
</form>
146-
147-
<div className="mt-6 text-center text-sm text-gray-600">
148-
{isLogin ? "Don't have an account? " : "Already have an account? "}
149-
<button
150-
onClick={() => setIsLogin(!isLogin)}
151-
className="text-blue-600 hover:text-blue-700 font-medium"
152-
>
153-
{isLogin ? 'Sign up' : 'Login'}
154-
</button>
155-
</div>
140+
<form onSubmit={handleSubmit} className="space-y-4">
141+
<div>
142+
<label className="block text-sm font-medium text-gray-700 mb-2">
143+
Email
144+
</label>
145+
<div className="relative">
146+
<Mail className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
147+
<input
148+
type="email"
149+
value={email}
150+
onChange={(e) => setEmail(e.target.value)}
151+
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
152+
placeholder="you@example.com"
153+
required
154+
/>
155+
</div>
156+
</div>
157+
158+
<div>
159+
<label className="block text-sm font-medium text-gray-700 mb-2">
160+
Password
161+
</label>
162+
<div className="relative">
163+
<Lock className="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
164+
<input
165+
type="password"
166+
value={password}
167+
onChange={(e) => setPassword(e.target.value)}
168+
className="w-full pl-10 pr-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none"
169+
placeholder="••••••••"
170+
required
171+
minLength={6}
172+
/>
173+
</div>
174+
</div>
175+
176+
<button
177+
type="submit"
178+
disabled={loading}
179+
className="w-full py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors font-medium disabled:opacity-50 disabled:cursor-not-allowed"
180+
>
181+
{loading ? 'Loading...' : isLogin ? 'Login' : 'Sign Up'}
182+
</button>
183+
</form>
184+
185+
<div className="mt-6 text-center text-sm text-gray-600">
186+
{isLogin ? "Don't have an account? " : "Already have an account? "}
187+
<button
188+
onClick={() => setIsLogin(!isLogin)}
189+
className="text-blue-600 hover:text-blue-700 font-medium"
190+
>
191+
{isLogin ? 'Sign up' : 'Login'}
192+
</button>
193+
</div>
194+
</>
195+
)}
156196
</div>
157197

158198
<div className="mt-6 text-center text-sm text-gray-500">

src/contexts/AuthContext.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,10 @@ export function AuthProvider({ children }: { children: ReactNode }) {
3535
const signUp = async (email: string, password: string) => {
3636
const { error } = await supabase.auth.signUp({ email, password });
3737
if (error) {
38-
// Handle specific errors
39-
if (error.message.includes('password')) {
40-
return { error: { message: 'Password is compromised or too weak. Choose a stronger one.' } };
41-
}
4238
return { error };
4339
}
44-
return { error: null };
40+
// Success: User created, email sent
41+
return { error: null, message: 'Check your email for confirmation link.' };
4542
};
4643

4744
const signIn = async (email: string, password: string) => {

0 commit comments

Comments
 (0)