photum/frontend/contexts/AuthContext.tsx
NANDO9322 cf0cf4e95f feat(client): integra autenticacao real e melhora fluxo de login
- Integra AuthContext com API do Backend (/auth/login e /auth/register)
- Implementa Modo Hibrido: Demo Users usam Mock, outros usam API Real
- Habilita campo de senha e adiciona toggle de visibilidade (olho)
- Conecta formulario de Registro ao backend
- Adiciona preenchimento automatico de senha para usuarios de demonstracao
- Mapeia status 'ativo' do usuario vindo da API
2025-12-10 19:00:49 -03:00

131 lines
3.8 KiB
TypeScript

import React, { createContext, useContext, useState, ReactNode } from 'react';
import { User, UserRole } from '../types';
// Mock Users Database
const MOCK_USERS: User[] = [
{
id: 'superadmin-1',
name: 'Dev Admin',
email: 'admin@photum.com',
role: UserRole.SUPERADMIN,
avatar: 'https://i.pravatar.cc/150?u=admin'
},
{
id: 'owner-1',
name: 'PHOTUM CEO',
email: 'empresa@photum.com',
role: UserRole.BUSINESS_OWNER,
avatar: 'https://i.pravatar.cc/150?u=ceo'
},
{
id: 'photographer-1',
name: 'COLABORADOR PHOTUM',
email: 'foto@photum.com',
role: UserRole.PHOTOGRAPHER,
avatar: 'https://i.pravatar.cc/150?u=photo'
},
{
id: 'client-1',
name: 'PARCEIRO PHOTUM',
email: 'cliente@photum.com',
role: UserRole.EVENT_OWNER,
avatar: 'https://i.pravatar.cc/150?u=client'
}
];
interface AuthContextType {
user: User | null;
login: (email: string, password?: string) => Promise<boolean>;
logout: () => void;
register: (data: { nome: string; email: string; senha: string; telefone: string }) => Promise<boolean>;
availableUsers: User[]; // Helper for the login screen demo
}
const AuthContext = createContext<AuthContextType | undefined>(undefined);
export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const login = async (email: string, password?: string) => {
// 1. Check for Demo/Mock users first
const mockUser = MOCK_USERS.find(u => u.email === email);
if (mockUser) {
await new Promise(resolve => setTimeout(resolve, 800)); // Simulate delay
setUser({ ...mockUser, ativo: true });
return true;
}
// 2. Try Real API
try {
const response = await fetch(`${import.meta.env.VITE_API_URL}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, senha: password })
});
if (!response.ok) {
console.error('Login failed:', response.statusText);
return false;
}
const data = await response.json();
// Store token (optional, if you need it for other requests outside cookies)
// localStorage.setItem('token', data.access_token);
const backendUser = data.user;
// Map backend user to frontend User type
const mappedUser: User = {
id: backendUser.id,
email: backendUser.email,
name: backendUser.email.split('@')[0], // Fallback name or from profile if available
role: backendUser.role as UserRole,
ativo: backendUser.ativo,
// ... propagate other fields if needed or fetch profile
};
setUser(mappedUser);
return true;
} catch (err) {
console.error('Login error:', err);
return false;
}
};
const logout = () => {
setUser(null);
};
const register = async (data: { nome: string; email: string; senha: string; telefone: string }) => {
try {
const response = await fetch(`${import.meta.env.VITE_API_URL}/auth/register`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || 'Falha no cadastro');
}
return true;
} catch (err) {
console.error('Registration error:', err);
throw err;
}
};
return (
<AuthContext.Provider value={{ user, login, logout, register, availableUsers: MOCK_USERS }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) throw new Error('useAuth must be used within an AuthProvider');
return context;
};