first commit

This commit is contained in:
Urtzi Alfaro
2025-07-17 13:54:51 +02:00
parent 347ff51bd7
commit 5bb3e93da4
41 changed files with 10084 additions and 94 deletions

View File

@@ -0,0 +1,109 @@
import React, { createContext, useState, useContext, useEffect } from 'react';
import api from '../api/api';
import { useRouter } from 'next/router';
import axios from 'axios';
interface User {
id: string;
email: string;
full_name: string;
tenant_id: string;
}
interface Tenant {
id: string;
name: string;
subdomain: string;
}
interface AuthContextType {
user: User | null;
tenant: Tenant | null;
login: (email: string, password: string) => Promise<void>;
logout: () => void;
loading: boolean;
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
return context;
};
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [tenant, setTenant] = useState<Tenant | null>(null);
const [loading, setLoading] = useState(true);
const router = useRouter();
useEffect(() => {
const token = localStorage.getItem('access_token');
if (token) {
loadUserData();
} else {
setLoading(false);
}
}, []);
const loadUserData = async () => {
try {
const response = await api.get('/auth/users/me');
setUser(response.data.user);
setTenant(response.data.tenant);
} catch (error) {
console.error('Failed to load user data:', error);
localStorage.removeItem('access_token');
localStorage.removeItem('tenant_id');
setUser(null);
setTenant(null);
} finally {
setLoading(false);
}
};
const login = async (email: string, password: string) => {
try {
// Create form data for OAuth2PasswordRequestForm
const formData = new URLSearchParams();
formData.append('username', email);
formData.append('password', password);
// Make login request with correct content type
const response = await axios.post(
`${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'}/api/v1/auth/token`,
formData,
{
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
}
);
localStorage.setItem('access_token', response.data.access_token);
localStorage.setItem('tenant_id', response.data.tenant_id);
await loadUserData();
} catch (error) {
console.error('Login failed:', error);
throw error;
}
};
const logout = () => {
localStorage.removeItem('access_token');
localStorage.removeItem('tenant_id');
setUser(null);
setTenant(null);
router.push('/login');
};
return (
<AuthContext.Provider value={{ user, tenant, login, logout, loading }}>
{children}
</AuthContext.Provider>
);
};