feat: implement real user profile and authentication state
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m3s
All checks were successful
Build and Deploy / build-and-push (push) Successful in 2m3s
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Camera, Save, Mail, User as UserIcon, Building, Shield, Loader2, CheckCircle2 } from 'lucide-react';
|
||||
import { getUserById } from '../services/dataService';
|
||||
import { User } from '../types';
|
||||
import { getUserById, getTenants } from '../services/dataService';
|
||||
import { User, Tenant } from '../types';
|
||||
|
||||
export const UserProfile: React.FC = () => {
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
const [tenant, setTenant] = useState<Tenant | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isSuccess, setIsSuccess] = useState(false);
|
||||
|
||||
@@ -12,22 +13,29 @@ export const UserProfile: React.FC = () => {
|
||||
const [bio, setBio] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
const fetchUser = async () => {
|
||||
const storedId = localStorage.getItem('ctms_user_id');
|
||||
if (storedId) {
|
||||
const fetchUserAndTenant = async () => {
|
||||
const storedUserId = localStorage.getItem('ctms_user_id');
|
||||
if (storedUserId) {
|
||||
try {
|
||||
const fetchedUser = await getUserById(storedId);
|
||||
const fetchedUser = await getUserById(storedUserId);
|
||||
if (fetchedUser) {
|
||||
setUser(fetchedUser);
|
||||
setName(fetchedUser.name);
|
||||
setBio(fetchedUser.bio || '');
|
||||
|
||||
// Fetch tenant info
|
||||
const tenants = await getTenants();
|
||||
const userTenant = tenants.find(t => t.id === fetchedUser.tenant_id);
|
||||
if (userTenant) {
|
||||
setTenant(userTenant);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Error fetching profile:", err);
|
||||
console.error("Error fetching profile data:", err);
|
||||
}
|
||||
}
|
||||
};
|
||||
fetchUser();
|
||||
fetchUserAndTenant();
|
||||
}, []);
|
||||
|
||||
const handleSubmit = (e: React.FormEvent) => {
|
||||
@@ -59,7 +67,7 @@ export const UserProfile: React.FC = () => {
|
||||
<div className="bg-white p-6 rounded-2xl shadow-sm border border-slate-200 flex flex-col items-center text-center">
|
||||
<div className="relative group cursor-pointer">
|
||||
<div className="w-32 h-32 rounded-full overflow-hidden border-4 border-slate-50 shadow-sm">
|
||||
<img src={user.avatar_url} alt={user.name} className="w-full h-full object-cover" />
|
||||
<img src={user.avatar_url || `https://ui-avatars.com/api/?name=${encodeURIComponent(user.name)}&background=random`} alt={user.name} className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div className="absolute inset-0 bg-black/40 rounded-full flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200">
|
||||
<Camera className="text-white" size={28} />
|
||||
@@ -76,21 +84,23 @@ export const UserProfile: React.FC = () => {
|
||||
<span className="px-3 py-1 bg-purple-100 text-purple-700 rounded-full text-xs font-semibold capitalize border border-purple-200">
|
||||
{user.role}
|
||||
</span>
|
||||
{user.team_id && (
|
||||
<span className="px-3 py-1 bg-blue-100 text-blue-700 rounded-full text-xs font-semibold border border-blue-200">
|
||||
{user.team_id === 'sales_1' ? 'Vendas Alpha' : 'Vendas Beta'}
|
||||
{user.team_id === 'sales_1' ? 'Vendas Alpha' : user.team_id === 'sales_2' ? 'Vendas Beta' : user.team_id}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-slate-100 rounded-xl p-4 border border-slate-200">
|
||||
<h3 className="text-xs font-bold text-slate-500 uppercase tracking-wider mb-3">Status da Conta</h3>
|
||||
<div className="flex items-center gap-3 text-sm text-slate-600 mb-2">
|
||||
<div className="w-2 h-2 rounded-full bg-green-500"></div>
|
||||
Ativo
|
||||
<div className={`w-2 h-2 rounded-full ${user.status === 'active' ? 'bg-green-500' : 'bg-slate-400'}`}></div>
|
||||
{user.status === 'active' ? 'Ativo' : 'Inativo'}
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-sm text-slate-600">
|
||||
<Building size={14} />
|
||||
Fasto Corp (Organização)
|
||||
{tenant?.name || 'Organização'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user