kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
pull/715/head
rodzic
33fc9c331c
commit
2ed2873a93
|
@ -1,6 +1,6 @@
|
|||
'use client'
|
||||
|
||||
import { redirect, RedirectType } from 'next/navigation'
|
||||
// import { redirect, RedirectType } from 'next/navigation'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
import { useAuthenticatedAgentic } from '@/components/agentic-provider'
|
||||
|
@ -12,7 +12,6 @@ export default function LogoutPage() {
|
|||
;(async () => {
|
||||
if (ctx) {
|
||||
ctx.logout()
|
||||
redirect('/', RedirectType.replace)
|
||||
}
|
||||
})()
|
||||
}, [ctx])
|
||||
|
|
|
@ -11,7 +11,6 @@ import {
|
|||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState
|
||||
} from 'react'
|
||||
import { useLocalStorage } from 'react-use'
|
||||
|
@ -20,6 +19,7 @@ import * as config from '@/lib/config'
|
|||
|
||||
type AgenticContextType = {
|
||||
api: AgenticApiClient
|
||||
isAuthenticated: boolean
|
||||
logout: () => void
|
||||
}
|
||||
|
||||
|
@ -29,90 +29,117 @@ export function AgenticProvider({ children }: { children: ReactNode }) {
|
|||
const [authSession, setAuthSession] = useLocalStorage<AuthSession | null>(
|
||||
'agentic-auth-session'
|
||||
)
|
||||
|
||||
const logout = useCallback(() => {
|
||||
setAuthSession(null)
|
||||
}, [setAuthSession])
|
||||
|
||||
const agenticContext = useRef<AgenticContextType>({
|
||||
const onUpdateAuth = useCallback(
|
||||
(updatedAuthSession?: AuthSession | null) => {
|
||||
// console.log('onUpdateAuth', {
|
||||
// authSession: structuredClone(authSession),
|
||||
// updatedAuthSession: structuredClone(updatedAuthSession),
|
||||
// isCurrentlyAuthenticated: agenticContext.isAuthenticated
|
||||
// })
|
||||
|
||||
if (
|
||||
!!authSession !== !!updatedAuthSession ||
|
||||
authSession?.token !== updatedAuthSession?.token ||
|
||||
agenticContext.isAuthenticated !== !!updatedAuthSession
|
||||
) {
|
||||
setAuthSession(updatedAuthSession)
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[authSession, setAuthSession]
|
||||
)
|
||||
|
||||
const [agenticContext, setAgenticContext] = useState<AgenticContextType>({
|
||||
api: new AgenticApiClient({
|
||||
apiBaseUrl: config.apiBaseUrl,
|
||||
onUpdateAuth: (updatedAuthSession) => {
|
||||
// console.log('onUpdateAuth', updatedAuthSession)
|
||||
|
||||
if (
|
||||
!!authSession !== !!updatedAuthSession &&
|
||||
authSession?.token !== updatedAuthSession?.token
|
||||
) {
|
||||
// console.log('setAuthSession', updatedAuthSession)
|
||||
setAuthSession(updatedAuthSession)
|
||||
} else {
|
||||
// console.log('auth session not updated')
|
||||
}
|
||||
}
|
||||
onUpdateAuth
|
||||
}),
|
||||
isAuthenticated: !!authSession,
|
||||
logout
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// console.log('updating session from localStorage', authSession?.token)
|
||||
if (agenticContext.current) {
|
||||
if (authSession) {
|
||||
agenticContext.current.api.authSession = authSession
|
||||
} else {
|
||||
agenticContext.current.api.authSession = undefined
|
||||
if (authSession) {
|
||||
// console.log('setting auth session to truthy', {
|
||||
// authSession: structuredClone(authSession),
|
||||
// isAuthenticated: agenticContext.isAuthenticated,
|
||||
// setAgenticContext: !agenticContext.isAuthenticated
|
||||
// })
|
||||
|
||||
agenticContext.api.authSession = authSession
|
||||
if (!agenticContext.isAuthenticated) {
|
||||
setAgenticContext({
|
||||
...agenticContext,
|
||||
isAuthenticated: true
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// console.log('setting auth session to falsy', {
|
||||
// authSession: structuredClone(authSession),
|
||||
// isAuthenticated: agenticContext.isAuthenticated,
|
||||
// setAgenticContext: !!agenticContext.isAuthenticated
|
||||
// })
|
||||
|
||||
agenticContext.api.authSession = undefined
|
||||
|
||||
if (agenticContext.isAuthenticated) {
|
||||
setAgenticContext({
|
||||
...agenticContext,
|
||||
isAuthenticated: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}, [agenticContext, authSession])
|
||||
|
||||
return (
|
||||
<AgenticContext.Provider value={agenticContext.current}>
|
||||
<AgenticContext.Provider value={agenticContext}>
|
||||
{children}
|
||||
</AgenticContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useAgentic(): AgenticContextType {
|
||||
export function useAgentic(): AgenticContextType | undefined {
|
||||
const ctx = useContext(AgenticContext)
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMounted) {
|
||||
setIsMounted(true)
|
||||
return
|
||||
}
|
||||
}, [isMounted, setIsMounted])
|
||||
|
||||
if (!ctx) {
|
||||
throw new Error('useAgentic must be used within an AgenticProvider')
|
||||
}
|
||||
|
||||
return ctx
|
||||
return isMounted ? ctx : undefined
|
||||
}
|
||||
|
||||
export function useUnauthenticatedAgentic(): AgenticContextType | undefined {
|
||||
const ctx = useAgentic()
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMounted) {
|
||||
setIsMounted(true)
|
||||
return
|
||||
}
|
||||
if (ctx && ctx.isAuthenticated) {
|
||||
// console.log('REQUIRES UNAUTHENTICATED: redirecting to /app')
|
||||
redirect('/app', RedirectType.replace)
|
||||
}
|
||||
|
||||
if (ctx.api.isAuthenticated) {
|
||||
redirect('/app', RedirectType.replace)
|
||||
}
|
||||
}, [isMounted, setIsMounted, ctx])
|
||||
|
||||
return isMounted ? ctx : undefined
|
||||
return ctx
|
||||
}
|
||||
|
||||
export function useAuthenticatedAgentic(): AgenticContextType | undefined {
|
||||
const ctx = useAgentic()
|
||||
const [isMounted, setIsMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isMounted) {
|
||||
setIsMounted(true)
|
||||
return
|
||||
}
|
||||
if (ctx && !ctx.isAuthenticated) {
|
||||
// console.log('REQUIRES AUTHENTICATED: redirecting to /login')
|
||||
redirect('/login', RedirectType.replace)
|
||||
}
|
||||
|
||||
if (!ctx.api.isAuthenticated) {
|
||||
redirect('/login', RedirectType.replace)
|
||||
}
|
||||
}, [isMounted, setIsMounted, ctx])
|
||||
|
||||
return isMounted ? ctx : undefined
|
||||
return ctx
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@ import {
|
|||
TooltipProvider,
|
||||
TooltipTrigger
|
||||
} from '@/components/ui/tooltip'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export function DarkModeToggle() {
|
||||
export function DarkModeToggle({ className }: { className?: string }) {
|
||||
const { setTheme, resolvedTheme } = useTheme()
|
||||
|
||||
return (
|
||||
|
@ -22,7 +23,7 @@ export function DarkModeToggle() {
|
|||
<Button
|
||||
variant='outline'
|
||||
size='icon'
|
||||
className='cursor-pointer'
|
||||
className={cn('cursor-pointer', className)}
|
||||
onClick={() =>
|
||||
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
import cs from 'clsx'
|
||||
'use client'
|
||||
|
||||
import { ActiveLink } from '@/components/active-link'
|
||||
import { useAgentic } from '@/components/agentic-provider'
|
||||
import { DarkModeToggle } from '@/components/dark-mode-toggle'
|
||||
|
||||
import styles from './styles.module.css'
|
||||
|
||||
export function Header() {
|
||||
const ctx = useAgentic()
|
||||
|
||||
return (
|
||||
<header className={styles.header}>
|
||||
<div className={styles.headerContent}>
|
||||
|
@ -13,18 +16,32 @@ export function Header() {
|
|||
AGENTIC
|
||||
</ActiveLink>
|
||||
|
||||
<div className='md:hidden'>
|
||||
<div className='flex justify-end items-center h-full gap-4'>
|
||||
<ActiveLink href='/about' className='link'>
|
||||
About
|
||||
</ActiveLink>
|
||||
</div>
|
||||
|
||||
<div className={cs(styles.rhs)}>
|
||||
<div className='hidden md:block'>
|
||||
<ActiveLink href='/about' className='link mr-2'>
|
||||
About
|
||||
</ActiveLink>
|
||||
</div>
|
||||
{ctx?.api.isAuthenticated ? (
|
||||
<>
|
||||
<ActiveLink href='/app' className='link'>
|
||||
Dashboard
|
||||
</ActiveLink>
|
||||
|
||||
<ActiveLink href='/logout' className='link'>
|
||||
Logout
|
||||
</ActiveLink>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<ActiveLink href='/login' className='link'>
|
||||
Login
|
||||
</ActiveLink>
|
||||
|
||||
<ActiveLink href='/signup' className='link'>
|
||||
Sign up
|
||||
</ActiveLink>
|
||||
</>
|
||||
)}
|
||||
|
||||
<DarkModeToggle />
|
||||
</div>
|
||||
|
|
|
@ -38,15 +38,6 @@
|
|||
min-height: 32px;
|
||||
}
|
||||
|
||||
.rhs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
gap: 0.5em;
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: 'Josefin Sans';
|
||||
font-weight: bold;
|
||||
|
|
Ładowanie…
Reference in New Issue