Initial commit with contrats and domaines modules
This commit is contained in:
119
resources/js/Pages/Categories/Index.vue
Normal file
119
resources/js/Pages/Categories/Index.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<script setup>
|
||||
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'
|
||||
import { Head, useForm, router } from '@inertiajs/vue3'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = defineProps({ categories: Array })
|
||||
|
||||
const showForm = ref(false)
|
||||
const editTarget = ref(null)
|
||||
|
||||
const form = useForm({ nom: '', description: '', couleur: '#3B82F6', icone: '', ordre: 0 })
|
||||
const editForm = useForm({ nom: '', description: '', couleur: '', icone: '', ordre: 0, active: true })
|
||||
|
||||
function openCreate() { form.reset(); showForm.value = true; editTarget.value = null }
|
||||
function openEdit(cat) {
|
||||
editTarget.value = cat
|
||||
editForm.nom = cat.nom
|
||||
editForm.description = cat.description ?? ''
|
||||
editForm.couleur = cat.couleur ?? '#3B82F6'
|
||||
editForm.icone = cat.icone ?? ''
|
||||
editForm.ordre = cat.ordre
|
||||
editForm.active = cat.active
|
||||
}
|
||||
|
||||
function submitCreate() { form.post(route('categories.store'), { onSuccess: () => { showForm.value = false; form.reset() } }) }
|
||||
function submitEdit() { editForm.put(route('categories.update', editTarget.value.id), { onSuccess: () => editTarget.value = null }) }
|
||||
|
||||
function deactivate(cat) {
|
||||
if (confirm(`Désactiver "${cat.nom}" ?`)) {
|
||||
router.delete(route('categories.destroy', cat.id))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Head title="Catégories" />
|
||||
<AuthenticatedLayout>
|
||||
<template #header>
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="text-xl font-semibold text-gray-900">Catégories</h1>
|
||||
<button @click="openCreate" class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 transition-colors">+ Ajouter</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Formulaire création -->
|
||||
<div v-if="showForm" class="mb-6 rounded-xl bg-white p-5 shadow-sm border border-blue-200">
|
||||
<h2 class="mb-4 text-sm font-semibold text-gray-700">Nouvelle catégorie</h2>
|
||||
<form @submit.prevent="submitCreate" class="grid gap-3 sm:grid-cols-3">
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Nom *</label><input v-model="form.nom" type="text" required class="block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" /></div>
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Couleur</label><input v-model="form.couleur" type="color" class="block h-10 w-full rounded-lg border border-gray-300 cursor-pointer" /></div>
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Ordre</label><input v-model="form.ordre" type="number" min="0" class="block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" /></div>
|
||||
<div class="sm:col-span-3"><label class="block text-xs font-medium text-gray-600 mb-1">Description</label><input v-model="form.description" type="text" class="block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" /></div>
|
||||
<div class="sm:col-span-3 flex gap-2">
|
||||
<button type="submit" :disabled="form.processing" class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50 transition-colors">{{ form.processing ? '...' : 'Créer' }}</button>
|
||||
<button type="button" @click="showForm = false" class="rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors">Annuler</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Liste -->
|
||||
<div class="rounded-xl bg-white shadow-sm border border-gray-100 overflow-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-100 text-sm">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="px-5 py-3 text-left text-xs font-medium text-gray-500 uppercase">Catégorie</th>
|
||||
<th class="px-5 py-3 text-left text-xs font-medium text-gray-500 uppercase">Description</th>
|
||||
<th class="px-5 py-3 text-right text-xs font-medium text-gray-500 uppercase">Articles</th>
|
||||
<th class="px-5 py-3 text-center text-xs font-medium text-gray-500 uppercase">Statut</th>
|
||||
<th class="px-5 py-3 text-center text-xs font-medium text-gray-500 uppercase">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-50">
|
||||
<template v-for="cat in categories" :key="cat.id">
|
||||
<tr :class="['hover:bg-gray-50 transition-colors', !cat.active ? 'opacity-50' : '']">
|
||||
<td class="px-5 py-3">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="h-4 w-4 rounded-full flex-shrink-0" :style="{ backgroundColor: cat.couleur || '#6B7280' }" />
|
||||
<span class="font-medium text-gray-900">{{ cat.nom }}</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-5 py-3 text-gray-500">{{ cat.description || '—' }}</td>
|
||||
<td class="px-5 py-3 text-right text-gray-700">{{ cat.articles_count }}</td>
|
||||
<td class="px-5 py-3 text-center">
|
||||
<span :class="['rounded-full px-2.5 py-1 text-xs font-medium', cat.active ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-600']">
|
||||
{{ cat.active ? 'Active' : 'Inactive' }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-5 py-3 text-center">
|
||||
<div class="flex items-center justify-center gap-2">
|
||||
<button @click="openEdit(cat)" class="text-gray-400 hover:text-indigo-600 transition-colors">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" /></svg>
|
||||
</button>
|
||||
<button v-if="cat.active" @click="deactivate(cat)" class="text-gray-400 hover:text-red-600 transition-colors">
|
||||
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M18.364 18.364A9 9 0 005.636 5.636m12.728 12.728A9 9 0 015.636 5.636m12.728 12.728L5.636 5.636" /></svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Edit inline row -->
|
||||
<tr v-if="editTarget?.id === cat.id">
|
||||
<td colspan="5" class="bg-indigo-50 px-5 py-4">
|
||||
<form @submit.prevent="submitEdit" class="grid gap-3 sm:grid-cols-4">
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Nom *</label><input v-model="editForm.nom" type="text" required class="block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" /></div>
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Couleur</label><input v-model="editForm.couleur" type="color" class="block h-10 w-full rounded-lg border border-gray-300" /></div>
|
||||
<div><label class="block text-xs font-medium text-gray-600 mb-1">Ordre</label><input v-model="editForm.ordre" type="number" min="0" class="block w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none" /></div>
|
||||
<div class="flex items-end gap-2">
|
||||
<button type="submit" :disabled="editForm.processing" class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 disabled:opacity-50 transition-colors">Enregistrer</button>
|
||||
<button type="button" @click="editTarget = null" class="rounded-lg border border-gray-300 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 transition-colors">Annuler</button>
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
<p v-if="!categories.length" class="py-10 text-center text-gray-400">Aucune catégorie.</p>
|
||||
</div>
|
||||
</AuthenticatedLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user