feat: TrpcProvider and SelectedClientProvider

This commit is contained in:
2026-02-12 15:25:52 -06:00
parent 32314228c4
commit 5d698490e2
2 changed files with 115 additions and 0 deletions

View 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
}

View 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>
)
}