go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/chirp/pkg/static/_nextjs/src/components/sessionProvider.tsx (about) 1 /** 2 * Copyright (c) 2024 - Present. Will Charczuk. All rights reserved. 3 * Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository. 4 */ 5 import { Spinner } from '@blueprintjs/core'; 6 import { Session } from '../app/api'; 7 import React, { useContext, useState, useEffect } from 'react'; 8 import useSWR from 'swr' 9 10 type SessionProviderProps = { 11 children: React.ReactNode 12 baseURL?: string 13 }; 14 15 export const SessionContext = React.createContext?.< 16 Session | undefined 17 >(undefined) 18 19 export function useSession(): Session { 20 if (!SessionContext) { 21 throw new Error("React Context is unavailable in Server Components") 22 } 23 // @ts-expect-error Satisfy TS if branch on line below 24 const value: Session = useContext(SessionContext) 25 if (!value) { 26 throw new Error( 27 "`useSession` must be wrapped in a <SessionProvider />" 28 ) 29 } 30 return value 31 } 32 33 const fetcher = async (url: string): Promise<Session> => { 34 const r = await fetch(url) 35 const data = await r.json() 36 return data as Session 37 } 38 39 export function SessionProvider(props: SessionProviderProps) { 40 if (!SessionContext) { 41 throw new Error("React Context is unavailable in Server Components") 42 } 43 const { data, isLoading } = useSWR('/api/v1/session', fetcher) 44 if (!isLoading) { 45 return ( 46 <Spinner /> 47 ) 48 } 49 return ( 50 <SessionContext.Provider value={data}>{props.children}</SessionContext.Provider> 51 ) 52 }