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}