La fiche empilait tout sur une page, en lecture seule. Le dossier personnel existait pourtant en base — date et lieu de naissance, nationalité, adresse, contact d'urgence, NIR et IBAN chiffrés — sans qu'aucun écran ne l'écrive : un salarié créé restait un dossier vide que rien ne permettait de remplir. Cinq onglets, cinq routes : une fiche s'envoie par lien et se rouvre au même endroit. Le bandeau porte ce qui ne change pas d'un onglet à l'autre, et le gabarit le tient une fois pour toutes. Deux points d'écriture et non un seul. L'état civil et les coordonnées demandent `members.edit` ; le NIR, l'IBAN et le BIC exigent en plus de pouvoir les lire. Fondus dans un même formulaire, un profil habilité à modifier mais pas à lire aurait renvoyé des champs vides — et effacé ce qui ne lui avait jamais été montré. Le journal retient qu'ils ont été renseignés, jamais leur valeur. Les parcours qui déposaient une pièce ou ouvraient un accès passent désormais par l'onglet qui les porte. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { notFound } from 'next/navigation';
|
||
|
||
import { DocumentsPanel } from '@/app/(app)/equipe/[id]/DocumentsPanel';
|
||
import { InvitationPanel } from '@/app/(app)/equipe/[id]/InvitationPanel';
|
||
import { Badge } from '@/components/ui/Badge';
|
||
import { Card, CardHeader, EmptyState } from '@/components/ui/Card';
|
||
import { listDocuments } from '@/server/documents/queries';
|
||
import { getEmployee } from '@/server/employees/queries';
|
||
|
||
export const dynamic = 'force-dynamic';
|
||
|
||
export default async function DocumentsTab({
|
||
params,
|
||
}: {
|
||
params: Promise<{ id: string }>;
|
||
}) {
|
||
const { id } = await params;
|
||
const employee = await getEmployee(id);
|
||
if (!employee) notFound();
|
||
|
||
// `members.documents.view` peut manquer là où `members.view` est accordée :
|
||
// la section disparaît alors, plutôt que d'échouer sur toute la page.
|
||
const documents = await listDocuments(id).catch(() => null);
|
||
|
||
return (
|
||
<div className="flex flex-col gap-5">
|
||
{documents ? (
|
||
<Card>
|
||
<CardHeader
|
||
title="Pièces du dossier"
|
||
badge={<Badge tone="neutral">{documents.documents.length}</Badge>}
|
||
/>
|
||
<DocumentsPanel
|
||
membershipId={employee.id}
|
||
documents={documents.documents}
|
||
canManage={documents.canManage}
|
||
/>
|
||
</Card>
|
||
) : (
|
||
<EmptyState
|
||
title="Documents non consultables"
|
||
description="Votre rôle ne donne pas accès aux pièces du dossier."
|
||
/>
|
||
)}
|
||
|
||
{employee.canInvite ? (
|
||
<Card>
|
||
<CardHeader title="Accès à l’application" />
|
||
<InvitationPanel
|
||
membershipId={employee.id}
|
||
defaultEmail={employee.email ?? employee.profile?.personalEmail ?? ''}
|
||
hasAccount={employee.hasAccount}
|
||
invitation={employee.invitation}
|
||
/>
|
||
</Card>
|
||
) : null}
|
||
</div>
|
||
);
|
||
}
|