Skip to content

Commit

Permalink
Implemented the useAuth custom hook
Browse files Browse the repository at this point in the history
  • Loading branch information
hernan-clich committed Nov 22, 2021
1 parent 40f3286 commit 0ed80cc
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 33 deletions.
20 changes: 20 additions & 0 deletions app/config/firebase/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { getApps, initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';

const firebaseClientConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID
};

function initFirebase() {
const apps = getApps();
if (!apps.length) initializeApp(firebaseClientConfig);
}

initFirebase();

export const auth = getAuth();
83 changes: 83 additions & 0 deletions app/hooks/useAuth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import cookies from 'js-cookie';
import { GoogleAuthProvider, onIdTokenChanged, signInWithPopup, signOut } from 'firebase/auth';
import type { User } from 'firebase/auth';
import { useRouter } from 'next/router';
import { createContext, useContext, useEffect, useState } from 'react';
import { auth } from '~config/firebase/client';
import PATHS from '~constants/paths';
import { ReactNode } from 'hoist-non-react-statics/node_modules/@types/react';

interface IAuthContext {
authenticated: boolean;
logout: () => void;
signInWithGoogle: () => void;
user: User | null;
}

const AuthContext = createContext<IAuthContext>({
authenticated: false,
logout: () => null,
signInWithGoogle: () => null,
user: null
});

export const AuthProvider = ({ children }: { children: ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
const router = useRouter();

const setTokenCookie = (token: string) => {
cookies.set('token', token, {
expires: 1 / 24
});
};

const removeTokenCookie = () => cookies.remove('token');

const signInWithGoogle = () => {
const provider = new GoogleAuthProvider();
signInWithPopup(auth, provider)
.then(() => {
router.push(PATHS.HOME);
})
.catch((e) => {
throw new Error(`Error signing in: ${e}`);
});
};

const logout = () => {
signOut(auth)
.then(() => {
router.push(PATHS.HOME);
})
.catch((e) => {
throw new Error(`Error signing out: ${e}`);
});
};

useEffect(() => {
const cancelAuthListener = onIdTokenChanged(auth, async (user) => {
if (user) {
const token = await user.getIdToken();
setTokenCookie(token);
setUser(user);
} else {
removeTokenCookie();
setUser(null);
}
});

return () => {
cancelAuthListener();
};
}, []);

return (
<AuthContext.Provider value={{ user, authenticated: !!user, logout, signInWithGoogle }}>
{children}
</AuthContext.Provider>
);
};

export function useAuth() {
return useContext(AuthContext);
}
30 changes: 12 additions & 18 deletions app/screens/Auth/components/AuthContent/index.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
import { useState } from 'react';
import CustomButton from '~components/CustomButton';
import CustomText from '~components/CustomText';
import GoogIcon from '~components/GoogIcon';
import { useAuth } from '~hooks/useAuth';
import * as Styled from './styles';

function AuthContent() {
const [isLoggedIn, setIsLoggedIn] = useState(true);
const { logout, signInWithGoogle } = useAuth();

return (
<Styled.AuthContentContainer>
<CustomText size="big" weight="regular" className="title">
{isLoggedIn ? 'Iniciar sesión con Google' : 'Crear cuenta con Google'}
Iniciar sesión con Google
</CustomText>
<CustomButton size="regular" weight="regular">
<CustomButton size="regular" weight="regular" onClick={signInWithGoogle}>
<div className="btnContents">
<GoogIcon secondary />
{isLoggedIn ? 'Iniciar sesión' : 'Crear cuenta'}
Iniciar sesión
</div>
</CustomButton>
{/* @todo: put this in a better place, maybe the header?? */}
<CustomButton size="regular" weight="regular" onClick={logout}>
<div className="btnContents">
<GoogIcon secondary />
Logout
</div>
</CustomButton>
<div className="togglerContainer">
<CustomText as="span" size="xsmall" weight="regular">
{isLoggedIn ? 'Todavía no tenes una cuenta?' : 'Ya tenes una cuenta?'}
</CustomText>
<CustomText
as="span"
size="xsmall"
weight="black"
onClick={() => setIsLoggedIn((prevState) => !prevState)}
>
{isLoggedIn ? 'Registrate!' : 'Inicia sesión'}
</CustomText>
</div>
</Styled.AuthContentContainer>
);
}
Expand Down
12 changes: 0 additions & 12 deletions app/screens/Auth/components/AuthContent/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,4 @@ export const AuthContentContainer = styled.div`
margin-right: ${SECONDARY_SPACING_EM};
}
}
.togglerContainer {
span {
user-select: none;
}
span:nth-child(2) {
cursor: pointer;
margin-left: 4px;
user-select: none;
}
}
`;
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
"dependencies": {
"clsx": "^1.1.1",
"firebase": "^9.5.0",
"js-cookie": "^3.0.1",
"next": "11.0.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"styled-components": "^5.3.0",
"uuid": "^8.3.2"
},
"devDependencies": {
"@types/js-cookie": "^3.0.1",
"@types/node": "^15.12.5",
"@types/react": "17.0.13",
"@types/styled-components": "^5.1.10",
Expand Down
9 changes: 6 additions & 3 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import type { AppProps } from 'next/app';
import { AuthProvider } from '~hooks/useAuth';
import GlobalStyles from '~styles/GlobalStyles';

function MyApp({ Component, pageProps }: AppProps) {
return (
<GlobalStyles>
<Component {...pageProps} />
</GlobalStyles>
<AuthProvider>
<GlobalStyles>
<Component {...pageProps} />
</GlobalStyles>
</AuthProvider>
);
}
export default MyApp;
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"baseUrl": ".",
"paths": {
"~components/*": ["app/components/*"],
"~config/*": ["app/config/*"],
"~constants/*": ["app/constants/*"],
"~hooks/*": ["app/hooks/*"],
"~pages/*": ["pages/*"],
Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,11 @@
"@types/react" "*"
hoist-non-react-statics "^3.3.0"

"@types/js-cookie@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-3.0.1.tgz#04aa743e2e0a85a22ee9aa61f6591a8bc19b5d68"
integrity sha512-7wg/8gfHltklehP+oyJnZrz9XBuX5ZPP4zB6UsI84utdlkRYLnOm2HfpLXazTwZA+fpGn0ir8tGNgVnMEleBGQ==

"@types/json-schema@^7.0.7":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
Expand Down Expand Up @@ -2510,6 +2515,11 @@ jest-worker@27.0.0-next.5:
merge-stream "^2.0.0"
supports-color "^8.0.0"

js-cookie@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.1.tgz#9e39b4c6c2f56563708d7d31f6f5f21873a92414"
integrity sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==

"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
Expand Down

0 comments on commit 0ed80cc

Please sign in to comment.