Files
agenciapsilmno/src/features/agenda/components/cards/AgendaNextSessionsCardList.vue
T

119 lines
5.1 KiB
Vue

<!--
|--------------------------------------------------------------------------
| Agência PSI
|--------------------------------------------------------------------------
| Criado e desenvolvido por Leonardo Nohama
|
| Tecnologia aplicada à escuta.
| Estrutura para o cuidado.
|
| Arquivo: src/features/agenda/components/cards/AgendaNextSessionsCardList.vue
| Data: 2026
| Local: São Carlos/SP Brasil
|--------------------------------------------------------------------------
| © 2026 Todos os direitos reservados
|--------------------------------------------------------------------------
-->
<script setup>
import { computed, ref, watch } from 'vue';
const props = defineProps({
title: { type: String, default: 'Agenda' },
view: { type: String, default: 'day' }, // 'day' | 'week'
mode: { type: String, default: 'work_hours' } // 'full_24h' | 'work_hours'
});
const emit = defineEmits(['today', 'prev', 'next', 'changeView', 'toggleMode', 'createSession', 'createBlock', 'search']);
// UX: busca com debounce simples
const searchLocal = ref('');
let t = null;
watch(searchLocal, (v) => {
clearTimeout(t);
t = setTimeout(() => emit('search', v), 220);
});
// SelectButtons (executivo, direto)
const viewOptions = [
{ label: 'Dia', value: 'day' },
{ label: 'Semana', value: 'week' }
];
const modeOptions = [
{ label: 'Horário de funcionamento', value: 'work_hours' },
{ label: 'Dia completo (24h)', value: 'full_24h' }
];
const modeTag = computed(() => {
return props.mode === 'full_24h' ? { severity: 'info', text: '24h' } : { severity: 'success', text: 'Funcionamento' };
});
function onChangeView(val) {
emit('changeView', val);
}
function onToggleMode(val) {
emit('toggleMode', val);
}
</script>
<template>
<Card class="mb-3 md:mb-4">
<template #content>
<div class="flex flex-column gap-3">
<!-- Top row -->
<div class="flex align-items-start justify-content-between gap-3 flex-wrap">
<div class="min-w-0">
<div class="flex align-items-center gap-2 flex-wrap">
<div class="text-xl md:text-2xl font-semibold leading-tight">
{{ title }}
</div>
<Tag :severity="modeTag.severity" :value="modeTag.text" />
</div>
<div class="text-sm mt-1" style="color: var(--text-color-secondary)">Navegue, filtre e crie compromissos com velocidade sem perder controle clínico.</div>
</div>
<div class="flex align-items-center gap-2 flex-wrap">
<Button size="small" icon="pi pi-plus" label="Sessão" @click="emit('createSession')" />
<Button size="small" icon="pi pi-lock" severity="secondary" label="Bloqueio" @click="emit('createBlock')" />
</div>
</div>
<Divider class="my-0" />
<!-- Controls row -->
<div class="grid gap-3 md:gap-4" style="grid-template-columns: 1fr">
<div class="grid gap-3 md:gap-4 items-center" style="grid-template-columns: 1fr">
<div class="flex align-items-center justify-content-between gap-3 flex-wrap">
<!-- Nav -->
<div class="flex align-items-center gap-2 flex-wrap">
<Button size="small" text icon="pi pi-angle-left" @click="emit('prev')" />
<Button size="small" text icon="pi pi-angle-right" @click="emit('next')" />
<Button size="small" icon="pi pi-calendar" label="Hoje" @click="emit('today')" />
</div>
<!-- View + Mode -->
<div class="flex align-items-center gap-2 flex-wrap">
<SelectButton :modelValue="view" :options="viewOptions" optionLabel="label" optionValue="value" @update:modelValue="onChangeView" />
<SelectButton :modelValue="mode" :options="modeOptions" optionLabel="label" optionValue="value" @update:modelValue="onToggleMode" />
</div>
</div>
<!-- Search -->
<div class="flex align-items-center gap-2 flex-wrap">
<div class="flex-1 min-w-[260px]">
<FloatLabel>
<InputText id="agenda-search" v-model="searchLocal" class="w-full" />
<label for="agenda-search">Buscar por título / observação</label>
</FloatLabel>
</div>
<Button size="small" text icon="pi pi-times" :disabled="!searchLocal" @click="searchLocal = ''" />
</div>
</div>
</div>
</div>
</template>
</Card>
</template>