A very performant and light (2mb in memory) link shortener and tracker. Written in Rust and React and uses Postgres/SQLite.
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 28 const login = async (email: string, password: string) => { 29 const response = await api.login(email, password); 30 const { token, user } = response; 31 localStorage.setItem('token', token); 32 localStorage.setItem('user', JSON.stringify(user)); 33 setUser(user); 34 }; 35 36 const register = async (email: string, password: string, adminToken: string) => { 37 const response = await api.register(email, password, adminToken); 38 const { token, user } = response; 39 localStorage.setItem('token', token); 40 localStorage.setItem('user', JSON.stringify(user)); 41 setUser(user); 42 }; 43 44 const logout = () => { 45 localStorage.removeItem('token'); 46 localStorage.removeItem('user'); 47 setUser(null); 48 }; 49 50 return ( 51 <AuthContext.Provider value={{ user, login, register, logout, isLoading }}> 52 {children} 53 </AuthContext.Provider> 54 ); 55} 56 57export function useAuth() { 58 const context = useContext(AuthContext); 59 if (context === undefined) { 60 throw new Error('useAuth must be used within an AuthProvider'); 61 } 62 return context; 63}