feat(dashboard): complete frontend redesign for Issue #271

- +layout.svelte: Upload button in header (authenticated users only)
- +page.server.ts: call /api/dashboard/resume, /pulse, /activity;
  remove deprecated /api/documents/incomplete and /recent-activity
- +page.svelte: 2-col grid layout (main + 320px sidebar), greeting,
  DashboardFamilyPulse + DashboardActivityFeed in sidebar
- DashboardResumeStrip: refactored to use server data (resumeDoc prop),
  SVG thumbnail, progress bar with aria-*, empty state, CTA
- DashboardFamilyPulse: new component — weekly stats from audit_log
- DashboardActivityFeed: new component — activity feed with "für dich" badge
- Update specs for new data shapes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-19 17:44:08 +02:00
committed by marcel
parent d34e8986af
commit 5a98edac86
10 changed files with 488 additions and 157 deletions

View File

@@ -40,10 +40,10 @@ const emptyData = {
string,
import('$lib/generated/api').components['schemas']['SearchMatchData']
>,
incompleteDocs: [],
recentDocs: [],
resumeDoc: null,
pulse: null,
activityFeed: [],
stats: null,
incompleteCount: 0,
initialValues: { senderName: '', receiverName: '' },
segmentationDocs: [],
transcriptionDocs: [],
@@ -233,33 +233,31 @@ describe('Home page dashboard mode', () => {
const dashboardData = {
...emptyData,
isDashboard: true,
canWrite: false,
incompleteDocs: [],
recentDocs: []
resumeDoc: null,
pulse: null,
activityFeed: []
};
it('hides the right column when canWrite is false and incompleteDocs is empty', async () => {
it('renders empty state when resumeDoc is null', async () => {
render(Page, { data: dashboardData });
const rightCol = page.getByTestId('dashboard-right-column');
await expect.element(rightCol).not.toBeInTheDocument();
const empty = page.getByTestId('resume-strip-empty');
await expect.element(empty).toBeInTheDocument();
});
it('shows the right column when canWrite is true', async () => {
render(Page, { data: { ...dashboardData, canWrite: true } });
const rightCol = page.getByTestId('dashboard-right-column');
await expect.element(rightCol).toBeInTheDocument();
});
it('shows the right column when incompleteDocs is non-empty', async () => {
render(Page, {
data: {
...dashboardData,
canWrite: false,
incompleteDocs: [{ id: 'd1', title: 'Taufschein' }]
}
});
const rightCol = page.getByTestId('dashboard-right-column');
await expect.element(rightCol).toBeInTheDocument();
it('renders resume card when resumeDoc is provided', async () => {
const resume = {
documentId: 'doc-1',
title: 'Geburtsurkunde',
caption: 'Max · 1920',
excerpt: 'Hiermit…',
page: 1,
pages: 3,
pct: 33,
collaborators: []
};
render(Page, { data: { ...dashboardData, resumeDoc: resume } });
const strip = page.getByTestId('resume-strip');
await expect.element(strip).toBeInTheDocument();
});
});