This repository has no description
1import React, { useState, useEffect } from 'react';
2import { useLocation, useNavigate } from 'react-router-dom';
3import { useAuth } from '../../contexts/AuthContext';
4import './Login.css';
5
6const Login = () => {
7 const [handle, setHandle] = useState('');
8 const { login, loading, error, isAuthenticated } = useAuth();
9 const navigate = useNavigate();
10 const location = useLocation();
11
12 // Extract returnUrl from query parameters
13 const queryParams = new URLSearchParams(location.search);
14 const returnUrl = queryParams.get('returnUrl') || '/verifier';
15
16 console.log('Login component: returnUrl =', returnUrl);
17
18 // Log auth status to debug
19 useEffect(() => {
20 console.log('Login component auth status:', {
21 isAuthenticated,
22 loading,
23 hasError: !!error,
24 returnUrl
25 });
26 }, [isAuthenticated, loading, error, returnUrl]);
27
28 // Handle redirection after successful authentication
29 useEffect(() => {
30 if (isAuthenticated) {
31 console.log('Login: User is authenticated, redirecting to', returnUrl);
32
33 // Set a short delay to ensure state updates complete
34 setTimeout(() => {
35 console.log('Login: Executing redirect to', returnUrl);
36 window.location.replace(returnUrl);
37 }, 100);
38 }
39 }, [isAuthenticated, returnUrl]);
40
41 const handleInputChange = (event) => {
42 setHandle(event.target.value);
43 };
44
45 const handleSubmit = async (event) => {
46 event.preventDefault();
47 console.log(`Login attempt for handle: ${handle || 'default PDS'}, returnUrl: ${returnUrl}`);
48
49 try {
50 // Store the returnUrl in localStorage as a backup
51 localStorage.setItem('auth_redirect_url', returnUrl);
52
53 // Call the login function from AuthContext
54 await login(handle || null, returnUrl);
55 } catch (err) {
56 console.error('Login error:', err);
57 }
58 };
59
60 // If already authenticated, show a message while redirecting
61 if (isAuthenticated) {
62 return (
63 <div className="login-container login-status">
64 <p>Already logged in. Redirecting to {returnUrl}...</p>
65 </div>
66 );
67 }
68
69 return (
70 <div className="home-page">
71 <div className="home-content">
72 <h1>Login to cred.blue</h1>
73 <p>Enter your Bluesky or ATProto handle</p>
74 <form onSubmit={handleSubmit} className="login-form">
75 <input
76 type="text"
77 value={handle}
78 onChange={handleInputChange}
79 placeholder="username.bsky.social"
80 aria-label="Bluesky Handle (optional)"
81 className="login-input-field"
82 disabled={loading}
83 />
84 {loading && <p className="login-status-message">Processing...</p>}
85 {error && <p className="login-error-message">Login failed: {error}</p>}
86 <button
87 type="submit"
88 disabled={loading || isAuthenticated}
89 className="login-submit-button"
90 >
91 {loading ? 'Processing...' : 'Login with Bluesky'}
92 </button>
93 </form>
94 <p className="login-privacy-note">
95 We use official Bluesky/ATProto OAuth to securely process your login.
96 </p>
97 </div>
98 </div>
99 );
100};
101
102export default Login;