add defunt et intervention

This commit is contained in:
Nyavokevin 2025-11-10 17:43:18 +03:00
parent 51ff282d5b
commit 0c4ff92fd5
21 changed files with 1240 additions and 369 deletions

View File

@ -0,0 +1,23 @@
<template>
<defunts-template>
<template #defunt-new-action>
<add-button text="Ajouter" />
</template>
<template #select-filter>
<filter-table />
</template>
<template #defunt-other-action>
<table-action />
</template>
<template #defunt-table>
<defunts-list />
</template>
</defunts-template>
</template>
<script setup>
import DefuntsTemplate from "@/components/templates/Defunts/DefuntsTemplate.vue";
import addButton from "@/components/molecules/new-button/addButton.vue";
import FilterTable from "@/components/molecules/Tables/FilterTable.vue";
import TableAction from "@/components/molecules/Tables/TableAction.vue";
import DefuntsList from "@/components/molecules/Defunts/DefuntsList.vue";
</script>

View File

@ -0,0 +1,23 @@
<template>
<interventions-template>
<template #intervention-new-action>
<add-button text="Ajouter" />
</template>
<template #select-filter>
<filter-table />
</template>
<template #intervention-other-action>
<table-action />
</template>
<template #intervention-table>
<interventions-list />
</template>
</interventions-template>
</template>
<script setup>
import InterventionsTemplate from "@/components/templates/Interventions/InterventionsTemplate.vue";
import addButton from "@/components/molecules/new-button/addButton.vue";
import FilterTable from "@/components/molecules/Tables/FilterTable.vue";
import TableAction from "@/components/molecules/Tables/TableAction.vue";
import interventionsList from "@/components/molecules/Interventions/interventionsList.vue";
</script>

View File

@ -0,0 +1,71 @@
<template>
<intervention-details-template>
<template #preceding-action>
<div class="col-12">
<router-link
to="/interventions"
class="btn btn-outline-secondary btn-sm mb-3"
>
<i class="fas fa-arrow-left me-2"></i>Retour aux interventions
</router-link>
</div>
</template>
<template #intervention-details>
<intervention-details
:intervention="currentIntervention"
@update="handleUpdate"
@cancel="handleCancel"
/>
</template>
</intervention-details-template>
</template>
<script setup>
import { ref } from "vue";
import { RouterLink } from "vue-router";
import InterventionDetailsTemplate from "@/components/templates/Interventions/InterventionDetailsTemplate.vue";
import interventionDetails from "@/components/molecules/Interventions/interventionDetails.vue";
const currentIntervention = ref({
id: 1,
title: "Cérémonie religieuse catholique",
status: {
label: "Confirmé",
color: "success",
variant: "fill",
size: "md",
},
date: "2024-12-15T14:00",
defuntName: "Jean Dupont",
lieux: "Église Saint-Pierre, 75008 Paris",
duree: "1h30",
description:
"Messe funéraire traditionnelle suivie de la bénédiction du corps. Prévoyez environ 80 personnes.",
contactFamilial: "Marie Dupont - 06 12 34 56 78",
coordonneesContact: "01 42 34 56 78 - contact@eglise-stpierre.fr",
nombrePersonnes: 80,
prestationsSupplementaires: "Fleurs, musique d'orgue, livret de cérémonie",
action: {
label: "Mettre à jour",
color: "primary",
},
members: [
{
image: "/images/pretre.jpg",
name: "Père Martin",
},
{
image: "/images/organiste.jpg",
name: "Claire Organiste",
},
],
});
const handleUpdate = (updatedIntervention) => {
console.log("Intervention mise à jour:", updatedIntervention);
currentIntervention.value = updatedIntervention;
};
const handleCancel = () => {
console.log("Édition annulée");
};
</script>

View File

@ -0,0 +1,161 @@
<template>
<div class="card">
<div class="p-3 card-body">
<div class="d-flex">
<div
class="p-2 avatar avatar-xl bg-gradient-dark border-radius-md d-flex align-items-center justify-content-center"
>
<i class="fa fa-user text-white"></i>
</div>
<div class="my-auto ms-3">
<h6>{{ nom }} {{ prenom }}</h6>
<p class="mb-0 text-xs text-secondary">
(e) le: {{ formatDate(date_naissance) }} | Décédé(e) le:
{{ formatDate(date_deces) }}
</p>
<p class="mb-0 text-xs text-secondary">
Lieu de décès: {{ lieu_deces }}
</p>
</div>
<div class="ms-auto">
<div class="dropdown">
<button
id="navbarDropdownMenuLink"
class="btn btn-link text-secondary ps-0 pe-2"
:class="{ show: showMenu }"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
@click="showMenu = !showMenu"
>
<i class="text-lg fa fa-ellipsis-v"></i>
</button>
<div
class="dropdown-menu dropdown-menu-end me-sm-n4 me-n3"
:class="{ show: showMenu }"
aria-labelledby="navbarDropdownMenuLink"
>
<a
v-for="(drop, index) in dropdown"
:key="index"
class="dropdown-item border-radius-md"
:href="drop.route"
@click.prevent="handleDropdownClick(drop.action)"
>
{{ drop.label }}
</a>
</div>
</div>
</div>
</div>
<p class="mt-3 text-sm">
{{ description }}
</p>
<hr class="horizontal dark" />
<div class="row">
<div class="col-6">
<h6 class="mb-0 text-sm">{{ calculateAge }}</h6>
<p class="mb-0 text-sm text-secondary font-weight-bold">
Âge au décès
</p>
</div>
<div class="col-6 text-end">
<h6 class="mb-0 text-sm">{{ formatDate(date_deces) }}</h6>
<p class="mb-0 text-sm text-secondary font-weight-bold">
Date de décès
</p>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from "vue";
import { defineProps, defineEmits } from "vue";
const props = defineProps({
nom: {
type: String,
default: "",
required: true,
},
prenom: {
type: String,
default: "",
},
date_naissance: {
type: String,
default: "",
},
date_deces: {
type: String,
default: "",
},
lieu_deces: {
type: String,
default: "",
},
description: {
type: String,
default: "",
},
dropdown: {
type: Array,
default: () => [],
},
});
const emit = defineEmits(["dropdown-action"]);
const showMenu = ref(false);
// Calcul de l'âge au décès
const calculateAge = computed(() => {
if (!props.date_naissance || !props.date_deces) return "N/A";
const birthDate = new Date(props.date_naissance);
const deathDate = new Date(props.date_deces);
const age = deathDate.getFullYear() - birthDate.getFullYear();
// Ajuster si l'anniversaire n'est pas encore passé dans l'année de décès
const monthDiff = deathDate.getMonth() - birthDate.getMonth();
if (
monthDiff < 0 ||
(monthDiff === 0 && deathDate.getDate() < birthDate.getDate())
) {
return age - 1;
}
return age;
});
// Formatage des dates
const formatDate = (dateString) => {
if (!dateString) return "Non renseignée";
const date = new Date(dateString);
return date.toLocaleDateString("fr-FR", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
};
// Gestion des clics sur le dropdown
const handleDropdownClick = (action) => {
showMenu.value = false;
emit("dropdown-action", action);
};
</script>
<style scoped>
.avatar {
min-width: 48px;
min-height: 48px;
}
.text-xs {
font-size: 0.75rem;
}
</style>

View File

@ -0,0 +1,113 @@
<template>
<div class="mt-4 card">
<div class="p-3 card-body">
<div class="d-flex align-items-center justify-content-between mb-3">
<h6 class="mb-0">{{ title }}</h6>
<SoftBadge
:color="status.color"
:variant="status.variant"
:size="status.size"
>
{{ status.label }}
</SoftBadge>
</div>
<div class="mb-3">
<p class="mb-1"><b>Date :</b> {{ date }}</p>
<p class="mb-1"><b>Nom du défunt :</b> {{ defuntName }}</p>
<p class="mb-1"><b>Lieu :</b> {{ lieux }}</p>
<p class="mb-0"><b>Durée :</b> {{ duree }}</p>
</div>
<!-- eslint-disable-next-line vue/no-v-html -->
<p class="mt-3" v-html="description" />
<hr class="horizontal dark" />
<div class="d-flex align-items-center">
<button
type="button"
class="mb-0 btn btn-sm"
:class="`bg-gradient-${action.color}`"
@click="goToDetail"
>
{{ action.label }}
</button>
<div class="avatar-group ms-auto">
<a
v-for="({ image: memberImage, name }, index) of members"
:key="index"
href="javascript:;"
class="avatar avatar-lg avatar-xs rounded-circle"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
:title="name"
>
<img alt="Image placeholder" :src="memberImage" />
</a>
</div>
</div>
</div>
</div>
</template>
<script setup>
import SoftBadge from "@/components/SoftBadge.vue";
import { defineProps } from "vue";
import { useRouter } from "vue-router";
const router = useRouter();
defineProps({
title: {
type: String,
default: "",
},
status: {
type: Object,
default: () => ({
label: "En attente",
color: "warning",
variant: "fill",
size: "md",
}),
},
date: {
type: String,
default: "",
},
defuntName: {
type: String,
default: "",
},
lieux: {
type: String,
default: "",
},
duree: {
type: String,
default: "",
},
description: {
type: String,
default: "",
},
action: {
type: Object,
default: () => ({
route: "",
color: "primary",
label: "Voir détails",
}),
},
members: {
type: Array,
default: () => [],
},
});
const goToDetail = () => {
router.push({ name: "Intervention details" });
};
</script>

View File

@ -0,0 +1,178 @@
<template>
<div class="row">
<div
v-for="(defunt, index) in defunts"
:key="index"
class="col-xl-4 col-md-6 col-12 mb-4"
>
<defunt-card
:nom="defunt.nom"
:prenom="defunt.prenom"
:date_naissance="defunt.date_naissance"
:date_deces="defunt.date_deces"
:lieu_deces="defunt.lieu_deces"
:description="defunt.description"
:dropdown="dropdownOptions"
@dropdown-action="(action) => handleAction(action, defunt)"
/>
</div>
</div>
</template>
<script setup>
import DefuntCard from "@/components/atoms/Defunts/DefuntCard.vue";
import { ref } from "vue";
// Données d'exemple
const defunts = ref([
{
id: 1,
nom: "Dupont",
prenom: "Jean",
date_naissance: "1950-03-15",
date_deces: "2024-01-10",
lieu_deces: "Hôpital Saint-Louis, Paris 10ème",
description:
"Décédé des suites d'une longue maladie. Souhaitait une cérémonie religieuse catholique. Famille très présente.",
},
{
id: 2,
nom: "Martin",
prenom: "Sophie",
date_naissance: "1965-08-22",
date_deces: "2024-01-08",
lieu_deces: "Domicile, 92 Rue de Rivoli, Paris 4ème",
description:
"Décès naturel à domicile. Cérémonie laïque souhaitée. Environ 50 personnes attendues.",
},
{
id: 3,
nom: "Bernard",
prenom: "Pierre",
date_naissance: "1942-11-30",
date_deces: "2024-01-05",
lieu_deces: "Clinique du Val de Seine, Issy-les-Moulineaux",
description:
"Ancien militaire, décédé des suites d'un cancer. Demande d'honneurs militaires. Cérémonie au crématorium.",
},
{
id: 4,
nom: "Moreau",
prenom: "Marie",
date_naissance: "1938-07-14",
date_deces: "2024-01-03",
lieu_deces: "EHPAD Les Jardins Fleuris, Vincennes",
description:
"Décédée paisiblement à l'EHPAD. Cérémonie religieuse à l'église Saint-Louis de Vincennes. Famille nombreuse.",
},
{
id: 5,
nom: "Leroy",
prenom: "Philippe",
date_naissance: "1972-12-05",
date_deces: "2024-01-01",
lieu_deces: "Centre Hospitalier Universitaire, Créteil",
description:
"Décès accidentel. Jeune famille endeuillée. Cérémonie intime souhaitée. Crémation prévue.",
},
{
id: 6,
nom: "Petit",
prenom: "Claire",
date_naissance: "1980-04-18",
date_deces: "2023-12-28",
lieu_deces: "Hôpital Necker, Paris 15ème",
description:
"Décédée après une courte maladie. Professeure de musique. Cérémonie avec prestation musicale des élèves.",
},
{
id: 7,
nom: "Roux",
prenom: "Antoine",
date_naissance: "1955-09-12",
date_deces: "2023-12-25",
lieu_deces: "Maison de retraite Les Tilleuls, Sceaux",
description:
"Ancien artisan ébéniste. Décès pendant la nuit de Noël. Cérémonie au cimetière du Père Lachaise.",
},
{
id: 8,
nom: "Garcia",
prenom: "Elena",
date_naissance: "1968-02-28",
date_deces: "2023-12-20",
lieu_deces: "Hôpital Européen Georges Pompidou, Paris",
description:
"D'origine espagnole. Décédée des suites d'une opération. Double cérémonie française et espagnole prévue.",
},
{
id: 9,
nom: "Fournier",
prenom: "Michel",
date_naissance: "1948-06-08",
date_deces: "2023-12-18",
lieu_deces: "Centre de Soins Palliatifs, Boulogne-Billancourt",
description:
"Ancien chef d'entreprise. Décès après une longue maladie. Cérémonie civile au funérarium.",
},
]);
// Gestion des actions du dropdown
const handleAction = (action, defunt) => {
switch (action) {
case "edit":
console.log("Modifier le défunt:", defunt);
// Ouvrir modal d'édition
break;
case "view":
console.log("Voir les détails:", defunt);
// Naviguer vers la page détail
break;
case "create_intervention":
console.log("Créer une intervention pour:", defunt);
// Ouvrir wizard de création d'intervention
break;
case "delete":
console.log("Supprimer le défunt:", defunt);
// Confirmer la suppression
if (
confirm(
`Êtes-vous sûr de vouloir supprimer ${defunt.prenom} ${defunt.nom} ?`
)
) {
defunts.value = defunts.value.filter((d) => d.id !== defunt.id);
}
break;
}
};
// Fonction pour ajouter un nouveau défunt (exemple)
const ajouterDefunt = () => {
const nouveauDefunt = {
id: defunts.value.length + 1,
nom: "Nouveau",
prenom: "Défunt",
date_naissance: "1950-01-01",
date_deces: "2024-01-15",
lieu_deces: "Lieu à définir",
description: "Description à compléter",
};
defunts.value.unshift(nouveauDefunt);
};
</script>
<style scoped>
.page-link {
border: none;
margin: 0 2px;
border-radius: 8px;
}
.page-item.active .page-link {
background-color: #cb0c9f;
border-color: #cb0c9f;
}
.pagination {
gap: 4px;
}
</style>

View File

@ -0,0 +1,298 @@
<template>
<div class="mt-4 card">
<div class="p-3 card-body">
<!-- En-tête avec titre et badge de statut -->
<div class="d-flex align-items-center justify-content-between mb-4">
<h5 class="mb-0">Détails de l'Intervention</h5>
<SoftBadge
:color="intervention.status.color"
:variant="intervention.status.variant"
:size="intervention.status.size"
>
{{ intervention.status.label }}
</SoftBadge>
</div>
<!-- Informations Client -->
<div class="mb-4">
<div class="d-flex align-items-center justify-content-between mb-3">
<h6 class="mb-0">Informations Client</h6>
<button
type="button"
class="btn btn-sm bg-gradient-secondary"
@click="toggleEditMode"
>
{{ editMode ? "Sauvegarder" : "Modifier" }}
</button>
</div>
<div class="row">
<!-- Colonne gauche -->
<div class="col-md-6">
<SoftInput
label="Nom du défunt"
v-model="localIntervention.defuntName"
:disabled="!editMode"
class="mb-3"
/>
<SoftInput
label="Date de l'intervention"
type="datetime-local"
v-model="localIntervention.date"
:disabled="!editMode"
class="mb-3"
/>
<SoftInput
label="Lieu"
v-model="localIntervention.lieux"
:disabled="!editMode"
class="mb-3"
/>
</div>
<!-- Colonne droite -->
<div class="col-md-6">
<SoftInput
label="Durée prévue"
v-model="localIntervention.duree"
:disabled="!editMode"
class="mb-3"
/>
<SoftInput
label="Type de cérémonie"
v-model="localIntervention.title"
:disabled="!editMode"
class="mb-3"
/>
<SoftInput
label="Contact familial"
v-model="localIntervention.contactFamilial"
:disabled="!editMode"
class="mb-3"
/>
</div>
</div>
</div>
<!-- Description -->
<div class="mb-4">
<h6 class="mb-3">Description</h6>
<SoftInput
type="textarea"
rows="3"
v-model="localIntervention.description"
:disabled="!editMode"
placeholder="Description détaillée de l'intervention..."
/>
</div>
<hr class="horizontal dark" />
<!-- Informations supplémentaires -->
<div class="mb-4">
<h6 class="mb-3">Informations Complémentaires</h6>
<div class="row">
<div class="col-md-6">
<SoftInput
label="Nombre de personnes attendues"
type="number"
v-model="localIntervention.nombrePersonnes"
:disabled="!editMode"
class="mb-3"
/>
<SoftInput
label="Coordonnées du contact"
v-model="localIntervention.coordonneesContact"
:disabled="!editMode"
class="mb-3"
/>
</div>
<div class="col-md-6">
<SoftInput
label="Prestations supplémentaires"
type="textarea"
rows="2"
v-model="localIntervention.prestationsSupplementaires"
:disabled="!editMode"
class="mb-3"
/>
</div>
</div>
</div>
<!-- Équipe assignée -->
<div class="mb-4">
<div class="d-flex align-items-center justify-content-between mb-3">
<h6 class="mb-0">Équipe Assignée</h6>
<button
type="button"
class="btn btn-sm bg-gradient-info"
@click="showTeamModal = true"
>
Gérer l'équipe
</button>
</div>
<div class="avatar-group">
<a
v-for="(member, index) in localIntervention.members"
:key="index"
href="javascript:;"
class="avatar avatar-sm rounded-circle"
data-bs-toggle="tooltip"
data-bs-placement="bottom"
:title="member.name"
>
<img alt="Image placeholder" :src="member.image" />
</a>
</div>
</div>
<hr class="horizontal dark" />
<!-- Actions -->
<div class="d-flex justify-content-between">
<button
type="button"
class="btn btn-sm bg-gradient-danger"
@click="$emit('cancel')"
>
Annuler
</button>
<div>
<button
type="button"
class="btn btn-sm bg-gradient-secondary me-2"
@click="resetChanges"
:disabled="!hasChanges"
>
Réinitialiser
</button>
<button
type="button"
class="btn btn-sm"
:class="`bg-gradient-${intervention.action.color}`"
@click="saveChanges"
:disabled="!hasChanges"
>
{{ intervention.action.label }}
</button>
</div>
</div>
</div>
</div>
<!-- Modal pour gérer l'équipe -->
<div
v-if="showTeamModal"
class="modal fade show"
style="display: block"
tabindex="-1"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Gérer l'équipe</h5>
<button
type="button"
class="btn-close"
@click="showTeamModal = false"
></button>
</div>
<div class="modal-body">
<p>Interface de gestion de l'équipe à implémenter...</p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-sm bg-gradient-secondary"
@click="showTeamModal = false"
>
Fermer
</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, watch, defineProps, defineEmits } from "vue";
import SoftInput from "@/components/SoftInput.vue";
import SoftBadge from "@/components/SoftBadge.vue";
const props = defineProps({
intervention: {
type: Object,
default: () => ({}),
},
});
const emit = defineEmits(["update", "cancel"]);
// État local pour l'édition
const editMode = ref(false);
const showTeamModal = ref(false);
const localIntervention = ref({ ...props.intervention });
// Computed pour détecter les changements
const hasChanges = computed(() => {
return (
JSON.stringify(localIntervention.value) !==
JSON.stringify(props.intervention)
);
});
// Méthodes
const toggleEditMode = () => {
if (editMode.value) {
saveChanges();
}
editMode.value = !editMode.value;
};
const saveChanges = () => {
emit("update", localIntervention.value);
editMode.value = false;
};
const resetChanges = () => {
localIntervention.value = { ...props.intervention };
};
// Watch pour mettre à jour les données locales quand les props changent
watch(
() => props.intervention,
(newVal) => {
localIntervention.value = { ...newVal };
},
{ deep: true }
);
</script>
<style scoped>
.avatar-group {
display: flex;
gap: 8px;
}
.avatar-sm {
width: 32px;
height: 32px;
}
.modal {
background-color: rgba(0, 0, 0, 0.5);
}
.modal.show {
display: block;
}
</style>

View File

@ -0,0 +1,187 @@
<template>
<div class="intervention-list">
<div class="row">
<div
v-for="(intervention, index) in interventions"
:key="index"
class="col-lg-4 col-md-6 col-12 mb-4"
>
<card-interventions
:title="intervention.title"
:status="intervention.status"
:date="intervention.date"
:defunt-name="intervention.defuntName"
:lieux="intervention.lieux"
:duree="intervention.duree"
:description="intervention.description"
:action="intervention.action"
:members="intervention.members"
/>
</div>
</div>
<!-- Message si aucune intervention -->
<div v-if="interventions.length === 0" class="text-center py-5">
<p class="text-muted">Aucune intervention planifiée</p>
</div>
</div>
</template>
<script setup>
import CardInterventions from "@/components/atoms/Interventions/CardInterventions.vue";
import { defineProps } from "vue";
// Exemple de données
const interventions = [
{
title: "Cérémonie religieuse",
status: {
label: "Confirmé",
color: "success",
variant: "fill",
size: "md",
},
date: "15 Décembre 2024 - 14:00",
defuntName: "Jean Dupont",
lieux: "Église Saint-Pierre, Paris",
duree: "1h30",
description:
"Cérémonie religieuse traditionnelle suivie d'une bénédiction.",
action: {
label: "Voir détails",
color: "primary",
},
members: [
{
image: "/images/avatar1.jpg",
name: "Marie Curie",
},
{
image: "/images/avatar2.jpg",
name: "Pierre Durand",
},
],
},
{
title: "Crémation",
status: {
label: "En attente",
color: "warning",
variant: "fill",
size: "md",
},
date: "16 Décembre 2024 - 10:00",
defuntName: "Sophie Martin",
lieux: "Crématorium de Lyon",
duree: "45 minutes",
description: "Cérémonie de crémation avec discours des proches.",
action: {
label: "Modifier",
color: "info",
},
members: [
{
image: "/images/avatar3.jpg",
name: "Luc Bernard",
},
],
},
{
title: "Inhumation",
status: {
label: "Annulé",
color: "danger",
variant: "fill",
size: "md",
},
date: "17 Décembre 2024 - 11:00",
defuntName: "Paul Lefebvre",
lieux: "Cimetière du Père Lachaise, Paris",
duree: "2 heures",
description: "Inhumation suivie d'une réception familiale.",
action: {
label: "Voir raisons",
color: "secondary",
},
members: [
{
image: "/images/avatar4.jpg",
name: "Alice Moreau",
},
{
image: "/images/avatar5.jpg",
name: "Robert Petit",
},
{
image: "/images/avatar6.jpg",
name: "Claire Blanc",
},
],
},
{
title: "Cérémonie laïque",
status: {
label: "Planifié",
color: "info",
variant: "gradient",
size: "md",
},
date: "18 Décembre 2024 - 15:30",
defuntName: "Michelle Rousseau",
lieux: "Salle des fêtes, Marseille",
duree: "1 heure",
description: "Cérémonie laïque avec partage de souvenirs et musique.",
action: {
label: "Préparer",
color: "success",
},
members: [
{
image: "/images/avatar7.jpg",
name: "Thomas Leroy",
},
{
image: "/images/avatar8.jpg",
name: "Isabelle Marchand",
},
],
},
{
title: "Transport funéraire",
status: {
label: "Terminé",
color: "dark",
variant: "fill",
size: "sm",
},
date: "14 Décembre 2024 - 09:00",
defuntName: "Henri Garnier",
lieux: "De l'hôpital au funérarium",
duree: "30 minutes",
description: "Transport du défunt vers le funérarium.",
action: {
label: "Voir rapport",
color: "dark",
},
members: [
{
image: "/images/avatar9.jpg",
name: "David Morel",
},
],
},
];
// Props optionnelles pour permettre le passage de données externes
defineProps({
interventionData: {
type: Array,
default: () => [],
},
});
</script>
<style scoped>
.intervention-list {
padding: 20px 0;
}
</style>

View File

@ -1,205 +0,0 @@
<template>
<div class="row">
<div class="col-12 mb-4">
<div class="card">
<div class="card-header pb-0">
<div class="d-flex align-items-center">
<p class="font-weight-bold mb-0">Vue d'ensemble</p>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-xl-6 col-lg-6 col-md-6 mb-xl-0">
<div class="card card-profile-card">
<div class="card-body">
<h6 class="mb-0 font-weight-bold text-sm">
Informations Personnelles
</h6>
<div class="mt-3">
<div class="d-flex align-items-center mb-2">
<span class="text-xs text-secondary text-uppercase"
>Nom complet</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.employee?.full_name || "N/A" }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Email</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.employee?.email || "N/A" }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Téléphone</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.employee?.phone || "N/A" }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Poste</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.employee?.job_title || "N/A" }}
</p>
</div>
</div>
</div>
</div>
<div class="col-xl-6 col-lg-6 col-md-6">
<div class="card card-profile-card">
<div class="card-body">
<h6 class="mb-0 font-weight-bold text-sm">
Informations Professionnelles
</h6>
<div class="mt-3">
<div class="d-flex align-items-center mb-2">
<span class="text-xs text-secondary text-uppercase"
>Numéro de Diplôme</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.diploma_number || "N/A" }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Date du Diplôme</span
>
</div>
<p class="text-dark text-sm">
{{ formatDate(thanatopractitioner.diploma_date) }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Numéro d'Autorisation</span
>
</div>
<p class="text-dark text-sm">
{{ thanatopractitioner.authorization_number || "N/A" }}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Date d'Émission</span
>
</div>
<p class="text-dark text-sm">
{{
formatDate(thanatopractitioner.authorization_issue_date)
}}
</p>
<div class="d-flex align-items-center mb-2 mt-3">
<span class="text-xs text-secondary text-uppercase"
>Date d'Expiration</span
>
</div>
<p class="text-dark text-sm">
{{
formatDate(
thanatopractitioner.authorization_expiry_date
)
}}
</p>
</div>
</div>
</div>
</div>
</div>
<div class="row mt-4">
<div class="col-12">
<div class="card card-profile-card">
<div class="card-body">
<h6 class="mb-0 font-weight-bold text-sm">
Statut et Créé le
</h6>
<div class="mt-3">
<div class="d-flex align-items-center">
<div
class="badge me-3"
:class="{
'bg-success': thanatopractitioner.active,
'bg-danger': !thanatopractitioner.active
}"
>
<i
:class="{
'fas fa-check-circle me-1': thanatopractitioner.active,
'fas fa-times-circle me-1': !thanatopractitioner.active
}"
></i>
{{ thanatopractitioner.active ? "Actif" : "Inactif" }}
</div>
<div class="text-xs text-secondary">
Créé le {{ formattedDate }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { defineProps } from "vue";
defineProps({
thanatopractitioner: {
type: Object,
required: true,
},
formattedDate: {
type: String,
default: "N/A",
},
thanatopractitionerId: {
type: [Number, String],
required: true,
},
});
const formatDate = (dateString) => {
if (!dateString) return "N/A";
const date = new Date(dateString);
return date.toLocaleDateString("fr-FR");
};
</script>
<style scoped>
.card-profile-card {
border: 0;
box-shadow: 0 0 2rem 0 rgba(136, 152, 170, 0.15);
border-radius: 0.5rem;
}
.text-xs {
font-size: 0.75rem;
}
.text-sm {
font-size: 0.875rem;
}
.font-weight-bold {
font-weight: 600;
}
</style>

View File

@ -1,76 +0,0 @@
<template>
<div class="card-body text-center">
<!-- Client Avatar -->
<ClientAvatar
:avatar-url="avatarUrl"
:initials="initials"
:alt="thanatopractitionerName"
:editable="true"
@edit="$emit('edit-avatar')"
/>
<!-- Client Name -->
<h5 class="font-weight-bolder mb-0">
{{ thanatopractitionerName }}
</h5>
<p class="text-sm text-secondary mb-3">
{{ thanatopractitionerType }}
</p>
<!-- Quick Stats -->
<div class="row text-center mt-3">
<div class="col-6 border-end">
<h6 class="text-sm font-weight-bolder mb-0">
<i
class="fas"
:class="
isActive
? 'fa-check-circle text-success'
: 'fa-times-circle text-danger'
"
></i>
</h6>
<p class="text-xs text-secondary mb-0">Statut</p>
</div>
<div class="col-6">
<h6 class="text-sm font-weight-bolder mb-0">
{{ diplomaNumber || 'N/A' }}
</h6>
<p class="text-xs text-secondary mb-0">Diplôme</p>
</div>
</div>
</div>
</template>
<script setup>
import ClientAvatar from "@/components/atoms/client/ClientAvatar.vue";
import { defineProps, defineEmits } from "vue";
defineProps({
avatarUrl: {
type: String,
default: null,
},
initials: {
type: String,
required: true,
},
thanatopractitionerName: {
type: String,
required: true,
},
thanatopractitionerType: {
type: String,
default: "Thanatopractitioner",
},
isActive: {
type: Boolean,
default: true,
},
diplomaNumber: {
type: String,
default: null,
},
});
defineEmits(["edit-avatar"]);
</script>

View File

@ -0,0 +1,3 @@
<template>
<h1>Defunt Details</h1>
</template>

View File

@ -2,19 +2,19 @@
<div class="container-fluid py-4">
<div class="d-sm-flex justify-content-between">
<div>
<slot name="employee-new-action"></slot>
<slot name="defunt-new-action"></slot>
</div>
<div class="d-flex">
<div class="dropdown d-inline">
<slot name="select-filter"></slot>
</div>
<slot name="employee-other-action"></slot>
<slot name="defunt-other-action"></slot>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card mt-4">
<slot name="employee-table"></slot>
<div class="mt-4">
<slot name="defunt-table"></slot>
</div>
</div>
</div>

View File

@ -0,0 +1,16 @@
<template>
<div class="container-fluid py-4">
<div class="d-sm-flex justify-content-between">
<div>
<slot name="preceding-action"></slot>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card mt-4">
<slot name="intervention-details"></slot>
</div>
</div>
</div>
</div>
</template>

View File

@ -0,0 +1,23 @@
<template>
<div class="container-fluid py-4">
<div class="d-sm-flex justify-content-between">
<div>
<slot name="intervention-new-action"></slot>
</div>
<div class="d-flex">
<div class="dropdown d-inline">
<slot name="select-filter"></slot>
</div>
<slot name="intervention-other-action"></slot>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="">
<slot name="intervention-table"></slot>
</div>
</div>
</div>
</div>
</template>
<script></script>

View File

@ -1,7 +1,7 @@
<template>
<div class="messenger-configurator">
<!-- Floating Action Button -->
<div class="fab-container" @click="toggle">
<div class="fab-container" @click="togglePanel">
<div class="fab">
<i class="fas fa-robot"></i>
</div>
@ -19,7 +19,7 @@
<p>En ligne</p>
</div>
<div class="header-actions">
<button class="btn-icon" @click="toggle">
<button class="btn-icon" @click="togglePanel">
<i class="fas fa-times"></i>
</button>
</div>
@ -200,90 +200,96 @@
</div>
</template>
<script>
export default {
name: "MessengerConfigurator",
props: {
toggle: {
type: Function,
default: null,
},
},
data() {
return {
isOpen: false,
personality: "professional",
language: "fr",
responseLength: "medium",
userMessage: "",
hasSelections: false,
};
},
computed: {
getPersonalityText() {
const personalities = {
professional: "Professionnel",
friendly: "Amical",
technical: "Technique",
};
return personalities[this.personality];
},
getLanguageText() {
return this.language === "fr" ? "Français" : "English";
},
getResponseLengthText() {
const lengths = {
short: "Court",
medium: "Moyen",
detailed: "Détaillé",
};
return lengths[this.responseLength];
},
},
methods: {
toggle() {
this.isOpen = !this.isOpen;
if (this.toggle) {
this.toggle();
}
},
setPersonality(type) {
this.personality = type;
this.hasSelections = true;
},
setLanguage(lang) {
this.language = lang;
this.hasSelections = true;
},
setResponseLength(length) {
this.responseLength = length;
this.hasSelections = true;
},
saveConfiguration() {
// Save configuration logic
this.$store.dispatch("saveAIAssistantConfig", {
personality: this.personality,
language: this.language,
responseLength: this.responseLength,
});
<script setup>
import { ref, computed } from "vue";
import { defineProps } from "vue";
// Show success message
alert("Configuration enregistrée avec succès !");
},
resetToDefault() {
this.personality = "professional";
this.language = "fr";
this.responseLength = "medium";
this.hasSelections = false;
},
sendMessage() {
if (this.userMessage.trim()) {
// Handle user message
console.log("User message:", this.userMessage);
this.userMessage = "";
}
},
const props = defineProps({
toggle: {
type: Function,
default: null,
},
});
// Reactive data
const isOpen = ref(false);
const personality = ref("professional");
const language = ref("fr");
const responseLength = ref("medium");
const userMessage = ref("");
const hasSelections = ref(false);
// Computed properties
const getPersonalityText = computed(() => {
const personalities = {
professional: "Professionnel",
friendly: "Amical",
technical: "Technique",
};
return personalities[personality.value];
});
const getLanguageText = computed(() => {
return language.value === "fr" ? "Français" : "English";
});
const getResponseLengthText = computed(() => {
const lengths = {
short: "Court",
medium: "Moyen",
detailed: "Détaillé",
};
return lengths[responseLength.value];
});
// Methods
const togglePanel = () => {
isOpen.value = !isOpen.value;
if (props.toggle) {
props.toggle();
}
};
const setPersonality = (type) => {
personality.value = type;
hasSelections.value = true;
};
const setLanguage = (lang) => {
language.value = lang;
hasSelections.value = true;
};
const setResponseLength = (length) => {
responseLength.value = length;
hasSelections.value = true;
};
const saveConfiguration = () => {
// Save configuration logic
// this.$store.dispatch("saveAIAssistantConfig", {
// personality: this.personality,
// language: this.language,
// responseLength: this.responseLength,
// })
// Show success message
alert("Configuration enregistrée avec succès !");
};
const resetToDefault = () => {
personality.value = "professional";
language.value = "fr";
responseLength.value = "medium";
hasSelections.value = false;
};
const sendMessage = () => {
if (userMessage.value.trim()) {
// Handle user message
console.log("User message:", userMessage.value);
userMessage.value = "";
}
};
</script>

View File

@ -135,6 +135,22 @@ export default {
miniIcon: "C",
route: { name: "Gestion contacts" },
},
{
id: "interventions",
type: "single",
text: "Interventions",
icon: "Office",
miniIcon: "I",
route: { name: "Interventions" },
},
{
id: "Defunts",
type: "single",
text: "Defunts",
icon: "Office",
miniIcon: "I",
route: { name: "Defunts" },
},
{
id: "gestion-section",
type: "section-header",

View File

@ -569,6 +569,22 @@ const routes = [
"@/views/pages/Thanatopractitioners/ThanatopractitionerDetails.vue"
),
},
{
path: "/interventions",
name: "Interventions",
component: () => import("@/views/pages/Interventions/Interventions.vue"),
},
{
path: "/intervention",
name: "Intervention details",
component: () =>
import("@/views/pages/Interventions/InterventionDetails.vue"),
},
{
path: "/defunts",
name: "Defunts",
component: () => import("@/views/pages/Defunts/ListeDefunts.vue"),
},
// Paramétrage
{
path: "/parametrage/droits",

View File

@ -0,0 +1,6 @@
<template>
<defunt-presentation />
</template>
<script setup>
import DefuntPresentation from "@/components/Organism/Defunts/DefuntPresentation.vue";
</script>

View File

@ -0,0 +1,6 @@
<template>
<intervention-details-presentation />
</template>
<script setup>
import interventionDetailsPresentation from "@/components/Organism/Interventions/interventionDetailsPresentation.vue";
</script>

View File

@ -0,0 +1,6 @@
<template>
<intervention-presentation />
</template>
<script setup>
import InterventionPresentation from "@/components/Organism/Interventions/InterventionPresentation.vue";
</script>