diff --git a/frontend/views/ClinicasView.tsx b/frontend/views/ClinicasView.tsx index 0cbcbde..2926384 100644 --- a/frontend/views/ClinicasView.tsx +++ b/frontend/views/ClinicasView.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Building2, ArrowRight, Shield, MapPin, BadgeCheck, Palette, Save, Loader2 } from 'lucide-react'; +import { Building2, ArrowRight, Shield, MapPin, BadgeCheck, Palette, Save, Loader2, Plus, X } from 'lucide-react'; import { HybridBackend } from '../services/backend.ts'; import { PageHeader } from '../components/PageHeader.tsx'; import { EmptyState } from '../components/EmptyState.tsx'; @@ -24,9 +24,43 @@ export const ClinicasView: React.FC = () => { const currentRole = HybridBackend.getCurrentRole(); const isAdmin = currentRole === 'admin' || currentRole === 'donoclinica'; + // Papel da CONTA (não da unidade ativa) — é o que o backend usa para decidir + // se a nova unidade nasce como 'clinica' ou 'consultorio'. + const accountRole = (() => { + try { return JSON.parse(localStorage.getItem('SCOREODONTO_USER_DATA') || '{}').role as string | undefined; } + catch { return undefined; } + })(); + const isConsultorioAccount = accountRole === 'donoconsultorio'; + const unitLabel = isConsultorioAccount ? 'CONSULTÓRIO' : 'CLÍNICA'; + const canCreate = ['donoclinica', 'donoconsultorio', 'admin'].includes(accountRole || ''); + const [isEditingColor, setIsEditingColor] = useState(null); const [savingColor, setSavingColor] = useState(false); + const [showCreate, setShowCreate] = useState(false); + const [newNome, setNewNome] = useState(''); + const [newDoc, setNewDoc] = useState(''); + const [creating, setCreating] = useState(false); + + const handleCreate = async (e: React.FormEvent) => { + e.preventDefault(); + if (!newNome.trim()) return; + setCreating(true); + try { + const result = await HybridBackend.createClinica(newNome.trim(), newDoc.trim() || undefined); + if (!result.success) { toast.error(result.message || 'ERRO AO CRIAR UNIDADE.'); return; } + // Recarrega a lista COMPLETA do servidor (acrescenta a nova unidade às existentes, + // em vez de sobrescrever). A tela relê os workspaces no reload. + await HybridBackend.refreshWorkspaces(); + toast.success(`${unitLabel} CRIADA!`); + setTimeout(() => window.location.reload(), 900); + } catch { + toast.error('ERRO DE CONEXÃO.'); + } finally { + setCreating(false); + } + }; + const handleSwitch = (workspaceId: string) => { if (activeWorkspace?.id === workspaceId) { toast.info("VOCÊ JÁ ESTÁ NESTA UNIDADE."); @@ -81,6 +115,17 @@ export const ClinicasView: React.FC = () => { description="Configure a identidade visual e selecione a clínica para gerenciar atendimentos." /> + {canCreate && ( +
+ +
+ )} + {workspaces.length === 0 && ( )} @@ -208,6 +253,54 @@ export const ClinicasView: React.FC = () => { ))} + + {showCreate && ( +
{ if (!creating) setShowCreate(false); }} + > +
e.stopPropagation()}> +
+

Nova {unitLabel.toLowerCase()}

+ +
+
+
+ + setNewNome(e.target.value.toUpperCase())} + className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-teal-500 outline-none text-sm font-medium uppercase" + placeholder={isConsultorioAccount ? 'EX: DR. SILVA - CONSULTÓRIO' : 'EX: CLÍNICA SORRISO'} + /> +
+
+ + setNewDoc(e.target.value)} + className="w-full px-4 py-3 border border-gray-300 rounded-xl focus:ring-2 focus:ring-teal-500 outline-none text-sm font-medium" + placeholder="00.000.000/0000-00" + /> +
+ +
+
+
+ )} ); }; diff --git a/frontend/views/CreateClinicView.tsx b/frontend/views/CreateClinicView.tsx index bf8a649..889f469 100644 --- a/frontend/views/CreateClinicView.tsx +++ b/frontend/views/CreateClinicView.tsx @@ -10,17 +10,6 @@ function getStoredUser(): { nome?: string; role?: string } { try { return JSON.parse(localStorage.getItem('SCOREODONTO_USER_DATA') || '{}'); } catch { return {}; } } -function applyWorkspace(result: any, userRole: string) { - const ws = { - id: result.clinica.id, - nome: result.clinica.nome_fantasia, - cor: '#2563eb', - role: userRole, - }; - localStorage.setItem('SCOREODONTO_WORKSPACES', JSON.stringify([ws])); - localStorage.setItem('SCOREODONTO_ACTIVE_WORKSPACE', JSON.stringify(ws)); -} - export const CreateClinicView: React.FC = ({ onCreated }) => { const storedUser = getStoredUser(); const userRole = storedUser.role || 'donoclinica'; @@ -37,7 +26,9 @@ export const CreateClinicView: React.FC = ({ onCreated }) const doCreate = async (nomeFinal: string, doc?: string) => { const result = await HybridBackend.createClinica(nomeFinal.trim(), doc?.trim() || undefined); if (!result.success) return result; - applyWorkspace(result, userRole); + // Recarrega a lista do servidor (acrescenta a nova unidade às existentes em vez de + // sobrescrever). No onboarding o usuário tem só esta unidade, então vira a ativa. + await HybridBackend.refreshWorkspaces(); return result; };