Skip to content

Commit

Permalink
Add SignUp Screen, other login options, Verification Email Screen and…
Browse files Browse the repository at this point in the history
… Forgot Password Screen (#25)

* feat: create the signUp screen

* fix: Add signUp screen route to AppRouter

* fix: Add signUp screen link to signInForm

* feat: Add login buttons for google, apple, microsoft and github

* fix: Button elements replaced by the login buttons component

* fix: Remove unused components

* feat: Add verification email screen

* fix: Page redirects and rendering Breadcrumb

* feat: Add forgot password screen

* fix: fix routes and links to forgot password screen

* fix: Fix font colors of the signin and signup screens to white

* fix: optimize and washing code

* fix: optimize and washing code
  • Loading branch information
devsilasfreitas authored Mar 11, 2024
1 parent 13e4c59 commit f0137e7
Show file tree
Hide file tree
Showing 16 changed files with 525 additions and 47 deletions.
47 changes: 47 additions & 0 deletions frontend/src/assets/appleLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions frontend/src/assets/gitHubLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions frontend/src/assets/microsoftLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions frontend/src/components/SignInButtons/SignInButtons.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react";

const button: React.CSSProperties = {
boxSizing: 'border-box',
height: '40px',
display: 'flex',
alignItems: 'center',
width: '10em',
justifyContent: 'center',
margin: '5px'
}

const buttonMobile: React.CSSProperties = {
boxSizing: 'border-box',
height: '40px',
display: 'flex',
alignItems: 'center',
margin: '5px auto'
}

const container: React.CSSProperties = {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around'
}

export const SignInButtonsStyles = {
button,
buttonMobile,
container
}
103 changes: 103 additions & 0 deletions frontend/src/components/SignInButtons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Button } from "antd";
import { SignInButtonsStyles } from "./SignInButtons.styles";
import googleLogo from "../../assets/googleLogo.svg";
import appleLogo from "../../assets/appleLogo.svg";
import microsoftLogo from "../../assets/microsoftLogo.svg";
import gitHubLogo from "../../assets/gitHubLogo.svg";
import { useNavigate } from "react-router-dom";
import { signInWithPopup, GoogleAuthProvider, OAuthProvider, GithubAuthProvider, User } from "firebase/auth";
import { auth } from "../../config/firebase";



const SignInGoogle = async () => {
const provider = new GoogleAuthProvider();
return signInWithPopup(auth, provider);
}

const SignInApple = () => {
const provider = new OAuthProvider('apple.com');
provider.addScope('email');
provider.addScope('name');
provider.setCustomParameters({
// Localize the Apple authentication screen in French.
locale: 'br'
});
return signInWithPopup(auth, provider);
}

const SignInMicrosoft = () => {
const provider = new OAuthProvider('microsoft.com');
provider.addScope('mail.read');
provider.addScope('name.read');
return signInWithPopup(auth, provider);
}

const SignInGitHub = () => {
const provider = new GithubAuthProvider();
provider.addScope('name');
return signInWithPopup(auth, provider);
}

export const SignInButtons = ({isBroken}: {isBroken: boolean}) => {
const navigate = useNavigate();
const handleSignIn = async (provider: String) => {
switch (provider) {
case 'Google': await SignInGoogle().then((crendentialUser) => redirect(crendentialUser.user));
break;
case 'Apple': await SignInApple().then((crendentialUser) => redirect(crendentialUser.user));
break;
case 'Microsoft': await SignInMicrosoft().then((crendentialUser) => redirect(crendentialUser.user));
break;
case 'GitHub': await SignInGitHub().then((crendentialUser) => redirect(crendentialUser.user));
break;
}
}

const redirect = (user: User) => {
if (user?.emailVerified) {
navigate("/");
} else {
navigate("/verification-email");
}
};

const styles = isBroken ? SignInButtonsStyles.buttonMobile : SignInButtonsStyles.button;

return (
<div
style={isBroken ? {
...SignInButtonsStyles.container, flexDirection: 'column'
} : SignInButtonsStyles.container}
>
<Button
style={styles}
onClick={() => handleSignIn('Google')}
icon={<img src={googleLogo} alt="Logo da Google." width="15px" />}
>
Google
</Button>
<Button
style={styles}
onClick={() => handleSignIn('Apple')}
icon={<img src={appleLogo} alt="Logo da Apple." width="15px" />}
>
Apple
</Button>
<Button
style={styles}
onClick={() => handleSignIn('Microsoft')}
icon={<img src={microsoftLogo} alt="Logo da Microsoft." width="15px" />}
>
Microsoft
</Button>
<Button
style={styles}
onClick={() => handleSignIn('GitHub')}
icon={<img src={gitHubLogo} alt="Logo da GitHub." width="15px" />}
>
GitHub
</Button>
</div>
)
}
29 changes: 21 additions & 8 deletions frontend/src/components/SignInForm/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { LockOutlined, UserOutlined } from "@ant-design/icons";
import { LockOutlined, MailOutlined } from "@ant-design/icons";
import { Button, Form, Input } from "antd";
import { auth } from "../../config/firebase";
import { signInWithEmailAndPassword } from "firebase/auth";
import { useNavigate } from "react-router-dom";
import { User, signInWithEmailAndPassword } from "firebase/auth";
import { Link, useNavigate } from "react-router-dom";

type SignInFormType = {
email: string;
Expand All @@ -12,10 +12,18 @@ type SignInFormType = {
export const SignInForm = () => {
const navigate = useNavigate();

const redirect = (user: User) => {
if (user?.emailVerified) {
navigate("/");
} else {
navigate("/auth/verification-email");
}
}

const onFinish = async (values: SignInFormType) => {
try {
await signInWithEmailAndPassword(auth, values.email, values.password);
navigate("/");
const credentialUser = await signInWithEmailAndPassword(auth, values.email, values.password);
redirect(credentialUser.user);
} catch (e) {
console.error(e);
}
Expand All @@ -28,7 +36,7 @@ export const SignInForm = () => {
rules={[{ required: true, message: "Insira seu email" }]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
prefix={<MailOutlined className="site-form-item-icon" />}
placeholder="Email"
/>
</Form.Item>
Expand All @@ -45,9 +53,14 @@ export const SignInForm = () => {
</Form.Item>

<Form.Item>
<a href="#forgot_password" style={{ float: "right", marginBottom: 10 }}>
<div style={{display: "flex", justifyContent: "space-between", marginBottom: 10 }}>
<Link to="/auth/sign-up">
Não tem uma conta?
</Link>
<Link to="/auth/forgot-password" style={{textAlign: "right"}}>
Esqueceu a senha?
</a>
</Link>
</div>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}>
Entrar
</Button>
Expand Down
79 changes: 79 additions & 0 deletions frontend/src/components/SignUpForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { LockOutlined, UserOutlined, MailOutlined } from "@ant-design/icons";
import { Button, Form, Input } from "antd";
import { auth } from "../../config/firebase";
import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth";
import { Link, useNavigate } from "react-router-dom";

type SignUpFormType = {
name: string;
email: string;
password: string;
confirmPassword: string;
};

export const SignUpForm = () => {
const navigate = useNavigate();

const onFinish = async (values: SignUpFormType) => {
try {
if (values.password != values.confirmPassword) throw new Error('As senhas não conferem');
const userCredential = await createUserWithEmailAndPassword(auth, values.email, values.password);
await updateProfile(userCredential.user, {displayName: values.name});
navigate("/auth/verification-email");
} catch (e) {
console.error(e);
}
};

return (
<Form initialValues={{ remember: true }} onFinish={onFinish}>
<Form.Item<SignUpFormType>
name="name"
rules={[{required: true, message: "Insira seu nome"}]}
>
<Input
prefix={<UserOutlined className="site-form-item-icon" />}
placeholder="Nome"
/>
</Form.Item>
<Form.Item<SignUpFormType>
name="email"
rules={[{ required: true, message: "Insira seu email" }]}
>
<Input
prefix={<MailOutlined className="site-form-item-icon" />}
placeholder="Email"
/>
</Form.Item>

<Form.Item<SignUpFormType>
name="password"
rules={[{ required: true, message: "Insira sua senha" }]}
>
<Input.Password
prefix={<LockOutlined />}
type="password"
placeholder="Senha"
/>
</Form.Item>

<Form.Item<SignUpFormType>
name="confirmPassword"
rules={[{ required: true, message: "Confirme sua senha" }]}
>
<Input.Password
prefix={<LockOutlined />}
type="password"
placeholder="Confirme sua Senha"
/>
</Form.Item>

<Form.Item>
<Link to="/auth/sign-in" style={{ float: "right", marginBottom: 10 }}>Já tem uma conta?</Link>
<Button type="primary" htmlType="submit" style={{ width: "100%" }}>
Cadastrar
</Button>
</Form.Item>
</Form>
);
};
5 changes: 2 additions & 3 deletions frontend/src/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,8 @@ export const AppLayout: React.FC = () => {
const onClickMenuOption = (e: any) => {
if (e.key === "logout") {
auth.signOut();
} else if (e.key === "login") {
navigate("/auth/sign-in");
}
navigate("/auth/sign-in");
};

// TODO: completar login e logout
Expand All @@ -90,7 +89,7 @@ export const AppLayout: React.FC = () => {
</Header>

<Content style={{ padding: "24px 48px" }}>
{user && (
{user?.emailVerified && (
<Breadcrumb style={{ margin: "16px 0" }} items={Breadcrumbitems} />
)}

Expand Down
Loading

0 comments on commit f0137e7

Please sign in to comment.