go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/nodes/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 { NonIdealState, Spinner, SpinnerSize } from '@blueprintjs/core';
     6  import React, { useContext, useState, useEffect } from 'react';
     7  import * as sessionApi from '../api/session';
     8  
     9  type SessionProviderProps = {
    10    children: React.ReactNode
    11    baseURL?: string
    12  };
    13  
    14  export const SessionContext = React.createContext?.<
    15    sessionApi.Session | undefined
    16  >(undefined)
    17  
    18  export function useSession(): sessionApi.Session {
    19    if (!SessionContext) {
    20      throw new Error("React Context is unavailable in Server Components")
    21    }
    22    // @ts-expect-error Satisfy TS if branch on line below
    23    const value: Session = useContext(SessionContext)
    24    if (!value) {
    25      throw new Error(
    26        "`useSession` must be wrapped in a <SessionProvider />"
    27      )
    28    }
    29    return value
    30  }
    31  
    32  export function SessionProvider(props: SessionProviderProps) {
    33    if (!SessionContext) {
    34      throw new Error("React Context is unavailable in Server Components")
    35    }
    36    const [session, setSession] = useState<sessionApi.Session | undefined>();
    37  
    38    useEffect(() => {
    39      sessionApi.getSession().then(s => setSession(s));
    40    }, [])
    41    if (session === undefined) {
    42      return <Spinner size={SpinnerSize.LARGE} style={{ position: 'absolute', left: '50%', top: '50%' }} />
    43    }
    44    if (!session.authorized) {
    45      return (
    46        <NonIdealState description={"You are not authorized to view this page."}>
    47        </NonIdealState>
    48      )
    49    }
    50    return (
    51      <SessionContext.Provider value={session}>{props.children}</SessionContext.Provider>
    52    )
    53  }