use zustand
This commit is contained in:
parent
d2d358bff2
commit
5f29bc436c
15 changed files with 74 additions and 83 deletions
|
@ -1,6 +1,8 @@
|
|||
import { paths } from './schema.ts'
|
||||
import createClient, { Middleware } from 'openapi-fetch'
|
||||
import { dispatchMessage } from '../messageBus/messageBus.ts'
|
||||
import { useUserStore } from '../user/user.ts'
|
||||
import { getUserFromCookie } from '../auth/getUserFromCookie.ts'
|
||||
|
||||
export const initClient = () => {
|
||||
const client = createClient<paths>({ baseUrl: import.meta.env.VITE_API_URL })
|
||||
|
@ -9,6 +11,10 @@ export const initClient = () => {
|
|||
if (response.status === 401) {
|
||||
dispatchMessage('auth:unauthorized', null)
|
||||
}
|
||||
|
||||
const user = getUserFromCookie()
|
||||
console.debug('got user cookie', user)
|
||||
useUserStore.getState().setUser(user)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { useUser } from '../../user/user.ts'
|
||||
import NavButton from '../../../components/buttons/NavButton.tsx'
|
||||
import { useLocation } from 'react-router-dom'
|
||||
import { useTranslations } from '../../i18n/translations.ts'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
|
||||
export default function AuthNavButtons() {
|
||||
const { t } = useTranslations()
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
|
||||
const { pathname } = useLocation()
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { useUser } from '../../user/user.ts'
|
||||
import { useNavigate, Outlet } from 'react-router-dom'
|
||||
import { useEffect } from 'react'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
|
||||
export default function Protected() {
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
|
||||
const navigate = useNavigate()
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PropsWithChildren, useEffect, useRef } from 'react'
|
||||
import { AuthService } from '../authService.ts'
|
||||
import { useUser } from '../../user/user.ts'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
|
||||
interface RefreshUserProps {
|
||||
authService: AuthService
|
||||
|
@ -10,7 +10,7 @@ export default function RefreshUser({
|
|||
authService,
|
||||
children,
|
||||
}: PropsWithChildren<RefreshUserProps>) {
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
const didRefresh = useRef(false)
|
||||
|
||||
useEffect(() => {
|
||||
|
|
11
src/app/auth/getUserFromCookie.ts
Normal file
11
src/app/auth/getUserFromCookie.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { User } from '../user/user.ts'
|
||||
import { getCookie } from './cookies.ts'
|
||||
|
||||
export function getUserFromCookie(): User | null {
|
||||
const userCookie = getCookie('user')
|
||||
|
||||
if (!userCookie) return null
|
||||
|
||||
// TODO validate but it should be fine
|
||||
return JSON.parse(decodeURIComponent(userCookie)) as User
|
||||
}
|
|
@ -4,7 +4,7 @@ import TextInput from '../../../components/inputs/TextInput.tsx'
|
|||
import Button from '../../../components/buttons/Button.tsx'
|
||||
import { AuthService } from '../authService.ts'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { useUser } from '../../user/user.ts'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
import NavBar from '../../../components/NavBar.tsx'
|
||||
import NavButton from '../../../components/buttons/NavButton.tsx'
|
||||
import LinkButton from '../../../components/buttons/LinkButton.tsx'
|
||||
|
@ -26,7 +26,7 @@ export default function LoginPage({ authService }: LoginPageProps) {
|
|||
const passwordInputRef = useRef<HTMLInputElement | null>(null)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
|
||||
useEffect(() => {
|
||||
if (user) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { useNavigate } from 'react-router-dom'
|
||||
import { AuthService } from '../authService.ts'
|
||||
import { useEffect } from 'react'
|
||||
import { useUser } from '../../user/user.ts'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
|
||||
interface LogoutPageProps {
|
||||
authService: AuthService
|
||||
|
@ -9,7 +9,7 @@ interface LogoutPageProps {
|
|||
|
||||
export default function LogoutPage({ authService }: LogoutPageProps) {
|
||||
const navigate = useNavigate()
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { useRef, useState } from 'react'
|
||||
import { PostsService } from '../posts/postsService.ts'
|
||||
import { useUser } from '../../user/user.ts'
|
||||
import { useUserStore } from '../../user/user.ts'
|
||||
import { MediaService } from '../../media/mediaService.ts'
|
||||
import NewPostWidget from '../../../components/NewPostWidget.tsx'
|
||||
import SingleColumnLayout from '../../../layouts/SingleColumnLayout.tsx'
|
||||
|
@ -21,7 +21,7 @@ interface HomePageProps {
|
|||
const PageSize = 20
|
||||
|
||||
export default function HomePage({ postsService, mediaService }: HomePageProps) {
|
||||
const user = useUser()
|
||||
const user = useUserStore((state) => state.user)
|
||||
useSaveSignupCodeToLocalStorage()
|
||||
const [isSubmitting, setIsSubmitting] = useState(false)
|
||||
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import { addMessageListener, dispatchMessage } from '../messageBus/messageBus.ts'
|
||||
import { getCookie } from '../auth/cookies.ts'
|
||||
import { useMessageListener } from '../../hooks/useMessageListener.ts'
|
||||
import { useState } from 'react'
|
||||
import { setGlobal } from '../femtoApp.ts'
|
||||
import { create } from 'zustand'
|
||||
|
||||
export interface User {
|
||||
id: string
|
||||
|
@ -15,38 +11,12 @@ export enum Role {
|
|||
SuperUser = 1,
|
||||
}
|
||||
|
||||
let globalUser: User | null
|
||||
|
||||
export function initUser() {
|
||||
updateUser()
|
||||
|
||||
addMessageListener('auth:logged-in', updateUser)
|
||||
addMessageListener('auth:registered', updateUser)
|
||||
addMessageListener('auth:logged-out', updateUser)
|
||||
addMessageListener('auth:refreshed', updateUser)
|
||||
interface UserState {
|
||||
user: User | null
|
||||
setUser: (user: User | null) => void
|
||||
}
|
||||
|
||||
function updateUser() {
|
||||
globalUser = getUserFromCookie()
|
||||
setGlobal('user', globalUser)
|
||||
dispatchMessage('user:updated', globalUser)
|
||||
}
|
||||
|
||||
export function useUser(): User | null {
|
||||
const [user, setUser] = useState(globalUser)
|
||||
|
||||
useMessageListener('user:updated', (u) => {
|
||||
setUser(u)
|
||||
})
|
||||
|
||||
return user
|
||||
}
|
||||
|
||||
function getUserFromCookie(): User | null {
|
||||
const userCookie = getCookie('user')
|
||||
|
||||
if (!userCookie) return null
|
||||
|
||||
// TODO validate but it should be fine
|
||||
return JSON.parse(decodeURIComponent(userCookie)) as User
|
||||
}
|
||||
export const useUserStore = create<UserState>()((set) => ({
|
||||
user: null,
|
||||
setUser: (user: User | null) => set({ user }),
|
||||
}))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue