Correcao Sidebar Classico e Rail, Correcao Layout, Ajuste de Breakpoint para Tailwind, Ajuste AppTopbar, Ajuste Menu PopOver, Recriado Paleta de Cores, Inserido algumas animações leves, Reajuste Cor items NOVOS da tabela, Drawer Ajuda Corrigido no Logout, Whatsapp, sms, email, recursos extras

This commit is contained in:
Leonardo
2026-03-24 21:26:58 -03:00
parent a89d1f5560
commit 53a4980396
453 changed files with 121427 additions and 174407 deletions
+125 -151
View File
@@ -26,172 +26,146 @@
| created paciente criado ou atualizado com sucesso
|--------------------------------------------------------------------------
-->
<template>
<Dialog
v-model:visible="isOpen"
modal
:draggable="false"
:closable="false"
:dismissableMask="false"
:maximizable="false"
:style="{ width: '90vw', maxWidth: '1100px', height: maximized ? '100vh' : '90vh' }"
:contentStyle="{ padding: 0, overflow: 'auto', height: '100%' }"
pt:mask:class="backdrop-blur-xs"
>
<!-- Header -->
<template #header>
<div class="flex items-center justify-between w-full gap-3">
<!-- Título -->
<span class="text-base font-semibold text-[var(--text-color)] leading-tight">
{{ patientId ? 'Editar Paciente' : 'Cadastro de Paciente' }}
</span>
<!-- Botões à direita -->
<div class="flex items-center gap-1 ml-auto">
<!-- Preencher tudo ( testMODE) -->
<Button
v-if="pageRef?.canSee?.('testMODE')"
label="Preencher tudo"
icon="pi pi-bolt"
severity="secondary"
outlined
size="small"
class="rounded-full"
:disabled="pageRef?.saving?.value || pageRef?.deleting?.value"
@click="pageRef?.fillRandomPatient?.()"
/>
<!-- Excluir ( em edição) -->
<Button
v-if="patientId"
icon="pi pi-trash"
severity="danger"
outlined
size="small"
class="rounded-full"
:loading="pageRef?.deleting?.value"
:disabled="pageRef?.saving?.value || pageRef?.deleting?.value"
title="Excluir paciente"
@click="pageRef?.confirmDelete?.()"
/>
<!-- Maximizar -->
<button
class="w-8 h-8 rounded-lg border-none bg-transparent text-[var(--text-color-secondary)] cursor-pointer grid place-items-center text-sm transition-colors hover:bg-[var(--surface-ground)] hover:text-[var(--text-color)]"
:title="maximized ? 'Restaurar' : 'Maximizar'"
@click="maximized = !maximized"
>
<i :class="maximized ? 'pi pi-window-minimize' : 'pi pi-window-maximize'" />
</button>
<!-- Fechar -->
<button
class="w-8 h-8 rounded-lg border-none bg-transparent text-[var(--text-color-secondary)] cursor-pointer grid place-items-center text-sm transition-colors hover:bg-[var(--surface-ground)] hover:text-[var(--text-color)]"
title="Fechar"
@click="isOpen = false"
>
<i class="pi pi-times" />
</button>
</div>
</div>
</template>
<!-- Conteúdo -->
<PatientsCadastroPage
ref="pageRef"
:dialog-mode="true"
:patient-id="patientId"
@cancel="isOpen = false"
@created="onCreated"
/>
<!-- Footer -->
<template #footer>
<div class="flex justify-end gap-2">
<Button
label="Cancelar"
severity="secondary"
text
:disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value"
@click="isOpen = false"
/>
<!-- Na rota de pacientes: "Salvar" -->
<Button
v-if="isOnPatientsPage"
label="Salvar"
:loading="!!pageRef?.saving?.value"
:disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value"
@click="submitWith('only')"
/>
<!-- Fora da rota de pacientes: "Salvar e fechar" + "Salvar e ver pacientes" -->
<template v-else>
<Button
label="Salvar e fechar"
severity="secondary"
outlined
:loading="pendingMode === 'only' && !!pageRef?.saving?.value"
:disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value"
@click="submitWith('only')"
/>
<Button
label="Salvar e ver pacientes"
:loading="pendingMode === 'view' && !!pageRef?.saving?.value"
:disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value"
@click="submitWith('view')"
/>
</template>
</div>
</template>
</Dialog>
</template>
<script setup>
import { computed, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import PatientsCadastroPage from '@/features/patients/cadastro/PatientsCadastroPage.vue'
import { computed, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import PatientsCadastroPage from '@/features/patients/cadastro/PatientsCadastroPage.vue';
const props = defineProps({
modelValue: { type: Boolean, default: false },
patientId: { type: String, default: null }
})
const emit = defineEmits(['update:modelValue', 'created'])
modelValue: { type: Boolean, default: false },
patientId: { type: String, default: null }
});
const emit = defineEmits(['update:modelValue', 'created']);
const isOpen = computed({
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v)
})
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v)
});
// Reset maximized when dialog opens
watch(() => props.modelValue, (v) => { if (!v) maximized.value = false })
watch(
() => props.modelValue,
(v) => {
if (!v) maximized.value = false;
}
);
const maximized = ref(false)
const pageRef = ref(null)
const pendingMode = ref('only')
const maximized = ref(false);
const pageRef = ref(null);
const pendingMode = ref('only');
const route = useRoute()
const router = useRouter()
const route = useRoute();
const router = useRouter();
const isOnPatientsPage = computed(() => {
const p = String(route.path || '')
return p.includes('/patients') || p.includes('/pacientes')
})
const p = String(route.path || '');
return p.includes('/patients') || p.includes('/pacientes');
});
function patientsListRoute () {
const p = String(route.path || '')
return p.startsWith('/therapist') ? '/therapist/patients' : '/admin/pacientes'
function patientsListRoute() {
const p = String(route.path || '');
return p.startsWith('/therapist') ? '/therapist/patients' : '/admin/pacientes';
}
function submitWith (mode) {
pendingMode.value = mode
pageRef.value?.onSubmit()
function submitWith(mode) {
pendingMode.value = mode;
pageRef.value?.onSubmit();
}
async function onCreated (data) {
isOpen.value = false
emit('created', data)
if (pendingMode.value === 'view') {
await router.push(patientsListRoute())
}
async function onCreated(data) {
isOpen.value = false;
emit('created', data);
if (pendingMode.value === 'view') {
await router.push(patientsListRoute());
}
}
</script>
<template>
<Dialog
v-model:visible="isOpen"
modal
:draggable="false"
:closable="false"
:dismissableMask="false"
:maximizable="false"
:style="{ width: '90vw', maxWidth: '1100px', height: maximized ? '100vh' : '90vh' }"
:contentStyle="{ padding: 0, overflow: 'auto', height: '100%' }"
pt:mask:class="backdrop-blur-xs"
>
<!-- Header -->
<template #header>
<div class="flex items-center justify-between w-full gap-3">
<!-- Título -->
<span class="text-base font-semibold text-[var(--text-color)] leading-tight">
{{ patientId ? 'Editar Paciente' : 'Cadastro de Paciente' }}
</span>
<!-- Botões à direita -->
<div class="flex items-center gap-1 ml-auto">
<!-- Preencher tudo ( testMODE) -->
<Button
v-if="pageRef?.canSee?.('testMODE')"
label="Preencher tudo"
icon="pi pi-bolt"
severity="secondary"
outlined
size="small"
class="rounded-full"
:disabled="pageRef?.saving?.value || pageRef?.deleting?.value"
@click="pageRef?.fillRandomPatient?.()"
/>
<!-- Excluir ( em edição) -->
<Button
v-if="patientId"
icon="pi pi-trash"
severity="danger"
outlined
size="small"
class="rounded-full"
:loading="pageRef?.deleting?.value"
:disabled="pageRef?.saving?.value || pageRef?.deleting?.value"
title="Excluir paciente"
@click="pageRef?.confirmDelete?.()"
/>
<!-- Maximizar -->
<button
class="w-8 h-8 rounded-lg border-none bg-transparent text-[var(--text-color-secondary)] cursor-pointer grid place-items-center text-sm transition-colors hover:bg-[var(--surface-ground)] hover:text-[var(--text-color)]"
:title="maximized ? 'Restaurar' : 'Maximizar'"
@click="maximized = !maximized"
>
<i :class="maximized ? 'pi pi-window-minimize' : 'pi pi-window-maximize'" />
</button>
<!-- Fechar -->
<button
class="w-8 h-8 rounded-lg border-none bg-transparent text-[var(--text-color-secondary)] cursor-pointer grid place-items-center text-sm transition-colors hover:bg-[var(--surface-ground)] hover:text-[var(--text-color)]"
title="Fechar"
@click="isOpen = false"
>
<i class="pi pi-times" />
</button>
</div>
</div>
</template>
<!-- Conteúdo -->
<PatientsCadastroPage ref="pageRef" :dialog-mode="true" :patient-id="patientId" @cancel="isOpen = false" @created="onCreated" />
<!-- Footer -->
<template #footer>
<div class="flex justify-end gap-2">
<Button label="Cancelar" severity="secondary" text :disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value" @click="isOpen = false" />
<!-- Na rota de pacientes: "Salvar" -->
<Button v-if="isOnPatientsPage" label="Salvar" :loading="!!pageRef?.saving?.value" :disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value" @click="submitWith('only')" />
<!-- Fora da rota de pacientes: "Salvar e fechar" + "Salvar e ver pacientes" -->
<template v-else>
<Button label="Salvar e fechar" severity="secondary" outlined :loading="pendingMode === 'only' && !!pageRef?.saving?.value" :disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value" @click="submitWith('only')" />
<Button label="Salvar e ver pacientes" :loading="pendingMode === 'view' && !!pageRef?.saving?.value" :disabled="!!pageRef?.saving?.value || !!pageRef?.deleting?.value" @click="submitWith('view')" />
</template>
</div>
</template>
</Dialog>
</template>