saveinmed/marketplace/src/context/AuthContext.tsx
Tiago Yamamoto 352ef86617 fix(marketplace): filter own products by company_id from JWT
- Add companyId field to AuthUser interface in AuthContext
- Extract company_id from JWT payload in Login.tsx
- Use user.companyId to filter products where seller_id matches
- This properly excludes own store products using UUID comparison
2025-12-23 16:31:46 -03:00

99 lines
2.6 KiB
TypeScript

import { createContext, ReactNode, useContext, useEffect, useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { apiClient } from '../services/apiClient'
import { authService } from '../services/auth'
export type UserRole = 'admin' | 'owner' | 'employee' | 'delivery' | 'seller' | 'customer'
export interface AuthUser {
id: string
name: string
username?: string
email?: string
companyId?: string
role: UserRole
token: string
}
interface AuthContextValue {
user: AuthUser | null
loading: boolean
login: (token: string, role: UserRole, name: string, id: string, companyId?: string, email?: string, username?: string) => void
logout: () => void
setUser: (user: AuthUser) => void
}
const AuthContext = createContext<AuthContextValue | undefined>(undefined)
const AUTH_KEY = 'mp-auth-user'
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<AuthUser | null>(() => {
const persisted = localStorage.getItem(AUTH_KEY)
return persisted ? (JSON.parse(persisted) as AuthUser) : null
})
const [loading, setLoading] = useState(true)
const navigate = useNavigate()
useEffect(() => {
setLoading(false)
}, [])
useEffect(() => {
if (user) {
localStorage.setItem(AUTH_KEY, JSON.stringify(user))
apiClient.setToken(user.token)
} else {
localStorage.removeItem(AUTH_KEY)
apiClient.setToken(null)
}
}, [user])
const login = (token: string, role: UserRole, name: string, id: string, companyId?: string, email?: string, username?: string) => {
setUser({ token, role, name, id, companyId, email, username })
// Redirect based on role
switch (role) {
case 'admin':
navigate('/dashboard', { replace: true })
break
case 'owner':
case 'seller':
navigate('/seller', { replace: true })
break
case 'employee':
navigate('/colaborador', { replace: true })
break
case 'delivery':
navigate('/entregas', { replace: true })
break
default:
navigate('/seller', { replace: true })
}
}
const logout = () => {
authService.logout().catch(() => undefined)
setUser(null)
navigate('/login', { replace: true })
}
const value = useMemo(
() => ({
user,
loading,
login,
logout,
setUser
}),
[user, loading]
)
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>
}
export const useAuth = () => {
const ctx = useContext(AuthContext)
if (!ctx) throw new Error('useAuth must be used within AuthProvider')
return ctx
}