initial commit
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
<script setup>
|
||||
import SupervisorLayout from '@/Layouts/SupervisorLayout.vue';
|
||||
import { Head, Link } from '@inertiajs/vue3';
|
||||
|
||||
defineProps({
|
||||
kpis: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
alerts: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
machinesOverview: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const formatCurrency = (value) =>
|
||||
new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(value ?? 0);
|
||||
|
||||
const formatDate = (iso) => {
|
||||
if (!iso) return '—';
|
||||
return new Intl.DateTimeFormat('fr-FR', {
|
||||
dateStyle: 'short',
|
||||
timeStyle: 'short',
|
||||
}).format(new Date(iso));
|
||||
};
|
||||
|
||||
const statusColor = (status) => {
|
||||
const colors = {
|
||||
available: 'bg-green-100 text-green-800',
|
||||
reserved: 'bg-yellow-100 text-yellow-800',
|
||||
running: 'bg-blue-100 text-blue-800',
|
||||
maintenance: 'bg-orange-100 text-orange-800',
|
||||
offline: 'bg-gray-100 text-gray-800',
|
||||
error: 'bg-red-100 text-red-800',
|
||||
};
|
||||
return colors[status] ?? 'bg-gray-100 text-gray-800';
|
||||
};
|
||||
|
||||
const severityColor = (severity) => {
|
||||
return severity === 'high' ? 'border-red-400 bg-red-50' : 'border-yellow-400 bg-yellow-50';
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Head title="Tableau de bord" />
|
||||
|
||||
<SupervisorLayout title="Tableau de bord">
|
||||
<!-- KPI cards -->
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4">
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<p class="text-sm font-medium text-gray-500">Chiffre d'affaires aujourd'hui</p>
|
||||
<p class="mt-2 text-2xl font-bold text-gray-900">
|
||||
{{ formatCurrency(kpis.revenue_today) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<p class="text-sm font-medium text-gray-500">Lavages aujourd'hui</p>
|
||||
<p class="mt-2 text-2xl font-bold text-gray-900">{{ kpis.washes_today }}</p>
|
||||
</div>
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<p class="text-sm font-medium text-gray-500">Réservations aujourd'hui</p>
|
||||
<p class="mt-2 text-2xl font-bold text-gray-900">{{ kpis.bookings_today }}</p>
|
||||
</div>
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<p class="text-sm font-medium text-gray-500">Machines hors ligne</p>
|
||||
<p class="mt-2 text-2xl font-bold" :class="kpis.offline_machines > 0 ? 'text-red-600' : 'text-gray-900'">
|
||||
{{ kpis.offline_machines }}
|
||||
<span class="text-sm font-normal text-gray-500">/ {{ kpis.machines_total }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||
<!-- Alerts -->
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<h2 class="mb-4 text-lg font-semibold text-gray-800">Alertes</h2>
|
||||
<div v-if="alerts.length === 0" class="text-sm text-gray-500">
|
||||
Aucune alerte pour le moment.
|
||||
</div>
|
||||
<ul v-else class="space-y-3">
|
||||
<li
|
||||
v-for="(alert, index) in alerts"
|
||||
:key="index"
|
||||
class="rounded-md border-l-4 px-3 py-2 text-sm"
|
||||
:class="severityColor(alert.severity)"
|
||||
>
|
||||
<p class="font-medium text-gray-800">{{ alert.message }}</p>
|
||||
<p class="mt-1 text-xs text-gray-500">{{ formatDate(alert.occurred_at) }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Machines overview -->
|
||||
<div class="rounded-lg bg-white p-5 shadow">
|
||||
<div class="mb-4 flex items-center justify-between">
|
||||
<h2 class="text-lg font-semibold text-gray-800">Parc machines</h2>
|
||||
<Link
|
||||
:href="route('supervisor.machines.index')"
|
||||
class="text-sm text-indigo-600 hover:text-indigo-800"
|
||||
>
|
||||
Voir tout →
|
||||
</Link>
|
||||
</div>
|
||||
<div v-if="machinesOverview.length === 0" class="text-sm text-gray-500">
|
||||
Aucune machine dans votre périmètre.
|
||||
</div>
|
||||
<ul v-else class="divide-y divide-gray-100">
|
||||
<li
|
||||
v-for="machine in machinesOverview"
|
||||
:key="machine.uuid"
|
||||
class="flex items-center justify-between py-3"
|
||||
>
|
||||
<div>
|
||||
<Link
|
||||
:href="route('supervisor.machines.show', machine.uuid)"
|
||||
class="font-medium text-gray-800 hover:text-indigo-600"
|
||||
>
|
||||
{{ machine.name }}
|
||||
</Link>
|
||||
<p class="text-xs text-gray-500">
|
||||
{{ machine.establishment_name }} · {{ machine.type_label }}
|
||||
</p>
|
||||
</div>
|
||||
<span
|
||||
class="rounded-full px-2.5 py-0.5 text-xs font-medium"
|
||||
:class="statusColor(machine.status)"
|
||||
>
|
||||
{{ machine.status_label }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</SupervisorLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user