feat: Phase B — interactive dashboard, breadcrumbs, clickable navigation
- Breadcrumb component: reusable nav with items array (label+href)
- DeadlineTrafficLights: buttons → Links to /fristen?status={filter}
- CaseOverviewGrid: static metrics → clickable Links to /cases?status={filter}
- UpcomingTimeline: items → clickable Links to /fristen/{id} or /termine/{id}
with case number links and hover chevron
- QuickActions: swap CalDAV Sync for "Neuer Termin" → /termine/neu,
fix "Frist eintragen" → /fristen/neu
- AISummaryCard: add RefreshCw button with spinning animation
- RecentActivityList: new component showing recent case events
- DeadlineList: accept initialStatus prop, add this_week/ok filters
- fristen/page.tsx: read searchParams.status for initial filter
- Add breadcrumbs to dashboard, fristen, cases, termine pages
- Add RecentActivity type, update DashboardData type
This commit is contained in:
@@ -1,10 +1,12 @@
|
||||
"use client";
|
||||
|
||||
import { Sparkles } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { Sparkles, RefreshCw } from "lucide-react";
|
||||
import type { DashboardData } from "@/lib/types";
|
||||
|
||||
interface Props {
|
||||
data: DashboardData;
|
||||
onRefresh?: () => void;
|
||||
}
|
||||
|
||||
function generateSummary(data: DashboardData): string {
|
||||
@@ -51,18 +53,39 @@ function generateSummary(data: DashboardData): string {
|
||||
return parts.join(" ");
|
||||
}
|
||||
|
||||
export function AISummaryCard({ data }: Props) {
|
||||
export function AISummaryCard({ data, onRefresh }: Props) {
|
||||
const [spinning, setSpinning] = useState(false);
|
||||
const summary = generateSummary(data);
|
||||
|
||||
function handleRefresh() {
|
||||
if (!onRefresh) return;
|
||||
setSpinning(true);
|
||||
onRefresh();
|
||||
setTimeout(() => setSpinning(false), 1000);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-xl border border-neutral-200 bg-white p-5">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="rounded-md bg-violet-50 p-1.5">
|
||||
<Sparkles className="h-4 w-4 text-violet-500" />
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="rounded-md bg-violet-50 p-1.5">
|
||||
<Sparkles className="h-4 w-4 text-violet-500" />
|
||||
</div>
|
||||
<h2 className="text-sm font-semibold text-neutral-900">
|
||||
KI-Zusammenfassung
|
||||
</h2>
|
||||
</div>
|
||||
<h2 className="text-sm font-semibold text-neutral-900">
|
||||
KI-Zusammenfassung
|
||||
</h2>
|
||||
{onRefresh && (
|
||||
<button
|
||||
onClick={handleRefresh}
|
||||
title="Aktualisieren"
|
||||
className="rounded-md p-1.5 text-neutral-400 transition-colors hover:bg-neutral-100 hover:text-neutral-600"
|
||||
>
|
||||
<RefreshCw
|
||||
className={`h-4 w-4 ${spinning ? "animate-spin" : ""}`}
|
||||
/>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-3 text-sm leading-relaxed text-neutral-700">
|
||||
{summary}
|
||||
|
||||
Reference in New Issue
Block a user