clientlist selectie & dashboardpage

This commit is contained in:
colinislit
2025-11-19 23:19:56 +01:00
parent f5a30dbae5
commit 4b71c4a615
3 changed files with 104 additions and 102 deletions

View File

@@ -2,25 +2,99 @@
* Client Dashboard - Level 2 (Client Dossier)
*
* Overzicht van client voortgang, recente activiteit en belangrijke metrics.
* Dit is de hoofd-dashboard pagina die opent wanneer je een client selecteert.
*/
export default function ClientDashboardPage({ params }: { params: Promise<{ id: string }> }) {
return (
<div>
<h1 className="text-2xl font-bold text-slate-900 mb-6">
Dashboard
</h1>
import { notFound } from 'next/navigation';
import { ChevronLeft } from 'lucide-react';
import Link from 'next/link';
import { getClient } from '../../actions';
import { transformClient } from '@/lib/types/client';
import { ClientTabs } from '../components/client-tabs';
<div className="bg-slate-100 border-2 border-dashed border-slate-300 rounded-lg p-12 text-center">
<p className="text-slate-600 text-lg mb-2">
Client Dashboard
</p>
<p className="text-slate-500 text-sm">
Overzicht, recente activiteit, snelle acties
</p>
<p className="text-xs text-slate-400 mt-4">
Placeholder - Not designed yet
</p>
interface ClientDashboardPageProps {
params: Promise<{ id: string }>;
searchParams: Promise<{ tab?: string }>;
}
export default async function ClientDashboardPage({
params,
searchParams,
}: ClientDashboardPageProps) {
const { id } = await params;
const { tab } = await searchParams;
// Fetch client data
let client;
try {
client = await getClient(id);
} catch (error) {
notFound();
}
if (!client) {
notFound();
}
const clientWithAge = transformClient(client);
return (
<div className="min-h-full bg-slate-50">
{/* Header */}
<div className="bg-white border-b border-slate-200">
<div className="px-4 sm:px-6 lg:px-8 py-6">
{/* Breadcrumb */}
<Link
href="/epd/clients"
className="inline-flex items-center gap-2 text-sm text-slate-600 hover:text-slate-900 mb-4 transition-colors"
>
<ChevronLeft className="h-4 w-4" />
<span>Terug naar cliënten</span>
</Link>
{/* Client Info */}
<div className="flex items-start justify-between">
<div className="flex items-center gap-4">
{/* Avatar */}
<div className="h-16 w-16 rounded-full bg-gradient-to-br from-teal-500 to-teal-600 flex items-center justify-center shadow-md">
<span className="text-white font-semibold text-xl">
{client.first_name[0]}
{client.last_name[0]}
</span>
</div>
{/* Name & Info */}
<div>
<h1 className="text-2xl font-bold text-slate-900">
{clientWithAge.full_name}
</h1>
<div className="flex items-center gap-4 mt-1 text-sm text-slate-600">
<span>{clientWithAge.age} jaar</span>
<span></span>
<span>
Geboren:{' '}
{new Date(client.birth_date).toLocaleDateString('nl-NL')}
</span>
</div>
</div>
</div>
{/* Actions */}
<div className="flex items-center gap-2">
<Link
href={`/epd/clients/${client.id}/edit`}
className="inline-flex items-center gap-2 px-4 py-2 border border-slate-300 text-slate-700 font-medium rounded-lg hover:bg-slate-50 transition-colors"
>
Bewerken
</Link>
</div>
</div>
</div>
</div>
{/* Tab Content */}
<div className="px-4 sm:px-6 lg:px-8 py-6">
<ClientTabs clientId={client.id} activeTab={tab} />
</div>
</div>
);

View File

@@ -1,94 +1,18 @@
import { notFound } from 'next/navigation';
import { ChevronLeft } from 'lucide-react';
import Link from 'next/link';
import { getClient } from '../actions';
import { transformClient } from '@/lib/types/client';
import { ClientTabs } from './components/client-tabs';
import { redirect } from 'next/navigation';
interface ClientDetailPageProps {
params: Promise<{ id: string }>;
searchParams: Promise<{ tab?: string }>;
}
/**
* Redirect route: /epd/clients/[id] -> /epd/clients/[id]/dashboard
*
* Wanneer een gebruiker direct naar /epd/clients/[id] navigeert,
* wordt deze automatisch doorgestuurd naar het dashboard.
*/
export default async function ClientDetailPage({
params,
searchParams,
}: ClientDetailPageProps) {
const { id } = await params;
const { tab } = await searchParams;
// Fetch client data
let client;
try {
client = await getClient(id);
} catch (error) {
notFound();
}
if (!client) {
notFound();
}
const clientWithAge = transformClient(client);
return (
<div className="min-h-full bg-slate-50">
{/* Header */}
<div className="bg-white border-b border-slate-200">
<div className="px-4 sm:px-6 lg:px-8 py-6">
{/* Breadcrumb */}
<Link
href="/epd/clients"
className="inline-flex items-center gap-2 text-sm text-slate-600 hover:text-slate-900 mb-4 transition-colors"
>
<ChevronLeft className="h-4 w-4" />
<span>Terug naar cliënten</span>
</Link>
{/* Client Info */}
<div className="flex items-start justify-between">
<div className="flex items-center gap-4">
{/* Avatar */}
<div className="h-16 w-16 rounded-full bg-gradient-to-br from-teal-500 to-teal-600 flex items-center justify-center shadow-md">
<span className="text-white font-semibold text-xl">
{client.first_name[0]}
{client.last_name[0]}
</span>
</div>
{/* Name & Info */}
<div>
<h1 className="text-2xl font-bold text-slate-900">
{clientWithAge.full_name}
</h1>
<div className="flex items-center gap-4 mt-1 text-sm text-slate-600">
<span>{clientWithAge.age} jaar</span>
<span></span>
<span>
Geboren:{' '}
{new Date(client.birth_date).toLocaleDateString('nl-NL')}
</span>
</div>
</div>
</div>
{/* Actions */}
<div className="flex items-center gap-2">
<Link
href={`/epd/clients/${client.id}/edit`}
className="inline-flex items-center gap-2 px-4 py-2 border border-slate-300 text-slate-700 font-medium rounded-lg hover:bg-slate-50 transition-colors"
>
Bewerken
</Link>
</div>
</div>
</div>
</div>
{/* Tab Content */}
<div className="px-4 sm:px-6 lg:px-8 py-6">
<ClientTabs clientId={client.id} activeTab={tab} />
</div>
</div>
);
redirect(`/epd/clients/${id}/dashboard`);
}

View File

@@ -124,7 +124,8 @@ export function ClientList({ initialClients }: ClientListProps) {
{filteredClients.map((client) => (
<tr
key={client.id}
className="hover:bg-slate-50 transition-colors"
onClick={() => router.push(`/epd/clients/${client.id}`)}
className="hover:bg-slate-50 transition-colors cursor-pointer"
>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
@@ -153,7 +154,10 @@ export function ClientList({ initialClients }: ClientListProps) {
{new Date(client.created_at).toLocaleDateString('nl-NL')}
</td>
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div className="flex items-center justify-end gap-2">
<div
className="flex items-center justify-end gap-2"
onClick={(e) => e.stopPropagation()}
>
<Link
href={`/epd/clients/${client.id}`}
className="text-teal-600 hover:text-teal-900 p-1 rounded hover:bg-teal-50 transition-colors"