A very performant and light (2mb in memory) link shortener and tracker. Written in Rust and React and uses Postgres/SQLite.
at master 2.3 kB view raw
1import { createContext, useContext, useEffect, useState } from 'react'; 2import { User } from '../types/api'; 3import * as api from '../api/client'; 4 5interface AuthContextType { 6 user: User | null; 7 login: (email: string, password: string) => Promise<void>; 8 register: (email: string, password: string, adminToken: string) => Promise<void>; 9 logout: () => void; 10 isLoading: boolean; 11} 12 13const AuthContext = createContext<AuthContextType | undefined>(undefined); 14 15export function AuthProvider({ children }: { children: React.ReactNode }) { 16 const [user, setUser] = useState<User | null>(null); 17 const [isLoading, setIsLoading] = useState(true); 18 19 useEffect(() => { 20 const token = localStorage.getItem('token'); 21 if (token) { 22 const userData = JSON.parse(localStorage.getItem('user') || 'null'); 23 setUser(userData); 24 } 25 setIsLoading(false); 26 27 const handleUnauthorized = () => { 28 setUser(null); 29 }; 30 31 window.addEventListener('unauthorized', handleUnauthorized); 32 33 return () => { 34 window.removeEventListener('unauthorized', handleUnauthorized); 35 }; 36 }, []); 37 38 const login = async (email: string, password: string) => { 39 const response = await api.login(email, password); 40 const { token, user } = response; 41 localStorage.setItem('token', token); 42 localStorage.setItem('user', JSON.stringify(user)); 43 setUser(user); 44 }; 45 46 const register = async (email: string, password: string, adminToken: string) => { 47 const response = await api.register(email, password, adminToken); 48 const { token, user } = response; 49 localStorage.setItem('token', token); 50 localStorage.setItem('user', JSON.stringify(user)); 51 setUser(user); 52 }; 53 54 const logout = () => { 55 localStorage.removeItem('token'); 56 localStorage.removeItem('user'); 57 setUser(null); 58 }; 59 60 return ( 61 <AuthContext.Provider value={{ user, login, register, logout, isLoading }}> 62 {children} 63 </AuthContext.Provider> 64 ); 65} 66 67export function useAuth() { 68 const context = useContext(AuthContext); 69 if (context === undefined) { 70 throw new Error('useAuth must be used within an AuthProvider'); 71 } 72 return context; 73}