fix-visual-adjustments
This commit is contained in:
parent
d966e40608
commit
f6fad55ff3
@ -309,7 +309,7 @@ export default function AgendamentoPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* legenda dinâmica: mostra as cores presentes nos agendamentos do dia atual */}
|
{/* legenda dinâmica: mostra as cores presentes nos agendamentos do dia atual */}
|
||||||
<div className="sm:absolute sm:top-2 sm:right-2 mt-2 sm:mt-0 z-40">
|
<div className="sm:absolute sm:top-2 sm:right-2 mt-2 sm:mt-0 z-10">
|
||||||
<DynamicLegend events={managerEvents} />
|
<DynamicLegend events={managerEvents} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -178,6 +178,33 @@ export default function LaudosEditorPage() {
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// Auto-salvar no localStorage sempre que houver mudanças (com debounce)
|
||||||
|
useEffect(() => {
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
// Capturar conteúdo atual do editor antes de salvar
|
||||||
|
const currentContent = editorRef.current?.innerHTML || content;
|
||||||
|
|
||||||
|
const draft = {
|
||||||
|
pacienteSelecionado,
|
||||||
|
content: currentContent,
|
||||||
|
campos,
|
||||||
|
solicitanteId,
|
||||||
|
solicitanteNome,
|
||||||
|
prazoDate,
|
||||||
|
prazoTime,
|
||||||
|
imagens,
|
||||||
|
lastSaved: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Só salvar se houver conteúdo ou dados preenchidos
|
||||||
|
if (currentContent || pacienteSelecionado || campos.exame || campos.diagnostico || imagens.length > 0) {
|
||||||
|
localStorage.setItem('laudoDraft', JSON.stringify(draft));
|
||||||
|
}
|
||||||
|
}, 1000); // Aguarda 1 segundo após última mudança
|
||||||
|
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [pacienteSelecionado, content, campos, solicitanteId, solicitanteNome, prazoDate, prazoTime, imagens]);
|
||||||
|
|
||||||
// Tentar obter o registro de médico correspondente ao usuário autenticado
|
// Tentar obter o registro de médico correspondente ao usuário autenticado
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let mounted = true;
|
let mounted = true;
|
||||||
@ -247,6 +274,23 @@ export default function LaudosEditorPage() {
|
|||||||
}
|
}
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
|
// Função para trocar de aba salvando conteúdo antes
|
||||||
|
const handleTabChange = (newTab: string) => {
|
||||||
|
// Salvar conteúdo do editor antes de trocar
|
||||||
|
if (editorRef.current) {
|
||||||
|
const editorContent = editorRef.current.innerHTML;
|
||||||
|
setContent(editorContent);
|
||||||
|
}
|
||||||
|
setActiveTab(newTab);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Restaurar conteúdo do editor quando voltar para a aba editor
|
||||||
|
useEffect(() => {
|
||||||
|
if (activeTab === 'editor' && editorRef.current && content) {
|
||||||
|
editorRef.current.innerHTML = content;
|
||||||
|
}
|
||||||
|
}, [activeTab]);
|
||||||
|
|
||||||
// Desfazer
|
// Desfazer
|
||||||
const handleUndo = () => {
|
const handleUndo = () => {
|
||||||
if (historyIndex > 0) {
|
if (historyIndex > 0) {
|
||||||
@ -321,11 +365,15 @@ export default function LaudosEditorPage() {
|
|||||||
|
|
||||||
// Salvar rascunho no localStorage
|
// Salvar rascunho no localStorage
|
||||||
const saveDraft = () => {
|
const saveDraft = () => {
|
||||||
|
// Capturar conteúdo atual do editor antes de salvar
|
||||||
|
const currentContent = editorRef.current?.innerHTML || content;
|
||||||
|
|
||||||
const draft = {
|
const draft = {
|
||||||
pacienteSelecionado,
|
pacienteSelecionado,
|
||||||
content,
|
content: currentContent,
|
||||||
campos,
|
campos,
|
||||||
solicitanteId,
|
solicitanteId,
|
||||||
|
solicitanteNome,
|
||||||
prazoDate,
|
prazoDate,
|
||||||
prazoTime,
|
prazoTime,
|
||||||
imagens,
|
imagens,
|
||||||
@ -389,6 +437,9 @@ export default function LaudosEditorPage() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Capturar conteúdo atual do editor antes de salvar
|
||||||
|
const currentContent = editorRef.current?.innerHTML || content;
|
||||||
|
|
||||||
const userId = user?.id || '00000000-0000-0000-0000-000000000001';
|
const userId = user?.id || '00000000-0000-0000-0000-000000000001';
|
||||||
|
|
||||||
let composedDueAt = undefined;
|
let composedDueAt = undefined;
|
||||||
@ -404,7 +455,7 @@ export default function LaudosEditorPage() {
|
|||||||
diagnosis: campos.diagnostico || '',
|
diagnosis: campos.diagnostico || '',
|
||||||
conclusion: campos.conclusao || '',
|
conclusion: campos.conclusao || '',
|
||||||
cid_code: campos.cid || '',
|
cid_code: campos.cid || '',
|
||||||
content_html: content,
|
content_html: currentContent,
|
||||||
content_json: {},
|
content_json: {},
|
||||||
requested_by: solicitanteId || userId,
|
requested_by: solicitanteId || userId,
|
||||||
due_at: composedDueAt ?? new Date().toISOString(),
|
due_at: composedDueAt ?? new Date().toISOString(),
|
||||||
@ -414,6 +465,10 @@ export default function LaudosEditorPage() {
|
|||||||
|
|
||||||
if (createNewReport) {
|
if (createNewReport) {
|
||||||
await createNewReport(payload as any);
|
await createNewReport(payload as any);
|
||||||
|
|
||||||
|
// Limpar rascunho salvo após sucesso
|
||||||
|
localStorage.removeItem('laudoDraft');
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: 'Laudo criado com sucesso!',
|
title: 'Laudo criado com sucesso!',
|
||||||
description: 'O laudo foi liberado e salvo.',
|
description: 'O laudo foi liberado e salvo.',
|
||||||
@ -536,7 +591,7 @@ export default function LaudosEditorPage() {
|
|||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex border-b border-border bg-card overflow-x-auto flex-shrink-0">
|
<div className="flex border-b border-border bg-card overflow-x-auto flex-shrink-0">
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('editor')}
|
onClick={() => handleTabChange('editor')}
|
||||||
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === 'editor'
|
activeTab === 'editor'
|
||||||
? 'border-blue-500 text-blue-600'
|
? 'border-blue-500 text-blue-600'
|
||||||
@ -547,7 +602,7 @@ export default function LaudosEditorPage() {
|
|||||||
Editor
|
Editor
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('imagens')}
|
onClick={() => handleTabChange('imagens')}
|
||||||
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === 'imagens'
|
activeTab === 'imagens'
|
||||||
? 'border-blue-500 text-blue-600'
|
? 'border-blue-500 text-blue-600'
|
||||||
@ -558,7 +613,7 @@ export default function LaudosEditorPage() {
|
|||||||
Imagens ({imagens.length})
|
Imagens ({imagens.length})
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('campos')}
|
onClick={() => handleTabChange('campos')}
|
||||||
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === 'campos'
|
activeTab === 'campos'
|
||||||
? 'border-blue-500 text-blue-600'
|
? 'border-blue-500 text-blue-600'
|
||||||
|
|||||||
@ -69,32 +69,47 @@ export default function EditarLaudoPage() {
|
|||||||
// Estado para rastrear alinhamento ativo
|
// Estado para rastrear alinhamento ativo
|
||||||
const [activeAlignment, setActiveAlignment] = useState('left');
|
const [activeAlignment, setActiveAlignment] = useState('left');
|
||||||
|
|
||||||
// Salvar conteúdo no localStorage sempre que muda
|
// Salvar conteúdo no localStorage sempre que muda (com debounce)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (content && laudoId) {
|
const timeoutId = setTimeout(() => {
|
||||||
localStorage.setItem(`laudo-draft-${laudoId}`, content);
|
if (laudoId) {
|
||||||
|
// Capturar conteúdo atual do editor antes de salvar
|
||||||
|
const currentContent = editorRef.current?.innerHTML || content;
|
||||||
|
|
||||||
|
const draft = {
|
||||||
|
content: currentContent,
|
||||||
|
campos,
|
||||||
|
lastSaved: new Date().toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
localStorage.setItem(`laudo-draft-${laudoId}`, JSON.stringify(draft));
|
||||||
}
|
}
|
||||||
}, [content, laudoId]);
|
}, 1000); // Aguarda 1 segundo após última mudança
|
||||||
|
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [content, campos, laudoId]);
|
||||||
|
|
||||||
// Sincronizar conteúdo com o editor
|
// Sincronizar conteúdo com o editor
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editorRef.current && content) {
|
if (editorRef.current && content) {
|
||||||
if (editorRef.current.innerHTML !== content) {
|
|
||||||
editorRef.current.innerHTML = content;
|
editorRef.current.innerHTML = content;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, [content]);
|
}, [content]);
|
||||||
|
|
||||||
|
// Função para trocar de aba salvando conteúdo antes
|
||||||
|
const handleTabChange = (newTab: string) => {
|
||||||
|
// Salvar conteúdo do editor antes de trocar
|
||||||
|
if (editorRef.current) {
|
||||||
|
const editorContent = editorRef.current.innerHTML;
|
||||||
|
setContent(editorContent);
|
||||||
|
}
|
||||||
|
setActiveTab(newTab);
|
||||||
|
};
|
||||||
|
|
||||||
// Restaurar conteúdo quando volta para a aba editor
|
// Restaurar conteúdo quando volta para a aba editor
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (activeTab === 'editor' && editorRef.current && content) {
|
if (activeTab === 'editor' && editorRef.current && content) {
|
||||||
editorRef.current.focus();
|
editorRef.current.innerHTML = content;
|
||||||
const range = document.createRange();
|
|
||||||
const sel = window.getSelection();
|
|
||||||
range.setStart(editorRef.current, editorRef.current.childNodes.length);
|
|
||||||
range.collapse(true);
|
|
||||||
sel?.removeAllRanges();
|
|
||||||
sel?.addRange(range);
|
|
||||||
}
|
}
|
||||||
}, [activeTab]);
|
}, [activeTab]);
|
||||||
|
|
||||||
@ -166,20 +181,36 @@ export default function EditarLaudoPage() {
|
|||||||
const contentHtml = r.content_html || r.conteudo_html || '';
|
const contentHtml = r.content_html || r.conteudo_html || '';
|
||||||
|
|
||||||
// Verificar se existe rascunho salvo no localStorage
|
// Verificar se existe rascunho salvo no localStorage
|
||||||
const draftContent = typeof window !== 'undefined' ? localStorage.getItem(`laudo-draft-${laudoId}`) : null;
|
let finalContent = contentHtml;
|
||||||
const finalContent = draftContent || contentHtml;
|
let finalCampos = {
|
||||||
|
cid: r.cid_code || r.cid || '',
|
||||||
|
diagnostico: r.diagnosis || r.diagnostico || '',
|
||||||
|
conclusao: r.conclusion || r.conclusao || '',
|
||||||
|
exame: r.exam || r.exame || '',
|
||||||
|
especialidade: r.especialidade || '',
|
||||||
|
mostrarData: !r.hide_date,
|
||||||
|
mostrarAssinatura: !r.hide_signature,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
const draftData = localStorage.getItem(`laudo-draft-${laudoId}`);
|
||||||
|
if (draftData) {
|
||||||
|
try {
|
||||||
|
const draft = JSON.parse(draftData);
|
||||||
|
if (draft.content) finalContent = draft.content;
|
||||||
|
if (draft.campos) finalCampos = { ...finalCampos, ...draft.campos };
|
||||||
|
} catch (err) {
|
||||||
|
// Se falhar parse, tentar como string simples (formato antigo)
|
||||||
|
finalContent = draftData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setCampos(finalCampos);
|
||||||
setContent(finalContent);
|
setContent(finalContent);
|
||||||
|
|
||||||
if (editorRef.current) {
|
if (editorRef.current) {
|
||||||
editorRef.current.innerHTML = finalContent;
|
editorRef.current.innerHTML = finalContent;
|
||||||
// Colocar cursor no final do texto
|
|
||||||
editorRef.current.focus();
|
|
||||||
const range = document.createRange();
|
|
||||||
const sel = window.getSelection();
|
|
||||||
range.setStart(editorRef.current, editorRef.current.childNodes.length);
|
|
||||||
range.collapse(true);
|
|
||||||
sel?.removeAllRanges();
|
|
||||||
sel?.addRange(range);
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Erro ao carregar laudo:', err);
|
console.warn('Erro ao carregar laudo:', err);
|
||||||
@ -357,7 +388,7 @@ export default function EditarLaudoPage() {
|
|||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex border-b border-border bg-card overflow-x-auto flex-shrink-0">
|
<div className="flex border-b border-border bg-card overflow-x-auto flex-shrink-0">
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('editor')}
|
onClick={() => handleTabChange('editor')}
|
||||||
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === 'editor'
|
activeTab === 'editor'
|
||||||
? 'border-blue-500 text-blue-600'
|
? 'border-blue-500 text-blue-600'
|
||||||
@ -368,7 +399,7 @@ export default function EditarLaudoPage() {
|
|||||||
Editor
|
Editor
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('campos')}
|
onClick={() => handleTabChange('campos')}
|
||||||
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
className={`px-2 sm:px-4 py-2 text-xs sm:text-sm font-medium border-b-2 transition-colors whitespace-nowrap ${
|
||||||
activeTab === 'campos'
|
activeTab === 'campos'
|
||||||
? 'border-blue-500 text-blue-600'
|
? 'border-blue-500 text-blue-600'
|
||||||
|
|||||||
@ -876,17 +876,6 @@ export default function ResultadosClient() {
|
|||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Mais filtros / Voltar */}
|
|
||||||
<div className="sm:col-span-4">
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
className="h-10 w-full rounded-full border border-primary/30 bg-primary/5 text-primary hover:bg-primary hover:text-primary-foreground"
|
|
||||||
>
|
|
||||||
<Filter className="mr-2 h-4 w-4" />
|
|
||||||
Mais filtros
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Voltar */}
|
{/* Voltar */}
|
||||||
<div className="sm:col-span-12">
|
<div className="sm:col-span-12">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -1396,13 +1396,13 @@ const ProfissionalPage = () => {
|
|||||||
|
|
||||||
{/* Filtros */}
|
{/* Filtros */}
|
||||||
<div className="p-4 border-b border-border">
|
<div className="p-4 border-b border-border">
|
||||||
<div className="flex flex-wrap items-center gap-4">
|
<div className="flex flex-wrap items-start gap-4">
|
||||||
<div className="relative flex-1 min-w-[200px]">
|
<div className="relative flex-1 min-w-[200px]">
|
||||||
{/* Search input integrado com busca por ID */}
|
{/* Search input integrado com busca por ID */}
|
||||||
<SearchBox />
|
<SearchBox />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2 mt-0">
|
||||||
<div className="flex items-center gap-1 text-sm">
|
<div className="flex items-center gap-1 text-sm">
|
||||||
<CalendarIcon className="w-4 h-4" />
|
<CalendarIcon className="w-4 h-4" />
|
||||||
<Input type="date" value={startDate ?? ''} onChange={(e) => { setStartDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm h-10" />
|
<Input type="date" value={startDate ?? ''} onChange={(e) => { setStartDate(e.target.value); setSelectedRange('custom'); }} className="p-1 text-sm h-10" />
|
||||||
@ -1411,7 +1411,7 @@ const ProfissionalPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center mt-0">
|
||||||
{/* date range buttons: Semana / Mês */}
|
{/* date range buttons: Semana / Mês */}
|
||||||
<DateRangeButtons />
|
<DateRangeButtons />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -79,7 +79,7 @@ export function PagesHeader({ title = "", subtitle = "" }: { title?: string, sub
|
|||||||
</Avatar>
|
</Avatar>
|
||||||
</Button>
|
</Button>
|
||||||
{dropdownOpen && (
|
{dropdownOpen && (
|
||||||
<div className="absolute right-0 mt-2 w-64 sm:w-80 bg-popover border border-border rounded-md shadow-lg z-50 text-popover-foreground animate-in fade-in slide-in-from-top-2">
|
<div className="absolute right-0 mt-2 w-64 sm:w-80 bg-popover border border-border rounded-md shadow-lg z-[100] text-popover-foreground animate-in fade-in slide-in-from-top-2">
|
||||||
<div className="p-3 sm:p-4 border-b border-border">
|
<div className="p-3 sm:p-4 border-b border-border">
|
||||||
<div className="flex flex-col space-y-1">
|
<div className="flex flex-col space-y-1">
|
||||||
<p className="text-xs sm:text-sm font-semibold leading-none">
|
<p className="text-xs sm:text-sm font-semibold leading-none">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user