diff --git a/components/Layout.tsx b/components/Layout.tsx index c2d3949..83b6189 100644 --- a/components/Layout.tsx +++ b/components/Layout.tsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import { NavLink, useLocation, useNavigate } from 'react-router-dom'; import { LayoutDashboard, Users, UserCircle, Bell, Search, Menu, X, LogOut, Hexagon, Settings, Building2 } from 'lucide-react'; -import { USERS } from '../constants'; +import { getAttendances, getUsers, getUserById } from '../services/dataService'; import { User } from '../types'; const SidebarItem = ({ to, icon: Icon, label, collapsed }: { to: string, icon: any, label: string, collapsed: boolean }) => ( @@ -24,16 +24,19 @@ export const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); const location = useLocation(); const navigate = useNavigate(); - const [currentUser, setCurrentUser] = useState(USERS[1]); // Default to standard user fallback + const [currentUser, setCurrentUser] = useState(null); useEffect(() => { - const storedUserId = localStorage.getItem('ctms_user_id'); - if (storedUserId) { - const user = USERS.find(u => u.id === storedUserId); - if (user) { - setCurrentUser(user); + const fetchCurrentUser = async () => { + const storedUserId = localStorage.getItem('ctms_user_id'); + if (storedUserId) { + const user = await getUserById(storedUserId); + if (user) { + setCurrentUser(user); + } } - } + }; + fetchCurrentUser(); }, []); const handleLogout = () => { @@ -41,16 +44,9 @@ export const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) => navigate('/login'); }; - // Simple title mapping based on route - const getPageTitle = () => { - if (location.pathname === '/') return 'Dashboard'; - if (location.pathname.includes('/admin/users')) return 'Gestão de Equipe'; - if (location.pathname.includes('/users/')) return 'Histórico do Usuário'; - if (location.pathname.includes('/attendances')) return 'Detalhes do Atendimento'; - if (location.pathname.includes('/super-admin')) return 'Gestão de Organizações'; - if (location.pathname.includes('/profile')) return 'Meu Perfil'; - return 'CTMS'; - }; + if (!currentUser) { + return
Carregando...
; + } const isSuperAdmin = currentUser.role === 'super_admin'; diff --git a/pages/Dashboard.tsx b/pages/Dashboard.tsx index 25bd0c2..dc1d5d3 100644 --- a/pages/Dashboard.tsx +++ b/pages/Dashboard.tsx @@ -40,10 +40,11 @@ export const Dashboard: React.FC = () => { const fetchData = async () => { setLoading(true); try { + const tenantId = localStorage.getItem('ctms_tenant_id') || CURRENT_TENANT_ID; // Fetch users and attendances in parallel const [fetchedUsers, fetchedData] = await Promise.all([ - getUsers(CURRENT_TENANT_ID), - getAttendances(CURRENT_TENANT_ID, filters) + getUsers(tenantId), + getAttendances(tenantId, filters) ]); setUsers(fetchedUsers); diff --git a/pages/Login.tsx b/pages/Login.tsx index 3884325..88ad427 100644 --- a/pages/Login.tsx +++ b/pages/Login.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Hexagon, Lock, Mail, ArrowRight, Loader2, Info } from 'lucide-react'; -import { USERS } from '../constants'; +import { getUsers } from '../services/dataService'; export const Login: React.FC = () => { const navigate = useNavigate(); @@ -10,18 +10,20 @@ export const Login: React.FC = () => { const [password, setPassword] = useState('password'); const [error, setError] = useState(''); - const handleLogin = (e: React.FormEvent) => { + const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setIsLoading(true); setError(''); - // Simulate API call and validation - setTimeout(() => { - const user = USERS.find(u => u.email.toLowerCase() === email.toLowerCase()); + try { + // Fetch all users to find match (simplified auth for demo) + const users = await getUsers('all'); + const user = users.find(u => u.email.toLowerCase() === email.toLowerCase()); if (user) { // Mock Login: Save to local storage localStorage.setItem('ctms_user_id', user.id); + localStorage.setItem('ctms_tenant_id', user.tenant_id); setIsLoading(false); @@ -33,9 +35,13 @@ export const Login: React.FC = () => { } } else { setIsLoading(false); - setError('Usuário não encontrado. Tente lidya@fasto.com ou root@system.com'); + setError('Usuário não encontrado. Tente os e-mails cadastrados.'); } - }, 1000); + } catch (err) { + console.error("Login error:", err); + setIsLoading(false); + setError('Erro ao conectar ao servidor.'); + } }; const fillCredentials = (type: 'admin' | 'super') => { diff --git a/pages/TeamManagement.tsx b/pages/TeamManagement.tsx index ff314b7..6908bcf 100644 --- a/pages/TeamManagement.tsx +++ b/pages/TeamManagement.tsx @@ -1,13 +1,27 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Users, Plus, MoreHorizontal, Mail, Shield, Search, X, Edit, Trash2, Save } from 'lucide-react'; -import { USERS } from '../constants'; +import { getUsers } from '../services/dataService'; +import { CURRENT_TENANT_ID } from '../constants'; import { User } from '../types'; export const TeamManagement: React.FC = () => { - const [users, setUsers] = useState(USERS.filter(u => u.role !== 'super_admin')); // Default hide super admin from list + const [users, setUsers] = useState([]); + const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [searchTerm, setSearchTerm] = useState(''); + useEffect(() => { + const fetchUsers = async () => { + setLoading(true); + const tenantId = localStorage.getItem('ctms_tenant_id') || CURRENT_TENANT_ID; + const data = await getUsers(tenantId); + // Hide super admin from the list for standard admin view + setUsers(data.filter(u => u.role !== 'super_admin')); + setLoading(false); + }; + fetchUsers(); + }, []); + // State for handling Add/Edit const [editingUser, setEditingUser] = useState(null); const [formData, setFormData] = useState({ @@ -23,6 +37,10 @@ export const TeamManagement: React.FC = () => { u.email.toLowerCase().includes(searchTerm.toLowerCase()) ); + if (loading && users.length === 0) { + return
Carregando equipe...
; + } + const getRoleBadge = (role: string) => { switch (role) { case 'super_admin': return 'bg-slate-900 text-white border-slate-700'; diff --git a/pages/UserDetail.tsx b/pages/UserDetail.tsx index b1028e5..e80f628 100644 --- a/pages/UserDetail.tsx +++ b/pages/UserDetail.tsx @@ -20,11 +20,12 @@ export const UserDetail: React.FC = () => { const loadData = async () => { try { + const tenantId = localStorage.getItem('ctms_tenant_id') || CURRENT_TENANT_ID; const u = await getUserById(id); setUser(u); if (u) { - const data = await getAttendances(CURRENT_TENANT_ID, { + const data = await getAttendances(tenantId, { userId: id, dateRange: { start: new Date(0), end: new Date() } // All time }); diff --git a/pages/UserProfile.tsx b/pages/UserProfile.tsx index 8fc90a6..387bbc1 100644 --- a/pages/UserProfile.tsx +++ b/pages/UserProfile.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Camera, Save, Mail, User as UserIcon, Building, Shield, Loader2, CheckCircle2 } from 'lucide-react'; -import { USERS } from '../constants'; +import { getUserById } from '../services/dataService'; import { User } from '../types'; export const UserProfile: React.FC = () => { @@ -14,11 +14,18 @@ export const UserProfile: React.FC = () => { const [bio, setBio] = useState(''); useEffect(() => { - // Simulate fetching user data - const currentUser = USERS[0]; - setUser(currentUser); - setName(currentUser.name); - setBio(currentUser.bio || ''); + const fetchUser = async () => { + const storedId = localStorage.getItem('ctms_user_id'); + if (storedId) { + const fetchedUser = await getUserById(storedId); + if (fetchedUser) { + setUser(fetchedUser); + setName(fetchedUser.name); + setBio(fetchedUser.bio || ''); + } + } + }; + fetchUser(); }, []); const handleSubmit = (e: React.FormEvent) => {