feat: TrpcProvider and SelectedClientProvider
This commit is contained in:
69
src/components/providers/SelectedClientProvider.tsx
Normal file
69
src/components/providers/SelectedClientProvider.tsx
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import {
|
||||||
|
createContext,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
type ReactNode,
|
||||||
|
} from 'react'
|
||||||
|
|
||||||
|
const STORAGE_KEY = 'msp-selected-client-id'
|
||||||
|
|
||||||
|
type SelectedClientContextValue = {
|
||||||
|
selectedClientId: string | null
|
||||||
|
setSelectedClientId: (id: string | null) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const SelectedClientContext = createContext<SelectedClientContextValue | null>(null)
|
||||||
|
|
||||||
|
export function SelectedClientProvider({ children }: { children: ReactNode }) {
|
||||||
|
const [selectedClientId, setState] = useState<string | null>(null)
|
||||||
|
const [hydrated, setHydrated] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
const stored = typeof window !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null
|
||||||
|
const legacy = typeof window !== 'undefined' ? localStorage.getItem('msp-selected-cliente-id') : null
|
||||||
|
const value = stored || legacy || null
|
||||||
|
if (value) setState(value)
|
||||||
|
if (legacy && !stored && typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem(STORAGE_KEY, value!)
|
||||||
|
localStorage.removeItem('msp-selected-cliente-id')
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setHydrated(true)
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const setSelectedClientId = useCallback((id: string | null) => {
|
||||||
|
setState(id)
|
||||||
|
try {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
if (id) localStorage.setItem(STORAGE_KEY, id)
|
||||||
|
else localStorage.removeItem(STORAGE_KEY)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const value: SelectedClientContextValue = hydrated
|
||||||
|
? { selectedClientId, setSelectedClientId }
|
||||||
|
: { selectedClientId: null, setSelectedClientId }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SelectedClientContext.Provider value={value}>
|
||||||
|
{children}
|
||||||
|
</SelectedClientContext.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSelectedClient() {
|
||||||
|
const ctx = useContext(SelectedClientContext)
|
||||||
|
if (!ctx) {
|
||||||
|
throw new Error('useSelectedClient must be used within SelectedClientProvider')
|
||||||
|
}
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
46
src/components/providers/TrpcProvider.tsx
Normal file
46
src/components/providers/TrpcProvider.tsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useState } from 'react'
|
||||||
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||||
|
import { httpBatchLink } from '@trpc/client'
|
||||||
|
import superjson from 'superjson'
|
||||||
|
import { trpc } from '@/lib/trpc-client'
|
||||||
|
|
||||||
|
function getBaseUrl() {
|
||||||
|
if (typeof window !== 'undefined') return ''
|
||||||
|
if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`
|
||||||
|
return `http://localhost:${process.env.PORT ?? 3000}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TrpcProvider({ children }: { children: React.ReactNode }) {
|
||||||
|
const [queryClient] = useState(
|
||||||
|
() =>
|
||||||
|
new QueryClient({
|
||||||
|
defaultOptions: {
|
||||||
|
queries: {
|
||||||
|
staleTime: 5 * 1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const [trpcClient] = useState(() =>
|
||||||
|
trpc.createClient({
|
||||||
|
links: [
|
||||||
|
httpBatchLink({
|
||||||
|
url: `${getBaseUrl()}/api/trpc`,
|
||||||
|
fetch(url, options) {
|
||||||
|
return fetch(url, { ...options, credentials: 'include' })
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
transformer: superjson,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<trpc.Provider client={trpcClient} queryClient={queryClient}>
|
||||||
|
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
|
||||||
|
</trpc.Provider>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user