Skip to content

Commit 3629657

Browse files
committed
feat: Implement hit tracking and update user streak in AuthStore
1 parent db58341 commit 3629657

9 files changed

Lines changed: 73 additions & 8 deletions

File tree

src/components/Layout/AppLayout.tsx

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
1-
import React from 'react'
1+
import React, { useEffect } from 'react'
22
import 'react-contexify/dist/ReactContexify.css'
33
import { Outlet } from 'react-router-dom'
44
import { BeatLoader } from 'react-spinners'
55
import 'src/assets/App.css'
6-
import { AuthModal, useAuth } from 'src/features/auth'
6+
import { AuthModal, AuthStore, useAuth } from 'src/features/auth'
7+
import { usePostHit } from 'src/features/hits'
78
import { MarketingBanner } from 'src/features/MarketingBanner'
89
import { Header } from './Header'
910

1011
export const AppLayout = () => {
11-
const { isAuthModalOpen, closeAuthModal } = useAuth()
12+
const { isAuthModalOpen } = useAuth()
13+
const { setStreak } = AuthStore()
14+
const postHitMutation = usePostHit()
15+
16+
useEffect(() => {
17+
postHitMutation.mutateAsync({ data: { type: 'visit' } }).then((data) => {
18+
setStreak(data.streak)
19+
})
20+
}, [])
1221

1322
return (
1423
<>

src/features/auth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export * from './hooks/useAuth'
33
export * from './stores/authModalStore'
44
export * from './stores/authStore'
55
export * from './types'
6+
export * from './utils/auth'

src/features/auth/stores/authStore.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ type AuthState = {
99

1010
type AuthActions = {
1111
initState: (state: AuthState) => void
12+
setStreak: (streak: number) => void
1213
clear: () => void
1314
}
1415

@@ -17,11 +18,19 @@ export const AuthStore = create(
1718
(set) => ({
1819
idToken: null,
1920
user: null,
21+
2022
initState: (newState: AuthState) =>
2123
set({
2224
idToken: newState.idToken,
2325
user: newState.user,
2426
}),
27+
setStreak: (streak: number) =>
28+
set((state) => ({
29+
user: {
30+
...state.user!,
31+
streak,
32+
},
33+
})),
2534
clear: () => set({ user: null }),
2635
}),
2736
{

src/features/auth/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export type User = {
22
name: string
33
email: string
44
imageURL?: string
5+
streak?: number
56
}

src/features/auth/utils/auth.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { firebaseAuth } from 'src/lib/firebase'
2+
3+
export const getUserToken = async () => {
4+
return new Promise((resolve, _) => {
5+
const unsub = firebaseAuth.onAuthStateChanged(async (user) => {
6+
if (user) {
7+
const token = await user.getIdToken()
8+
resolve(token)
9+
} else {
10+
console.log('User not logged in')
11+
resolve(null)
12+
}
13+
unsub()
14+
})
15+
})
16+
}

src/features/hits/api/postHit.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useMutation } from '@tanstack/react-query'
2+
import { axios } from 'src/lib/axios'
3+
import { MutationConfig } from 'src/lib/react-query'
4+
import { Hit } from '../types'
5+
6+
type DTOProps = {
7+
data: {
8+
type: 'visit'
9+
}
10+
}
11+
const postHit = async ({ data }: DTOProps): Promise<Hit> => {
12+
return axios.post('/engine/hit', data)
13+
}
14+
15+
type QueryFnType = typeof postHit
16+
17+
type UsePostHitOptions = {
18+
config?: MutationConfig<QueryFnType>
19+
}
20+
export const usePostHit = ({ config }: UsePostHitOptions = {}) => {
21+
return useMutation({
22+
...config,
23+
mutationFn: postHit,
24+
})
25+
}

src/features/hits/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './api/postHit'
2+
export * from './types'

src/features/hits/types/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type Hit = {
2+
streak: number
3+
}

src/lib/interceptors/DefaultRequestInterceptor.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { AxiosRequestConfig } from 'axios'
22
import { API_ENDPOINT } from 'src/config'
3+
import { getUserToken } from 'src/features/auth'
34
import { isProduction } from 'src/utils/Environment'
4-
import { firebaseAuth } from '../firebase'
55

66
export async function DefaultRequestInterceptor(config: AxiosRequestConfig) {
77
if (config) {
@@ -10,10 +10,9 @@ export async function DefaultRequestInterceptor(config: AxiosRequestConfig) {
1010
config.headers.Accept = 'application/json'
1111
}
1212

13-
const user = firebaseAuth.currentUser
14-
if (user) {
15-
const token = await user.getIdToken()
16-
config.headers.Authorization = `Bearer ${token}`
13+
const token = await getUserToken()
14+
if (token) {
15+
config.headers.authorization = `Bearer ${token}`
1716
}
1817
}
1918

0 commit comments

Comments
 (0)