MelissaPaciente: dialog inline nova sessao + createSession mutation
Espelha o padrao do "Lancamento" mas pra agenda — botao "Agendar" agora
navega pra aba Agenda e abre dialog de nova sessao.
NOVO em src/features/patients/composables/usePatientSessions.js
- createSession(patientId, payload) — INSERT agenda_eventos com
status='agendado', resolve owner_id (auth.getUser) e tenant_id (lazy
import tenantStore). Auto-reload via _lastPatientId.
Validacao: inicio_em + fim_em obrigatorios.
Retorna {ok, data?, error?}.
NOVO em MelissaPaciente.vue
- Refs novaSessaoOpen + novaSessaoForm (tipo/data/hora/duracao_min/
modalidade/titulo_custom/observacoes)
- 3 catalogos:
- SESSAO_TIPOS: Sessao/Primeira/Retorno/Avaliacao/Devolutiva
- SESSAO_DURACOES: 30/40/45/50/55/60/90/120 min
- SESSAO_MODALIDADES: Presencial/Online
- goAgendar() agora alem de navegar pra aba Agenda, tambem inicializa
o form (default amanha 09:00, sessao 50min presencial) e abre o dialog.
- salvarSessao() handler com validacao (data + hora) e construcao de
inicio_em/fim_em a partir de data + hora + duracao_min. Local time
-> ISO via Date constructor.
- <Dialog> 460px com form: Tipo + grid 2-col (data + hora) + grid 2-col
(duracao + modalidade) + titulo opcional + observacoes Textarea.
- CSS .mpa-novo-lanc__opt pra "(opcional)" em cinza.
Validacoes:
- Data e hora obrigatorios (warn toast)
- Date constructor invalido -> warn toast
Pra criar sessoes mais complexas (recorrencia, multi-paciente, conflitos
de agenda), o user vai pra MelissaAgenda direto que tem o
AgendaEventDialog completo. Aqui no prontuario eh o caminho rapido.
ESLint: 0 errors.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -84,6 +84,64 @@ export function usePatientSessions() {
|
||||
.slice(0, 6)
|
||||
);
|
||||
|
||||
/**
|
||||
* Cria uma nova sessao na agenda do paciente.
|
||||
*
|
||||
* payload: {
|
||||
* inicio_em: ISO timestamp,
|
||||
* fim_em: ISO timestamp,
|
||||
* tipo: 'sessao' | 'primeira' | 'retorno' | etc,
|
||||
* modalidade: 'presencial' | 'online',
|
||||
* titulo?: string,
|
||||
* titulo_custom?: string,
|
||||
* observacoes?: string
|
||||
* }
|
||||
* Retorna {ok, data?, error?}.
|
||||
*/
|
||||
async function createSession(patientId, payload = {}) {
|
||||
if (!patientId || busy.value) return { ok: false, error: 'busy' };
|
||||
if (!payload?.inicio_em || !payload?.fim_em) {
|
||||
return { ok: false, error: 'Inicio/fim obrigatorios' };
|
||||
}
|
||||
busy.value = true;
|
||||
try {
|
||||
const { data: userData } = await supabase.auth.getUser();
|
||||
const ownerId = userData?.user?.id;
|
||||
let tenantId = null;
|
||||
try {
|
||||
const { useTenantStore } = await import('@/stores/tenantStore');
|
||||
tenantId = useTenantStore().activeTenantId || null;
|
||||
} catch { /* sem tenant store — segue */ }
|
||||
|
||||
const row = {
|
||||
patient_id: patientId,
|
||||
owner_id: ownerId,
|
||||
tenant_id: tenantId,
|
||||
inicio_em: payload.inicio_em,
|
||||
fim_em: payload.fim_em,
|
||||
status: 'agendado',
|
||||
modalidade: payload.modalidade || 'presencial',
|
||||
tipo: payload.tipo || 'sessao',
|
||||
titulo: String(payload.titulo || '').trim() || null,
|
||||
titulo_custom: String(payload.titulo_custom || '').trim() || null,
|
||||
observacoes: String(payload.observacoes || '').trim() || null
|
||||
};
|
||||
|
||||
const { data, error: err } = await supabase
|
||||
.from('agenda_eventos')
|
||||
.insert([row])
|
||||
.select()
|
||||
.single();
|
||||
if (err) throw err;
|
||||
if (_lastPatientId) await load(_lastPatientId);
|
||||
return { ok: true, data };
|
||||
} catch (e) {
|
||||
return { ok: false, error: e?.message || 'Erro ao agendar sessao' };
|
||||
} finally {
|
||||
busy.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza o status de uma sessao (mutation). Recarrega a lista do paciente
|
||||
* ao final pra refletir o novo estado nos computeds derivados.
|
||||
@@ -114,6 +172,7 @@ export function usePatientSessions() {
|
||||
busy,
|
||||
load,
|
||||
updateStatus,
|
||||
createSession,
|
||||
proximaSessao,
|
||||
ultimaSessao,
|
||||
totalSessoes,
|
||||
|
||||
Reference in New Issue
Block a user