feat: add Supabase authentication context and routes
- Implemented Supabase authentication context in `supabase.tsx` for managing user login and logout. - Created a new SVG logo file for branding. - Set up main application entry point in `main.tsx` with router integration. - Added web vitals reporting in `reportWebVitals.ts`. - Generated route tree in `routeTree.gen.ts` for application routing. - Established root route in `__root.tsx` with TanStack Router Devtools integration. - Created authenticated route in `_authenticated.tsx` to protect routes. - Developed planes route under authenticated section in `planes.tsx`. - Implemented login route with form handling in `login.tsx`. - Added index route with welcome message in `index.tsx`. - Included basic styles in `styles.css`. - Configured TypeScript settings in `tsconfig.json`. - Set up Vite configuration with React and TanStack Router plugins in `vite.config.ts`.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import { createClient, type User } from '@supabase/supabase-js'
|
||||
import { createContext, useContext, useEffect, useState } from 'react'
|
||||
|
||||
const supabase = createClient(
|
||||
import.meta.env.VITE_SUPABASE_URL,
|
||||
import.meta.env.VITE_SUPABASE_ANON_KEY,
|
||||
)
|
||||
|
||||
export interface SupabaseAuthState {
|
||||
isAuthenticated: boolean
|
||||
user: any
|
||||
login: (email: string, password: string) => Promise<void>
|
||||
logout: () => Promise<void>
|
||||
isLoading: boolean
|
||||
}
|
||||
|
||||
const SupabaseAuthContext = createContext<SupabaseAuthState | undefined>(
|
||||
undefined,
|
||||
)
|
||||
|
||||
export function SupabaseAuthProvider({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
}) {
|
||||
const [user, setUser] = useState<User | null>(null)
|
||||
const [isAuthenticated, setIsAuthenticated] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
// Get initial session
|
||||
supabase.auth.getSession().then(({ data: { session } }) => {
|
||||
setUser(session?.user ?? null)
|
||||
setIsAuthenticated(!!session?.user)
|
||||
setIsLoading(false)
|
||||
})
|
||||
|
||||
// Listen for auth changes
|
||||
const {
|
||||
data: { subscription },
|
||||
} = supabase.auth.onAuthStateChange((_event, session) => {
|
||||
setUser(session?.user ?? null)
|
||||
setIsAuthenticated(!!session?.user)
|
||||
setIsLoading(false)
|
||||
})
|
||||
|
||||
return () => subscription.unsubscribe()
|
||||
}, [])
|
||||
|
||||
const login = async (email: string, password: string) => {
|
||||
const { error } = await supabase.auth.signInWithPassword({
|
||||
email,
|
||||
password,
|
||||
})
|
||||
if (error) throw error
|
||||
}
|
||||
|
||||
const logout = async () => {
|
||||
const { error } = await supabase.auth.signOut()
|
||||
if (error) throw error
|
||||
location.reload()
|
||||
}
|
||||
|
||||
return (
|
||||
<SupabaseAuthContext.Provider
|
||||
value={{
|
||||
isAuthenticated,
|
||||
user,
|
||||
login,
|
||||
logout,
|
||||
isLoading,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</SupabaseAuthContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export function useSupabaseAuth() {
|
||||
const context = useContext(SupabaseAuthContext)
|
||||
if (context === undefined) {
|
||||
throw new Error('useSupabaseAuth must be used within SupabaseAuthProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
Reference in New Issue
Block a user