clientlist selectie & dashboardpage
This commit is contained in:
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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`);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user