157 lines
4.4 KiB
Vue
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>
|