Skip to content

Commit

Permalink
firebase auth implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
arazaki committed Aug 25, 2022
1 parent 2ae6bbc commit 4b9c401
Show file tree
Hide file tree
Showing 12 changed files with 378 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,5 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

.env
7 changes: 7 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import { useContext } from "react";
import Header from "components/Header";
import { Outlet } from "react-router-dom";
import { Container, Layout } from "./styles/globalStyles";
import FirebaseAuthService from "./firebase/FirebaseAuthService";
import GlobalContext from "store/context";

function App() {
const { setUser } = useContext(GlobalContext);

FirebaseAuthService.subscribeToAuthChanges(setUser);

return (
<div className="App">
<Layout>
Expand Down
97 changes: 97 additions & 0 deletions src/components/Login/SignIn/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import FirebaseAuthService from "../../../firebase/FirebaseAuthService";
import { useState, useContext } from "react";
import { Content, ButtonGroup, FormGroup } from "./styles";
import MainButton from "components/MainButton";
import GlobalContext from "store/context";

const SignIn = () => {
const { user } = useContext(GlobalContext);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");

const handleSubmit = async (e) => {
e.preventDefault();
try {
await FirebaseAuthService.loginUser(username, password);
setUsername("");
setPassword("");
} catch (error) {
alert(error.message);
}
};

const handleLoginWithGoogle = async () => {
try {
await FirebaseAuthService.loginWithGoogle();
} catch (error) {
alert(error.message);
}
};

const handleSendResetPasswordEmail = async () => {
if (!username) {
alert("Missing username");
return;
}

try {
await FirebaseAuthService.resetPassword(username);
alert("Sent the password reset email");
} catch (error) {
alert(error.message);
}
};

const handleLogout = () => {
FirebaseAuthService.logoutUser();
};

return (
<Content>
{user ? (
<div>
<h2>Welcome, {user.email}</h2>
<MainButton onClick={handleLogout}>Logout</MainButton>
</div>
) : (
<>
<h1>Create an account</h1>
<FormGroup onSubmit={handleSubmit}>
<label>
Email
<input
placeholder="Email"
type="email"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</label>
<label>
Password
<input
placeholder="Password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<ButtonGroup>
<button type="button" onClick={handleSendResetPasswordEmail}>
Reset Password
</button>
<button type="submit">Login</button>
<button type="button" onClick={handleLoginWithGoogle}>
Login With Google
</button>
<button type="button">Sign Up</button>
</ButtonGroup>
</FormGroup>
</>
)}
</Content>
);
};

export default SignIn;
49 changes: 49 additions & 0 deletions src/components/Login/SignIn/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import styled from "styled-components";

export const Content = styled.div`
height: 100%;
padding: 3rem 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: center;
& > h1 {
margin-bottom: 3rem;
}
`;

export const FormGroup = styled.form`
& > label {
font-size: 1.4rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
& > input {
font-size: 1.6rem;
margin-bottom: 1rem;
padding: 1rem;
border-radius: 0.5rem;
border: none;
}
}
`;

export const ButtonGroup = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
gap: 1rem;
& > button {
border: none;
padding: 1rem 5rem;
border-radius: 0.5rem;
background-color: #1aae9f;
color: #fff;
cursor: pointer;
font-weight: 600;
font-size: 1.6rem;
}
`;
69 changes: 69 additions & 0 deletions src/components/Login/SignUp/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import FirebaseAuthService from "../../../firebase/FirebaseAuthService";
import { useState, useContext } from "react";
import { Content, ButtonGroup, FormGroup } from "./styles";
import MainButton from "components/MainButton";
import GlobalContext from "store/context";

const SignUp = () => {
const { user } = useContext(GlobalContext);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");

const handleSubmit = async (e) => {
e.preventDefault();

try {
await FirebaseAuthService.registerUser(username, password);
setUsername("");
setPassword("");
} catch (error) {
alert(error.message);
}
};

const handleLogout = () => {
FirebaseAuthService.logoutUser();
};

return (
<Content>
{user ? (
<div>
<h2>Welcome, {user.email}</h2>
<MainButton onClick={handleLogout}>Logout</MainButton>
</div>
) : (
<>
<h1>Create an account</h1>
<FormGroup onSubmit={handleSubmit}>
<label>
Email
<input
placeholder="Email"
type="email"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</label>
<label>
Password
<input
placeholder="Password"
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</label>
<ButtonGroup>
<button type="submit">Sign Up</button>
</ButtonGroup>
</FormGroup>
</>
)}
</Content>
);
};

export default SignUp;
48 changes: 48 additions & 0 deletions src/components/Login/SignUp/styles.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import styled from "styled-components";

export const Content = styled.div`
height: 100%;
padding: 3rem 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: center;
& > h1 {
margin-bottom: 3rem;
}
`;

export const FormGroup = styled.form`
& > label {
font-size: 1.4rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
& > input {
font-size: 1.6rem;
margin-bottom: 1rem;
padding: 1rem;
border-radius: 0.5rem;
border: none;
}
}
`;

export const ButtonGroup = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: stretch;
& > button {
border: none;
padding: 1rem 5rem;
border-radius: 0.5rem;
background-color: #1aae9f;
color: #fff;
cursor: pointer;
font-weight: 600;
font-size: 1.6rem;
}
`;
65 changes: 65 additions & 0 deletions src/firebase/FirebaseAuthService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import firebase from "./FirebaseConfig";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
sendPasswordResetEmail,
signInWithPopup,
GoogleAuthProvider,
onAuthStateChanged,
} from "firebase/auth";

const auth = firebase.auth;

const registerUser = async (email, password) => {
try {
return await createUserWithEmailAndPassword(auth, email, password);
} catch (error) {
throw error;
}
};

const loginUser = async (email, password) => {
try {
return await signInWithEmailAndPassword(auth, email, password);
} catch (error) {
throw error;
}
};

const logoutUser = () => {
auth.signOut();
};

const loginWithGoogle = async () => {
const provider = new GoogleAuthProvider();
try {
return await signInWithPopup(auth, provider);
} catch (error) {
throw error;
}
};

const subscribeToAuthChanges = (handleAuthChanges) => {
onAuthStateChanged(auth, (user) => {
handleAuthChanges(user);
});
};

const resetPassword = async (email) => {
try {
return await sendPasswordResetEmail(auth, email);
} catch (error) {
throw error;
}
};

const FirebaseAuthService = {
registerUser,
loginUser,
logoutUser,
resetPassword,
loginWithGoogle,
subscribeToAuthChanges,
};

export default FirebaseAuthService;
25 changes: 25 additions & 0 deletions src/firebase/FirebaseConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
import { getAuth } from "firebase/auth";

const config = {
apiKey: process.env.REACT_APP_API_KEY,
authDomain: process.env.REACT_APP_AUTH_DOMAIN,
projectId: process.env.REACT_APP_PROJECT_ID,
storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
appId: process.env.REACT_APP_APP_ID,
measurementId: process.env.REACT_APP_MEASUREMENT_ID,
};

// Initialize Firebase
const firebaseApp = initializeApp(config);
const auth = getAuth(firebaseApp);
const analytics = getAnalytics(firebaseApp);

const firebaseConfig = {
auth,
analytics,
};

export default firebaseConfig;
4 changes: 4 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import EditTodo from "components/Todo/EditTodo";
import ViewTodo from "components/Todo/ViewTodo";
import Reorder from "components/Criteria/Reorder";
import EditCriteriaList from "components/Criteria/EditCriteriaList";
import SignUp from "components/Login/SignUp";
import SignIn from "components/Login/SignIn";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
Expand All @@ -24,6 +26,8 @@ root.render(
<BrowserRouter>
<Routes>
<Route path="/" element={<App />}>
<Route path="signin" element={<SignIn />}></Route>
<Route path="signup" element={<SignUp />}></Route>
<Route path="todos" element={<TodoList />}></Route>
<Route path="criterias" element={<CriteriaList />} />
<Route path="criterias/reorder" element={<Reorder />} />
Expand Down
Loading

0 comments on commit 4b9c401

Please sign in to comment.