Files
backend/resources/js/Pages/Supervisor/Washes/Index.vue
T

197 lines
7.4 KiB
Vue

<script setup>
import DataTable from '@/Components/Supervisor/DataTable.vue';
import Pagination from '@/Components/Supervisor/Pagination.vue';
import StatusBadge from '@/Components/Supervisor/StatusBadge.vue';
import TableHeaderCell from '@/Components/Supervisor/TableHeaderCell.vue';
import { useListFilters } from '@/Components/Supervisor/useListFilters.js';
import {
filterInputClass,
filterSelectClass,
getStatusColor,
linkClass,
rowClass,
tdClass,
washStatusColors,
} from '@/Components/Supervisor/ui.js';
import SupervisorLayout from '@/Layouts/SupervisorLayout.vue';
import { Head, Link } from '@inertiajs/vue3';
import { computed } from 'vue';
const props = defineProps({
washes: {
type: Object,
required: true,
},
establishments: {
type: Array,
default: () => [],
},
filters: {
type: Object,
default: () => ({}),
},
statusOptions: {
type: Object,
default: () => ({}),
},
});
const { localFilters, toggleSort } = useListFilters('supervisor.washes.index', {
establishment_id: props.filters.establishment_id ?? '',
user: props.filters.user ?? '',
status: props.filters.status ?? '',
date: props.filters.date ?? '',
sort: props.filters.sort ?? 'started_at',
direction: props.filters.direction ?? 'desc',
per_page: props.filters.per_page ?? 10,
}, { debounceKeys: ['user'] });
const showEstablishmentFilter = computed(() => props.establishments.length > 1);
const handleSort = (key) => toggleSort(key, ['started_at', 'duration_minutes', 'cost']);
const formatDate = (iso) => {
if (!iso) return '—';
return new Intl.DateTimeFormat('fr-FR', {
dateStyle: 'short',
timeStyle: 'short',
}).format(new Date(iso));
};
const formatCurrency = (value) =>
new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(value ?? 0);
</script>
<template>
<Head title="Lavages" />
<SupervisorLayout title="Lavages">
<DataTable>
<template #head>
<tr>
<TableHeaderCell
label="Début"
sortable
sort-key="started_at"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
>
<input v-model="localFilters.date" type="date" :class="filterInputClass" />
</TableHeaderCell>
<TableHeaderCell
label="Utilisateur"
sortable
sort-key="user"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
>
<input
v-model="localFilters.user"
type="text"
placeholder="Nom ou e-mail…"
:class="filterInputClass"
/>
</TableHeaderCell>
<TableHeaderCell
label="Machine"
sortable
sort-key="machine"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
>
<select
v-if="showEstablishmentFilter"
v-model="localFilters.establishment_id"
:class="filterSelectClass"
>
<option value="">Toutes</option>
<option v-for="est in establishments" :key="est.id" :value="est.id">
{{ est.name }}
</option>
</select>
</TableHeaderCell>
<TableHeaderCell
label="Statut"
sortable
sort-key="status"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
>
<select v-model="localFilters.status" :class="filterSelectClass">
<option value="">Tous</option>
<option v-for="(label, value) in statusOptions" :key="value" :value="value">
{{ label }}
</option>
</select>
</TableHeaderCell>
<TableHeaderCell
label="Durée"
sortable
sort-key="duration_minutes"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
/>
<TableHeaderCell
label="Coût"
sortable
sort-key="cost"
:active-sort="localFilters.sort"
:sort-direction="localFilters.direction"
@sort="handleSort"
/>
</tr>
</template>
<tr v-if="washes.data.length === 0">
<td colspan="6" class="px-6 py-12 text-center text-sm text-slate-400">
Aucun lavage trouvé.
</td>
</tr>
<tr v-for="wash in washes.data" :key="wash.uuid" :class="rowClass">
<td :class="[tdClass, 'font-medium text-slate-800']">
{{ formatDate(wash.started_at) }}
</td>
<td :class="tdClass">
<div class="font-medium text-slate-800">{{ wash.user?.name ?? '—' }}</div>
<div class="text-xs text-slate-400">{{ wash.user?.email }}</div>
</td>
<td :class="tdClass">
<Link
v-if="wash.machine"
:href="route('supervisor.machines.show', wash.machine.uuid)"
:class="linkClass"
>
{{ wash.machine.name }}
</Link>
<span v-else></span>
</td>
<td :class="tdClass">
<StatusBadge
:label="wash.status_label"
:color-class="getStatusColor(wash.status, washStatusColors)"
/>
</td>
<td :class="tdClass">
{{ wash.duration_minutes ? `${wash.duration_minutes} min` : '—' }}
</td>
<td :class="[tdClass, 'font-semibold text-slate-800']">
{{ formatCurrency(wash.cost) }}
</td>
</tr>
<template #footer>
<Pagination
:paginator="washes"
:per-page="localFilters.per_page"
@update:per-page="(value) => { localFilters.per_page = value; }"
/>
</template>
</DataTable>
</SupervisorLayout>
</template>