2025-11-14 17:13:37 +03:00

157 lines
4.4 KiB
Vue

<template>
<agenda-template>
<template #agenda-title>
<h5 class="mb-0">Agenda des Interventions</h5>
<p class="text-sm text-muted mb-0">
Gérez vos interventions et rendez-vous
</p>
</template>
<template #agenda-actions>
<add-intervention-button
text="Nouvelle Intervention"
@click="handleAddIntervention"
/>
</template>
<template #agenda-calendar>
<div v-if="loading" class="text-center py-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Chargement...</span>
</div>
<p class="text-muted mt-2">Chargement des interventions...</p>
</div>
<div v-else>
<agenda-calendar
:events="calendarEvents"
:loading="false"
@date-click="handleDateClick"
@event-click="handleEventClick"
@month-change="handleMonthChange"
/>
</div>
</template>
<template #agenda-sidebar>
<div v-if="loading" class="card">
<div class="card-header pb-0">
<h6 class="mb-0">Interventions à venir</h6>
</div>
<div class="card-body p-3">
<div class="text-center py-4">
<div
class="spinner-border spinner-border-sm text-primary me-2"
role="status"
>
<span class="visually-hidden">Chargement...</span>
</div>
<span class="text-muted">Chargement...</span>
</div>
</div>
</div>
<upcoming-interventions v-else :interventions="upcomingInterventions" />
</template>
</agenda-template>
</template>
<script setup>
import { computed } from "vue";
import AgendaTemplate from "@/components/templates/Agenda/AgendaTemplate.vue";
import AddInterventionButton from "@/components/atoms/Agenda/AddInterventionButton.vue";
import AgendaCalendar from "@/components/molecules/Agenda/AgendaCalendar.vue";
import UpcomingInterventions from "@/components/molecules/Agenda/UpcomingInterventions.vue";
import { defineProps, defineEmits } from "vue";
const props = defineProps({
interventions: {
type: Array,
default: () => [],
},
loading: {
type: Boolean,
default: false,
},
});
const emit = defineEmits([
"add-intervention",
"date-click",
"event-click",
"edit-intervention",
"month-change",
]);
// Transform interventions to calendar events format
const calendarEvents = computed(() => {
return props.interventions.map((intervention) => {
const statusColors = {
scheduled: "bg-gradient-info",
"in-progress": "bg-gradient-warning",
completed: "bg-gradient-success",
cancelled: "bg-gradient-secondary",
};
return {
id: intervention.id,
title: intervention.type || "Intervention",
start: intervention.scheduled_at,
end: intervention.scheduled_at,
className: statusColors[intervention.status] || "bg-gradient-info",
extendedProps: {
deceased: intervention.deceased,
status: intervention.status,
practitioner: intervention.assignedPractitioner,
type: intervention.type,
},
};
});
});
// Get upcoming interventions (next 7 days)
const upcomingInterventions = computed(() => {
const now = new Date();
const nextWeek = new Date(now.getTime() + 7 * 24 * 60 * 60 * 1000);
return props.interventions
.filter((intervention) => {
const date = new Date(intervention.scheduled_at);
return (
date >= now && date <= nextWeek && intervention.status !== "annule"
);
})
.sort((a, b) => new Date(a.scheduled_at) - new Date(b.scheduled_at))
.slice(0, 5)
.map((intervention) => ({
id: intervention.id,
title: intervention.type || "Intervention",
date: intervention.scheduled_at,
status: intervention.status,
deceased: intervention.deceased
? `${intervention.deceased.first_name} ${intervention.deceased.last_name}`
: null,
}));
});
const handleAddIntervention = () => {
emit("add-intervention");
};
const handleDateClick = (info) => {
emit("date-click", info);
};
const handleEventClick = (info) => {
emit("event-click", info.event);
};
const handleMonthChange = (dateInfo) => {
// Simply emit the event - parent handles all loading logic
emit("month-change", dateInfo);
};
</script>
<style scoped>
/* Additional styles if needed */
</style>