Files
scoreodonto.com/frontend/views/ConfiguracoesView.tsx
T
VPS 4 Builder 2a284f9e6e feat(ui): add Configurações page with profile/integration cards
Move user profile card and Google connect button from sidebar footer
to a dedicated Configurações view. Sidebar footer now shows a compact
user button that navigates to settings. All roles have access.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 04:54:22 +02:00

130 lines
6.3 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { User, Building2, ShieldCheck, LogOut } from 'lucide-react';
import { HybridBackend } from '../services/backend.ts';
import { GoogleConnectButton } from '../components/GoogleConnectButton.tsx';
export const ConfiguracoesView: React.FC = () => {
const [connectedAccounts, setConnectedAccounts] = useState<any[]>([]);
const currentRole = HybridBackend.getCurrentRole();
const userName = HybridBackend.getCurrentUserName();
const userEmail = HybridBackend.getCurrentUser();
const activeWorkspace = HybridBackend.getActiveWorkspace();
const clinColor = activeWorkspace?.cor || '#2563eb';
const fetchGoogleStatus = async () => {
try {
const response = await fetch('/api/auth/google/status');
const data = await response.json();
setConnectedAccounts(data);
} catch (error) {
console.error('Erro ao buscar status do Google:', error);
}
};
useEffect(() => {
fetchGoogleStatus();
}, []);
const handleLogout = () => {
if (window.confirm('TEM CERTEZA QUE DESEJA SAIR DO SISTEMA?')) {
HybridBackend.logout();
}
};
return (
<div className="space-y-8 max-w-2xl">
<div>
<h1 className="text-2xl font-black text-gray-900 uppercase tracking-tight">Configurações</h1>
<p className="text-sm text-gray-400 font-medium mt-1">Gerencie seu perfil e integrações</p>
</div>
{/* Perfil */}
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
<div className="px-6 py-4 border-b border-gray-50">
<h2 className="text-xs font-black text-gray-500 uppercase tracking-widest">Perfil</h2>
</div>
<div className="p-6">
<div className="flex items-center gap-4">
<div className="w-14 h-14 bg-gray-100 rounded-full flex items-center justify-center text-gray-500 border border-gray-200 flex-shrink-0">
<User size={24} />
</div>
<div className="min-w-0">
<p className="text-base font-black text-gray-800 uppercase truncate leading-none mb-1">{userName || '—'}</p>
<p className="text-sm font-medium text-gray-400 truncate">{userEmail || '—'}</p>
<span
className="inline-block mt-2 text-[10px] font-black uppercase tracking-widest px-2 py-0.5 rounded-full"
style={{ backgroundColor: `${clinColor}18`, color: clinColor }}
>
{currentRole}
</span>
</div>
</div>
</div>
</div>
{/* Unidade ativa */}
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
<div className="px-6 py-4 border-b border-gray-50">
<h2 className="text-xs font-black text-gray-500 uppercase tracking-widest">Unidade Ativa</h2>
</div>
<div className="p-6">
<div className="flex items-center gap-4">
<div
className="w-12 h-12 rounded-xl flex items-center justify-center text-white flex-shrink-0"
style={{ backgroundColor: clinColor }}
>
<Building2 size={20} />
</div>
<div>
<p className="text-sm font-black text-gray-800 uppercase">{activeWorkspace?.nome || 'Sem unidade vinculada'}</p>
{activeWorkspace?.id && (
<p className="text-[11px] text-gray-400 font-mono mt-0.5">ID: {activeWorkspace.id}</p>
)}
</div>
<div
className="ml-auto w-3 h-3 rounded-full flex-shrink-0"
style={{ backgroundColor: clinColor }}
/>
</div>
</div>
</div>
{/* Integrações */}
{currentRole === 'admin' && (
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
<div className="px-6 py-4 border-b border-gray-50">
<h2 className="text-xs font-black text-gray-500 uppercase tracking-widest">Integrações</h2>
</div>
<div className="p-6">
<GoogleConnectButton
ownerId="admin"
isConnected={connectedAccounts.some(a => a.owner_id === 'admin' || a.owner_id === userEmail)}
onStatusChange={fetchGoogleStatus}
/>
</div>
</div>
)}
{/* Segurança */}
<div className="bg-white rounded-2xl border border-gray-100 shadow-sm overflow-hidden">
<div className="px-6 py-4 border-b border-gray-50">
<h2 className="text-xs font-black text-gray-500 uppercase tracking-widest">Segurança</h2>
</div>
<div className="p-6 space-y-3">
<div className="flex items-center gap-3 text-green-600 bg-green-50 px-4 py-3 rounded-xl border border-green-100">
<ShieldCheck size={16} />
<span className="text-xs font-bold uppercase tracking-wide">Sessão ativa e autenticada</span>
</div>
<button
onClick={handleLogout}
className="w-full flex items-center justify-center gap-2 px-4 py-3 bg-red-50 text-red-600 hover:bg-red-100 rounded-xl text-xs font-black uppercase tracking-widest transition-all border border-red-100"
>
<LogOut size={16} />
Sair do Sistema
</button>
</div>
</div>
</div>
);
};