152 lines
7.6 KiB
Vue
152 lines
7.6 KiB
Vue
<script setup>
|
|
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
|
|
import { Head, Link } from '@inertiajs/vue3'
|
|
|
|
const props = defineProps({
|
|
asset: Object,
|
|
})
|
|
|
|
function formatDate(d) {
|
|
if (!d) return '—'
|
|
return new Intl.DateTimeFormat('fr-FR').format(new Date(d))
|
|
}
|
|
|
|
const statutLabels = {
|
|
en_service: 'En service',
|
|
hors_service: 'Hors service',
|
|
en_reparation: 'En réparation',
|
|
stock: 'En stock',
|
|
}
|
|
|
|
const statutColors = {
|
|
en_service: 'bg-green-100 text-green-800',
|
|
hors_service: 'bg-red-100 text-red-800',
|
|
en_reparation: 'bg-orange-100 text-orange-800',
|
|
stock: 'bg-blue-100 text-blue-800',
|
|
}
|
|
|
|
function checkWarranty(date) {
|
|
if (!date) return 'text-gray-400'
|
|
const today = new Date()
|
|
const exp = new Date(date)
|
|
if (exp < today) return 'text-red-600 font-bold'
|
|
const diff = (exp - today) / (1000 * 60 * 60 * 24)
|
|
if (diff <= 30) return 'text-orange-600 font-bold'
|
|
return 'text-gray-600'
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<Head :title="asset.nom" />
|
|
<AuthenticatedLayout>
|
|
<template #header>
|
|
<div class="flex items-center justify-between">
|
|
<div class="flex items-center gap-3">
|
|
<Link :href="route('assets.index')" class="text-gray-400 hover:text-gray-600 transition-colors">
|
|
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
|
</svg>
|
|
</Link>
|
|
<div>
|
|
<h1 class="text-xl font-semibold text-gray-900">{{ asset.nom }}</h1>
|
|
<p class="text-sm text-gray-500">{{ asset.type }} - {{ asset.marque }} {{ asset.modele }}</p>
|
|
</div>
|
|
</div>
|
|
<!-- Action Buttons: Edit -->
|
|
<Link :href="route('assets.edit', asset.id)"
|
|
class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 transition-colors">
|
|
Modifier
|
|
</Link>
|
|
</div>
|
|
</template>
|
|
|
|
<div class="grid gap-6 lg:grid-cols-3">
|
|
<div class="space-y-6 lg:col-span-2">
|
|
<!-- Informations de base -->
|
|
<div class="rounded-xl bg-white p-6 shadow-sm border border-gray-100">
|
|
<h2 class="mb-5 text-sm font-semibold uppercase tracking-wide text-gray-500">Détails du matériel</h2>
|
|
<div class="grid gap-4 sm:grid-cols-2">
|
|
<div>
|
|
<p class="text-xs text-gray-500">Nom / Hostname</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ asset.nom }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500">Type de matériel</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ asset.type }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500">Marque & Modèle</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ asset.marque || '—' }} {{ asset.modele || '' }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500">Code EAN/UPC</p>
|
|
<p class="mt-0.5 font-mono text-sm text-gray-900">{{ asset.code_ean || '—' }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500 font-bold">Numéro de série / SN</p>
|
|
<p class="mt-0.5 font-mono text-sm text-gray-900">{{ asset.numero_serie || '—' }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500 border-t pt-4 mt-2">Statut actuel</p>
|
|
<span :class="['mt-2 inline-block px-2 py-0.5 rounded-full text-xs font-medium', statutColors[asset.statut]]">
|
|
{{ statutLabels[asset.statut] }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes / Config -->
|
|
<div v-if="asset.notes" class="rounded-xl bg-white p-6 shadow-sm border border-gray-100">
|
|
<h2 class="mb-4 text-sm font-semibold uppercase tracking-wide text-gray-500">Notes & Configuration</h2>
|
|
<div class="whitespace-pre-wrap text-sm text-gray-700">{{ asset.notes }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-6 lg:col-span-1">
|
|
<!-- Localisation -->
|
|
<div class="rounded-xl bg-white p-6 shadow-sm border border-gray-100">
|
|
<h2 class="mb-4 text-sm font-semibold uppercase tracking-wide text-gray-500">Localisation</h2>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<p class="text-xs text-gray-500">Ville / Commune</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ asset.commune?.nom || 'Infrastructure Globale (Agglo)' }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500">Emplacement précis</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ asset.emplacement || '—' }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Cycle de vie & Garantie -->
|
|
<div class="rounded-xl bg-white p-6 shadow-sm border border-gray-100">
|
|
<h2 class="mb-4 text-sm font-semibold uppercase tracking-wide text-gray-500">Cycle de vie</h2>
|
|
<div class="space-y-4">
|
|
<div>
|
|
<p class="text-xs text-gray-500">Date d'achat</p>
|
|
<p class="mt-0.5 font-medium text-gray-900">{{ formatDate(asset.date_achat) }}</p>
|
|
</div>
|
|
<div>
|
|
<p class="text-xs text-gray-500">Fin de garantie (constructeur)</p>
|
|
<p class="mt-0.5 font-medium" :class="checkWarranty(asset.date_fin_garantie)">
|
|
{{ formatDate(asset.date_fin_garantie) }}
|
|
<span v-if="checkWarranty(asset.date_fin_garantie).includes('red')" class="ml-1" title="Expirée">⚠️ Expirée</span>
|
|
<span v-else-if="checkWarranty(asset.date_fin_garantie).includes('orange')" class="ml-1" title="Proche échéance">⏳ À renouveler</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Commande associée -->
|
|
<div v-if="asset.commande" class="rounded-xl bg-white p-6 shadow-sm border border-gray-100">
|
|
<h2 class="mb-4 text-sm font-semibold uppercase tracking-wide text-gray-500">Commande associée</h2>
|
|
<Link :href="route('commandes.show', asset.commande.id)" class="block rounded-lg border border-gray-100 bg-gray-50 p-4 hover:bg-gray-100 transition-colors">
|
|
<div class="font-medium text-indigo-600">{{ asset.commande.numero_commande }}</div>
|
|
<div class="mt-1 text-xs text-gray-600">{{ asset.commande.objet }}</div>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</AuthenticatedLayout>
|
|
</template>
|