← back to Letsbegin

components/AuthProvider.tsx

101 lines

'use client'

import { createContext, useContext, useEffect, useState, ReactNode } from 'react'
import { useRouter, usePathname } from 'next/navigation'

interface AuthContextType {
  isAuthenticated: boolean
  isLoading: boolean
  username: string | null
  logout: () => Promise<void>
}

const AuthContext = createContext<AuthContextType>({
  isAuthenticated: false,
  isLoading: true,
  username: null,
  logout: async () => {}
})

export function useAuth() {
  return useContext(AuthContext)
}

export function AuthProvider({ children }: { children: ReactNode }) {
  const [isAuthenticated, setIsAuthenticated] = useState(false)
  const [isLoading, setIsLoading] = useState(true)
  const [username, setUsername] = useState<string | null>(null)
  const router = useRouter()
  const pathname = usePathname()

  useEffect(() => {
    checkAuth()
  }, [])

  async function checkAuth() {
    try {
      const res = await fetch('/api/auth/session')
      const data = await res.json()

      if (data.authenticated) {
        setIsAuthenticated(true)
        setUsername(data.username || 'admin')
      } else {
        setIsAuthenticated(false)
        setUsername(null)
        // Redirect to login if not on login page
        if (pathname !== '/login') {
          router.push('/login')
        }
      }
    } catch (err) {
      console.error('Auth check failed:', err)
      setIsAuthenticated(false)
      if (pathname !== '/login') {
        router.push('/login')
      }
    } finally {
      setIsLoading(false)
    }
  }

  async function logout() {
    try {
      await fetch('/api/auth/logout', { method: 'POST' })
      setIsAuthenticated(false)
      setUsername(null)
      router.push('/login')
    } catch (err) {
      console.error('Logout error:', err)
    }
  }

  // Show loading state
  if (isLoading) {
    return (
      <div className="min-h-screen bg-[var(--background)] flex items-center justify-center">
        <div className="text-center">
          <div className="text-4xl mb-4 animate-pulse">🚀</div>
          <div className="text-[var(--foreground-secondary)]">Loading...</div>
        </div>
      </div>
    )
  }

  // Allow login page to render without auth
  if (pathname === '/login') {
    return <>{children}</>
  }

  // Require auth for all other pages
  if (!isAuthenticated) {
    return null // Will redirect in useEffect
  }

  return (
    <AuthContext.Provider value={{ isAuthenticated, isLoading, username, logout }}>
      {children}
    </AuthContext.Provider>
  )
}