Skip to content

Commit 885dc3d

Browse files
committed
feat: Create useAuth hook.
1 parent da9cf87 commit 885dc3d

6 files changed

Lines changed: 75 additions & 68 deletions

File tree

src/components/Layout/SettingsLayout/SettingsLayout.tsx

Lines changed: 12 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,23 @@
1-
import React, { useEffect, useState } from 'react'
1+
import React from 'react'
22
import 'react-contexify/dist/ReactContexify.css'
33
import { NavLink, Outlet } from 'react-router-dom'
4-
import toast from 'react-simple-toasts'
5-
import { auth } from 'src/features/auth'
6-
import { CurrentUser } from 'src/types'
4+
import { User } from 'src/features/auth/types'
5+
import { useAuth } from 'src/stores/user'
76
import './settings.css'
87

98
interface UserInfoProps {
10-
userInfo: CurrentUser
9+
user: User
1110
}
1211

13-
const UserInfo = ({ userInfo }: UserInfoProps) => {
14-
const logout = () => {
15-
auth
16-
.signOut()
17-
.then((result) => {
18-
toast('Account logged out successfuly', { theme: 'defaultToast' })
19-
})
20-
.catch((error) => {
21-
toast('Failed to logged out, please try later !!', { theme: 'failure' })
22-
})
23-
}
12+
const UserInfo = ({ user }: UserInfoProps) => {
13+
const { logout } = useAuth()
14+
2415
return (
2516
<div className="userCard">
26-
{userInfo?.imageURL && <img src={userInfo.imageURL} className="userImage"></img>}
17+
{user?.imageURL && <img src={user.imageURL} className="userImage"></img>}
2718
<div className="userInfos">
28-
<div className="userName">{userInfo?.name}</div>
29-
<div className="userEmail">{userInfo?.email}</div>
19+
<div className="userName">{user.name}</div>
20+
<div className="userEmail">{user?.email}</div>
3021
</div>
3122
<button className="logoutBtn" onClick={logout}>
3223
Logout
@@ -36,22 +27,7 @@ const UserInfo = ({ userInfo }: UserInfoProps) => {
3627
}
3728

3829
export const SettingsLayout = () => {
39-
const [user, setUser] = useState<CurrentUser | null>(null)
40-
useEffect(() => {
41-
const unsubscribe = auth.onAuthStateChanged((user) => {
42-
if (user) {
43-
const currentUser = {
44-
name: user?.displayName || '',
45-
email: user?.email || '',
46-
imageUrl: user?.photoURL || '',
47-
}
48-
setUser(currentUser)
49-
} else {
50-
setUser(null)
51-
}
52-
})
53-
return () => unsubscribe()
54-
})
30+
const { user } = useAuth()
5531
const navigation = [
5632
{
5733
name: 'Topics',
@@ -76,7 +52,7 @@ export const SettingsLayout = () => {
7652
]
7753
return (
7854
<div className="settings">
79-
{user != null && <UserInfo userInfo={user} />}
55+
{user != null && <UserInfo user={user} />}
8056
<div className="horizontalTabsLayout">
8157
<nav className="navigation">
8258
{navigation.map((item) => {

src/features/auth/components/AuthModal.tsx

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { GithubAuthProvider, GoogleAuthProvider, signInWithPopup } from 'firebase/auth'
1+
import { AuthProvider, OAuthProvider, signInWithPopup } from 'firebase/auth'
22
import { FaGithub, FaGoogle } from 'react-icons/fa'
33
import ReactModal from 'react-modal'
44
import toast from 'react-simple-toasts'
5+
import { useAuth } from 'src/stores/user'
56
import { auth, githubProvider, googleProvider } from '../api/Config'
67

78
type AuthModalProps = {
@@ -10,33 +11,30 @@ type AuthModalProps = {
1011
}
1112

1213
export const AuthModal = ({ showAuth, setShowAuth }: AuthModalProps) => {
13-
const signInWithGoogle = () => {
14-
signInWithPopup(auth, googleProvider)
15-
.then((result) => {
16-
const credential = GoogleAuthProvider.credentialFromResult(result)
17-
// TODO save this token in user settings maybe!
18-
const token = credential.accessToken
19-
// The signed-in user info.
20-
const user = result.user
21-
console.log(user)
22-
})
23-
.catch((error) => {
24-
toast("We couldn't login to you Google account!!", { theme: 'failure' })
25-
})
26-
}
14+
const { initState } = useAuth()
2715

28-
const signInWithGithub = () => {
29-
signInWithPopup(auth, githubProvider)
16+
const signIn = (provider: AuthProvider, providerName: string) => {
17+
signInWithPopup(auth, provider)
3018
.then((result) => {
31-
const credential = GithubAuthProvider.credentialFromResult(result)
32-
// TODO save this token in user settings maybe!
33-
const token = credential.accessToken
34-
// The signed-in user info.
35-
const user = result.user
36-
console.log(user)
19+
const credential = OAuthProvider.credentialFromResult(result)
20+
const accessToken = credential?.accessToken
21+
const email = result.user.displayName
22+
const name = result.user.displayName
23+
const imageURL = result.user.photoURL
24+
if (accessToken && name && email && imageURL) {
25+
initState({
26+
accessToken: accessToken,
27+
user: {
28+
name: name,
29+
email: email,
30+
imageURL: imageURL,
31+
},
32+
})
33+
}
3734
})
3835
.catch((error) => {
39-
toast("We couldn't login to you Github account!!", { theme: 'failure' })
36+
console.log(error)
37+
toast(`We couldn't login to your ${providerName} account!!`, { theme: 'failure' })
4038
})
4139
}
4240

@@ -66,14 +64,14 @@ export const AuthModal = ({ showAuth, setShowAuth }: AuthModalProps) => {
6664
</p>
6765
</div>
6866
<div>
69-
<button className="extraTextWithIconBtn" onClick={signInWithGithub}>
67+
<button className="extraTextWithIconBtn" onClick={() => signIn(githubProvider, 'Github')}>
7068
<FaGithub />
7169
Sign in with Github
7270
</button>
7371
<button
7472
className="extraTextWithIconBtn"
7573
style={{ marginLeft: 10 }}
76-
onClick={signInWithGoogle}>
74+
onClick={() => signIn(googleProvider, 'Google')}>
7775
<FaGoogle />
7876
Sign in with Google
7977
</button>

src/features/auth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './api/Config'
22
export * from './components/AuthModal'
3+
export * from './types'

src/features/auth/types/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export type User = {
2+
name: string
3+
email: string
4+
imageURL?: string
5+
}

src/stores/user.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { User } from 'src/features/auth/types'
2+
import { create } from 'zustand'
3+
import { persist } from 'zustand/middleware'
4+
5+
type AuthState = {
6+
accessToken: string | null
7+
user: User | null
8+
}
9+
10+
type AuthActions = {
11+
initState: (state: AuthState) => void
12+
isLogged: () => boolean
13+
logout: () => void
14+
}
15+
16+
export const useAuth = create(
17+
persist<AuthState & AuthActions>(
18+
(set, get) => ({
19+
accessToken: null,
20+
user: null,
21+
initState: (newState: AuthState) =>
22+
set({
23+
accessToken: newState.accessToken,
24+
user: newState.user,
25+
}),
26+
isLogged: () => !!get().user,
27+
logout: () => set({ user: null }),
28+
}),
29+
{
30+
name: 'auth-storage', // key in localStorage
31+
}
32+
)
33+
)

src/types/index.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,3 @@ export type DNDDuration =
123123
}
124124
| 'always'
125125
| 'never'
126-
127-
export type CurrentUser = {
128-
name: string
129-
email: string
130-
imageURL?: string
131-
}

0 commit comments

Comments
 (0)