feat : add Clients page with table and drawer form
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
95
frontend/pages/clients.vue
Normal file
95
frontend/pages/clients.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-2xl font-bold text-neutral-900">Clients</h1>
|
||||
<button
|
||||
class="rounded-md bg-primary-500 px-4 py-2 text-sm font-semibold text-white hover:bg-secondary-500"
|
||||
@click="openCreate"
|
||||
>
|
||||
+ Ajouter un client
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 overflow-x-auto rounded-lg border border-neutral-200">
|
||||
<table class="w-full text-left text-sm">
|
||||
<thead class="border-b border-neutral-200 bg-neutral-50">
|
||||
<tr>
|
||||
<th class="px-4 py-3 font-semibold text-neutral-700">Nom</th>
|
||||
<th class="px-4 py-3 font-semibold text-neutral-700">Email</th>
|
||||
<th class="px-4 py-3 font-semibold text-neutral-700">Adresse</th>
|
||||
<th class="px-4 py-3 font-semibold text-neutral-700">Téléphone</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="client in clients"
|
||||
:key="client.id"
|
||||
class="border-b border-neutral-100 hover:bg-neutral-50 cursor-pointer"
|
||||
@click="openEdit(client)"
|
||||
>
|
||||
<td class="px-4 py-3 font-semibold text-primary-500">{{ client.name }}</td>
|
||||
<td class="px-4 py-3 text-primary-500">{{ client.email ?? '-' }}</td>
|
||||
<td class="px-4 py-3 text-neutral-700">{{ formatAddress(client) }}</td>
|
||||
<td class="px-4 py-3 text-primary-500">{{ client.phone ?? '-' }}</td>
|
||||
</tr>
|
||||
<tr v-if="clients.length === 0 && !isLoading">
|
||||
<td colspan="4" class="px-4 py-8 text-center text-neutral-400">
|
||||
Aucun client trouvé.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<ClientDrawer
|
||||
v-model="drawerOpen"
|
||||
:client="selectedClient"
|
||||
@saved="onSaved"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Client } from '~/services/dto/client'
|
||||
|
||||
useHead({ title: 'Clients' })
|
||||
|
||||
const { getAll } = useClientService()
|
||||
const clients = ref<Client[]>([])
|
||||
const isLoading = ref(true)
|
||||
const drawerOpen = ref(false)
|
||||
const selectedClient = ref<Client | null>(null)
|
||||
|
||||
async function loadClients() {
|
||||
isLoading.value = true
|
||||
try {
|
||||
clients.value = await getAll()
|
||||
} finally {
|
||||
isLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function openCreate() {
|
||||
selectedClient.value = null
|
||||
drawerOpen.value = true
|
||||
}
|
||||
|
||||
function openEdit(client: Client) {
|
||||
selectedClient.value = client
|
||||
drawerOpen.value = true
|
||||
}
|
||||
|
||||
function formatAddress(client: Client): string {
|
||||
return [client.street, client.postalCode, client.city]
|
||||
.filter(Boolean)
|
||||
.join(', ') || '-'
|
||||
}
|
||||
|
||||
async function onSaved() {
|
||||
await loadClients()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadClients()
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user