Skip to content

Commit e5a11c6

Browse files
committed
Co-authored-by: Cooperzilla <[email protected]>
1 parent 3625a16 commit e5a11c6

File tree

11 files changed

+217
-17
lines changed

11 files changed

+217
-17
lines changed

frontend/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
},
1616
"dependencies": {
1717
"@emailjs/browser": "^4.3.3",
18+
"@react-oauth/google": "^0.12.1",
1819
"@tanstack/react-router": "^1.40.0",
1920
"aos": "^2.3.4",
2021
"axios": "^1.7.2",
@@ -26,6 +27,7 @@
2627
"prop-types": "^15.8.1",
2728
"react": "^18.3.1",
2829
"react-dom": "^18.3.1",
30+
"react-google-button": "^0.8.0",
2931
"react-helmet-async": "^2.0.5",
3032
"sonner": "^1.5.0"
3133
},

frontend/pnpm-lock.yaml

+27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useEffect } from 'react';
2+
import './styles.css';
3+
4+
const GoogleSignInButton = ({ clientId, onSuccess, onFailure }) => {
5+
useEffect(() => {
6+
const startApp = () => {
7+
gapi.load('auth2', () => {
8+
const auth2 = gapi.auth2.init({
9+
client_id: clientId,
10+
cookiepolicy: 'single_host_origin',
11+
});
12+
attachSignin(document.getElementById('googleSignInButton'));
13+
});
14+
};
15+
16+
const attachSignin = (element) => {
17+
auth2.attachClickHandler(element, {},
18+
(googleUser) => {
19+
onSuccess(googleUser);
20+
}, (error) => {
21+
onFailure(error);
22+
});
23+
};
24+
25+
startApp();
26+
}, [clientId, onSuccess, onFailure]);
27+
28+
return (
29+
<div className="flex flex-col items-center">
30+
<div id="googleSignInButton" className="custom-google-button">
31+
<div className="icon"></div>
32+
<span className="buttonText">Google</span>
33+
</div>
34+
</div>
35+
);
36+
};
37+
38+
export default GoogleSignInButton;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@import 'https://fonts.googleapis.com/css?family=Roboto';
2+
@tailwind base;
3+
@tailwind components;
4+
@tailwind utilities;
5+
6+
.custom-google-button {
7+
@apply inline-block bg-white text-gray-700 w-48 rounded-lg border border-gray-300 shadow-md;
8+
@apply transition-transform transform hover:scale-105 duration-300;
9+
@apply flex items-center justify-center cursor-pointer select-none;
10+
}
11+
12+
.custom-google-button .icon {
13+
background: url('path-to-your-google-icon.png') no-repeat center center / contain;
14+
@apply w-10 h-10;
15+
}
16+
17+
.custom-google-button .buttonText {
18+
@apply font-bold text-sm;
19+
font-family: 'Roboto', sans-serif;
20+
}

frontend/src/components/Login/Login.jsx frontend/src/components/Login/SignIn.jsx

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,23 @@
11
import { useState } from 'react';
22
import { auth, signInWithGoogle, signInWithEmailAndPassword } from '../../firebaseConfig';
3+
// import { GoogleButton } from 'react-google-button'
4+
import { UserAuth } from '../context/AuthContext';
35

4-
const Login = () => {
6+
const SignIn = () => {
57
const [email, setEmail] = useState('');
68
const [password, setPassword] = useState('');
79

10+
const { googleSignIn } = UserAuth();
11+
12+
const handleGoogleSignIn = async () => {
13+
try {
14+
const { user } = await googleSignIn();
15+
console.log(user, "Logged in with Google");
16+
} catch (error) {
17+
console.log(error);
18+
}
19+
}
20+
821
const handleLogin = async () => {
922
try {
1023
await signInWithEmailAndPassword(auth, email, password);
@@ -30,10 +43,10 @@ const Login = () => {
3043
placeholder="Password"
3144
/>
3245
<button onClick={handleLogin}>Login</button>
33-
<button onClick={signInWithGoogle}>Login with Google</button>
46+
<button onClick={handleGoogleSignIn}>Login with Google</button>
3447
<button onClick={() => alert('Implement Discord login')}>Login with Discord</button>
3548
</div>
3649
);
3750
};
3851

39-
export default Login;
52+
export default SignIn;

frontend/src/context/AuthContext.jsx

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import {
2+
GoogleAuthProvider,
3+
signInWithPopup,
4+
signInWithRedirect,
5+
signOut,
6+
onAuthStateChanged
7+
} from "firebase/auth";
8+
9+
import { useState, useContext, createContext, useEffect } from "react";
10+
import { auth } from "../firebaseConfig";
11+
12+
const AuthContext = createContext();
13+
14+
export const AuthContextProvider = ({ children }) => {
15+
const [user, setUser] = useState({});
16+
17+
const googleSignIn = () => {
18+
const provider = new GoogleAuthProvider();
19+
signInWithPopup(auth, provider);
20+
}
21+
22+
useEffect(() => {
23+
const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
24+
setUser(currentUser);
25+
console.log("User:", currentUser);
26+
});
27+
return () => {
28+
unsubscribe();
29+
};
30+
}, []);
31+
32+
// const logOut = () => {
33+
// signOut();
34+
// }
35+
36+
return (
37+
<AuthContext.Provider value={{ googleSignIn }}>
38+
{children}
39+
</AuthContext.Provider>
40+
);
41+
};
42+
43+
export const UserAuth = () => {
44+
return useContext(AuthContext);
45+
}

frontend/src/firebaseConfig.js

+21-12
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
import { initializeApp } from "firebase/app";
33
import { getAnalytics } from "firebase/analytics";
44
import {
5-
getAuth,
6-
GoogleAuthProvider,
7-
signInWithPopup,
8-
signInWithEmailAndPassword,
9-
createUserWithEmailAndPassword,
10-
sendPasswordResetEmail,
11-
updatePassword,
12-
linkWithPopup
13-
} from 'firebase/auth';
5+
getAuth,
6+
GoogleAuthProvider,
7+
signInWithPopup,
8+
signInWithEmailAndPassword as firebaseSignInWithEmailAndPassword,
9+
createUserWithEmailAndPassword,
10+
sendPasswordResetEmail,
11+
updatePassword,
12+
linkWithPopup
13+
}
14+
from 'firebase/auth';
1415

15-
import { getAuth, GoogleAuthProvider, signInWithPopup, signInWithEmailAndPassword, createUserWithEmailAndPassword, sendPasswordResetEmail, updatePassword, linkWithPopup } from 'firebase/auth';
1616
import { getFirestore, doc, setDoc, getDoc } from 'firebase/firestore';
1717

1818

@@ -22,6 +22,15 @@ import { getFirestore, doc, setDoc, getDoc } from 'firebase/firestore';
2222
// Your web app's Firebase configuration
2323
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
2424

25+
console.log(import.meta.env.VITE_FIREBASE_API_KEY);
26+
console.log(import.meta.env.VITE_FIREBASE_AUTH_DOMAIN);
27+
console.log(import.meta.env.VITE_FIREBASE_PROJECT_ID);
28+
console.log(import.meta.env.VITE_FIREBASE_STORAGE_BUCKET);
29+
console.log(import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID);
30+
console.log(import.meta.env.VITE_FIREBASE_APP_ID);
31+
32+
// change to env.local?
33+
2534
const firebaseConfig = {
2635
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
2736
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
@@ -55,9 +64,9 @@ const registerWithEmail = async (email, password) => {
5564
};
5665

5766
const signInWithEmailAndPassword = async (email, password) => {
58-
await signInWithEmailAndPassword(auth, email, password);
67+
await firebaseSignInWithEmailAndPassword(auth, email, password);
5968
};
60-
69+
6170
const sendPasswordReset = async (email) => {
6271
await sendPasswordResetEmail(auth, email);
6372
};

frontend/src/main.jsx

+3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { routeTree } from './routeTree.gen'
55
import './styles/tailwind.css';
66
import './styles/App.css';
77
import { HelmetProvider } from 'react-helmet-async';
8+
import { AuthContextProvider } from './context/AuthContext';
89

910
const router = createRouter({
1011
routeTree,
@@ -17,7 +18,9 @@ if (!rootElement.innerHTML) {
1718
root.render(
1819
<React.StrictMode>
1920
<HelmetProvider>
21+
<AuthContextProvider>
2022
<RouterProvider router={router} />
23+
</AuthContextProvider>
2124
</HelmetProvider>
2225
</React.StrictMode>,
2326
)

frontend/src/routes/Login.jsx

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,40 @@
11
import { createFileRoute } from '@tanstack/react-router';
2+
import SignIn from '../components/Login/SignIn'
3+
import { GoogleButton } from 'react-google-button'
4+
import { UserAuth } from '../context/AuthContext';
5+
import '../styles/Login.css';
26

37
export const Route = createFileRoute('/Login')({
48
component: Login,
59
});
610

711
function Login() {
12+
13+
const { googleSignIn } = UserAuth();
14+
15+
const handleGoogleSignIn = async () => {
16+
try {
17+
const { user } = await googleSignIn();
18+
console.log(user);
19+
} catch (error) {
20+
console.log(error);
21+
}
22+
}
23+
824
return (
9-
<p></p>
25+
<>
26+
<SignIn/>
27+
<div>
28+
<div className="flex justify-center items-center h-screen m-auto max-w-80 py-4">
29+
<GoogleButton
30+
onClick={handleGoogleSignIn}
31+
className="custom-google-button"
32+
/>
33+
</div>
34+
</div>
35+
</>
1036
)
11-
}
37+
}
38+
39+
40+
// Protected Route for account page/dashboard

frontend/src/styles/Login.css

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;
4+
5+
.custom-google-button {
6+
animation: bounceIn 1s;
7+
border-radius: 10px;
8+
}
9+
10+
.custom-google-button .icon {
11+
border-radius: 10px;
12+
}
13+

frontend/tailwind.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
fontFamily: {
1313
sans: ['"Bai Jamjuree"', "sans-serif"],
1414
serif: ['"Bebas Neue"', "serif"]
15+
serif: ['"Montserrat"', "serif"]
1516
}
1617
},
1718
},

0 commit comments

Comments
 (0)