New-Thanasoft/thanasoft-front/src/components/Organism/CRM/FournisseurDetailPresentation.vue
2026-01-28 15:36:37 +03:00

207 lines
5.2 KiB
Vue

<template>
<fournisseur-detail-template>
<template #button-return>
<div class="col-12">
<router-link
to="/fournisseurs"
class="btn btn-outline-secondary btn-sm mb-3"
>
<i class="fas fa-arrow-left me-2"></i>Retour aux fournisseurs
</router-link>
</div>
</template>
<template #loading-state>
<div v-if="isLoading" class="text-center p-5">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Chargement...</span>
</div>
</div>
</template>
<template #fournisseur-detail-sidebar>
<FournisseurDetailSidebar
:avatar-url="fournisseurAvatar"
:initials="getInitials(fournisseur.name)"
:fournisseur-name="fournisseur.name"
:fournisseur-type="fournisseur.type_label || 'Fournisseur'"
:contacts-count="filteredContactsCount"
:locations-count="locations.length"
:is-active="fournisseur.is_active"
:active-tab="activeTab"
@edit-avatar="triggerFileInput"
@change-tab="activeTab = $event"
/>
</template>
<template #file-input>
<input
:ref="fileInput"
type="file"
class="d-none"
accept="image/*"
@change="handleAvatarUpload"
/>
</template>
<template #fournisseur-detail-content>
<fournisseur-detail-content
:active-tab="activeTab"
:fournisseur="fournisseur"
:locations="locations"
:formatted-address="formatAddress(fournisseur)"
:fournisseur-id="fournisseur.id"
:contact-is-loading="contactLoading"
:location-is-loading="locationLoading"
@change-tab="activeTab = $event"
@updating-fournisseur="handleUpdateFournisseur"
@create-contact="handleAddContact"
@updating-contact="handleModifiedContact"
@contact-removed="handleRemovedContact"
@create-location="handleAddLocation"
@modify-location="handleModifyLocation"
@remove-location="handleRemoveLocation"
/>
</template>
</fournisseur-detail-template>
</template>
<script setup>
import { defineProps, defineEmits, ref, computed } from "vue";
import { useContactStore } from "@/stores/contactStore";
import FournisseurDetailTemplate from "@/components/templates/CRM/FournisseurDetailTemplate.vue";
import FournisseurDetailSidebar from "./fournisseur/FournisseurDetailSidebar.vue";
import FournisseurDetailContent from "./fournisseur/FournisseurDetailContent.vue";
import { RouterLink } from "vue-router";
const props = defineProps({
fournisseur: {
type: Object,
required: true,
},
locations: {
type: Array,
required: false,
default: () => [],
},
isLoading: {
type: Boolean,
default: false,
},
contactIsLoading: {
type: Boolean,
default: false,
},
fournisseurAvatar: {
type: String,
default: "",
},
activeTab: {
type: String,
default: "overview",
},
fileInput: {
type: Object,
required: true,
},
contactLoading: {
type: Boolean,
default: false,
},
locationLoading: {
type: Boolean,
default: false,
},
});
// Use contact store to get filtered contacts count
const contactStore = useContactStore();
const filteredContactsCount = computed(() => {
return contactStore.contacts.filter(
(contact) => contact.fournisseur_id === props.fournisseur.id
).length;
});
const localAvatar = ref(props.fournisseurAvatar);
const emit = defineEmits([
"updateTheFournisseur",
"handleFileInput",
"add-new-contact",
"updating-contact",
"contact-removed",
"add-new-location",
"modify-location",
"remove-location",
]);
const handleAvatarUpload = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
localAvatar.value = e.target.result;
// TODO: Upload to server
console.log("Upload avatar to server");
};
reader.readAsDataURL(file);
}
};
const handleUpdateFournisseur = (updateData) => {
emit("updateTheFournisseur", updateData);
};
const inputFile = () => {
emit("handleFileInput");
};
const handleAddContact = (data) => {
emit("add-new-contact", data);
};
const handleModifiedContact = (modifiedContact) => {
emit("updating-contact", modifiedContact);
};
const handleRemovedContact = (contactId) => {
emit("contact-removed", contactId);
};
const handleAddLocation = (data) => {
emit("add-new-location", data);
};
const handleModifyLocation = (location) => {
emit("modify-location", location);
};
const handleRemoveLocation = (locationId) => {
emit("remove-location", locationId);
};
const getInitials = (name) => {
if (!name) return "?";
return name
.split(" ")
.map((word) => word[0])
.join("")
.toUpperCase()
.substring(0, 2);
};
const formatAddress = (fournisseur) => {
const parts = [
fournisseur.billing_address.line1,
fournisseur.billing_address.line2,
fournisseur.billing_address.postal_code,
fournisseur.billing_address.city,
fournisseur.billing_address.country_code,
].filter(Boolean);
return parts.length > 0 ? parts.join(", ") : "Aucune adresse renseignée";
};
const triggerFileInput = () => {
if (props.fileInput) {
props.fileInput.click();
}
};
</script>