feat: complete Epic 0 — foundation migration & infrastructure setup
Stories 0.2-0.5: rename folders→declarations (backend+frontend), configure Redis for cache/queue/sessions, add foundation database migrations (permissions, archived_at), replace DeclarationStatus enum with architecture lifecycle values, create DeclarationObserver for status transition validation and auto-archive, fix controller status transitions to respect observer rules. 93 tests pass (240 assertions). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
232
resources/js/pages/declarations/Index.vue
Normal file
232
resources/js/pages/declarations/Index.vue
Normal file
@@ -0,0 +1,232 @@
|
||||
<script setup lang="ts">
|
||||
import { Head, Link, router } from '@inertiajs/vue3';
|
||||
import { FolderOpen } from 'lucide-vue-next';
|
||||
import Heading from '@/components/Heading.vue';
|
||||
import Pagination from '@/components/Pagination.vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import AppLayout from '@/layouts/AppLayout.vue';
|
||||
|
||||
type Declaration = {
|
||||
id: number;
|
||||
title: string;
|
||||
type: string;
|
||||
client_name: string;
|
||||
status: string;
|
||||
due_date: string | null;
|
||||
showUrl: string;
|
||||
editUrl: string;
|
||||
destroyUrl: string;
|
||||
};
|
||||
|
||||
type PaginatedData<T> = {
|
||||
data: T[];
|
||||
from: number | null;
|
||||
to: number | null;
|
||||
total: number;
|
||||
current_page: number;
|
||||
last_page: number;
|
||||
per_page: number;
|
||||
path: string;
|
||||
first_page_url: string;
|
||||
prev_page_url: string | null;
|
||||
next_page_url: string | null;
|
||||
last_page_url: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
declarations: PaginatedData<Declaration>;
|
||||
createUrl: string;
|
||||
workspaceName: string;
|
||||
};
|
||||
|
||||
defineProps<Props>();
|
||||
|
||||
function destroy(declaration: Declaration) {
|
||||
if (
|
||||
window.confirm(
|
||||
`Êtes-vous sûr de vouloir supprimer « ${declaration.title} » ?`,
|
||||
)
|
||||
) {
|
||||
router.delete(declaration.destroyUrl);
|
||||
}
|
||||
}
|
||||
|
||||
const typeLabels: Record<string, string> = {
|
||||
vat: 'TVA',
|
||||
vat_monthly: 'TVA mensuelle',
|
||||
vat_quarterly: 'TVA trimestrielle',
|
||||
corporate_tax: 'IS',
|
||||
income_tax: 'IR',
|
||||
cnss: 'CNSS',
|
||||
annual_balance: 'Bilan',
|
||||
other: 'Autre',
|
||||
};
|
||||
|
||||
const statusLabels: Record<string, string> = {
|
||||
draft: 'Brouillon',
|
||||
waiting_documents: 'En attente documents',
|
||||
documents_received: 'Documents reçus',
|
||||
processing: 'En cours de traitement',
|
||||
additional_documents_requested: 'Pièces complémentaires demandées',
|
||||
waiting_client_validation: 'En attente validation client',
|
||||
validated: 'Validé',
|
||||
closed: 'Clôturé',
|
||||
cancelled: 'Annulé',
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppLayout :breadcrumbs="[{ title: 'Déclarations' }]">
|
||||
<Head title="Déclarations" />
|
||||
|
||||
<div class="flex flex-col space-y-6 p-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<Heading
|
||||
variant="small"
|
||||
title="Déclarations"
|
||||
:description="`Gérer les déclarations du workspace « ${workspaceName} »`"
|
||||
/>
|
||||
<Button as-child>
|
||||
<Link :href="createUrl">Nouvelle déclaration</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="overflow-hidden rounded-xl border border-sidebar-border/70 dark:border-sidebar-border"
|
||||
>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full text-sm">
|
||||
<thead
|
||||
class="border-b border-sidebar-border/70 bg-muted/50"
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="h-10 px-4 text-left align-middle font-medium"
|
||||
>
|
||||
Titre
|
||||
</th>
|
||||
<th
|
||||
class="h-10 px-4 text-left align-middle font-medium"
|
||||
>
|
||||
Client
|
||||
</th>
|
||||
<th
|
||||
class="h-10 px-4 text-left align-middle font-medium"
|
||||
>
|
||||
Type
|
||||
</th>
|
||||
<th
|
||||
class="h-10 px-4 text-left align-middle font-medium"
|
||||
>
|
||||
Statut
|
||||
</th>
|
||||
<th
|
||||
class="h-10 px-4 text-left align-middle font-medium"
|
||||
>
|
||||
Date limite
|
||||
</th>
|
||||
<th
|
||||
class="h-10 px-4 text-right align-middle font-medium"
|
||||
>
|
||||
Actions
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="declaration in declarations.data"
|
||||
:key="declaration.id"
|
||||
class="border-b border-sidebar-border/50 last:border-0"
|
||||
>
|
||||
<td class="px-4 py-3 font-medium">
|
||||
<Link
|
||||
:href="declaration.showUrl"
|
||||
class="hover:underline"
|
||||
>
|
||||
{{ declaration.title }}
|
||||
</Link>
|
||||
</td>
|
||||
<td class="px-4 py-3 text-muted-foreground">
|
||||
{{ declaration.client_name }}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-muted-foreground">
|
||||
{{
|
||||
typeLabels[declaration.type] ??
|
||||
declaration.type
|
||||
}}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-muted-foreground">
|
||||
{{
|
||||
statusLabels[declaration.status] ??
|
||||
declaration.status
|
||||
}}
|
||||
</td>
|
||||
<td class="px-4 py-3 text-muted-foreground">
|
||||
{{ declaration.due_date || '—' }}
|
||||
</td>
|
||||
<td class="space-x-2 px-4 py-3 text-right">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
as-child
|
||||
>
|
||||
<Link :href="declaration.showUrl"
|
||||
>Voir</Link
|
||||
>
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
as-child
|
||||
>
|
||||
<Link :href="declaration.editUrl"
|
||||
>Modifier</Link
|
||||
>
|
||||
</Button>
|
||||
<Button
|
||||
variant="destructive"
|
||||
size="sm"
|
||||
@click="destroy(declaration)"
|
||||
>
|
||||
Supprimer
|
||||
</Button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="!declarations.data.length">
|
||||
<td
|
||||
colspan="6"
|
||||
class="px-4 py-8 text-center text-muted-foreground"
|
||||
>
|
||||
<div
|
||||
class="flex flex-col items-center gap-2"
|
||||
>
|
||||
<FolderOpen class="h-10 w-10" />
|
||||
<p>
|
||||
Aucune déclaration pour le moment.
|
||||
</p>
|
||||
<Button as-child>
|
||||
<Link :href="createUrl"
|
||||
>Créer votre première
|
||||
déclaration</Link
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<Pagination
|
||||
:pagination="{
|
||||
from: declarations.from ?? 0,
|
||||
to: declarations.to ?? 0,
|
||||
total: declarations.total,
|
||||
current_page: declarations.current_page,
|
||||
last_page: declarations.last_page,
|
||||
per_page: declarations.per_page,
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
</AppLayout>
|
||||
</template>
|
||||
Reference in New Issue
Block a user