feat: user data purge, breadcrumbs, first-login dialog, widget consolidation, bookkeeping cascade

- Admin can purge all personal data for a user (POST /api/admin/users/:userId/purge-data)
  while keeping the account; clears profile, notifications, bookings, ical tokens, preferences
- Add isNewUser flag to auth callback response; first-login dialog prompts for Standesbuchnummer
- Add PageBreadcrumbs component and apply to 18 sub-pages across the app
- Cascade budget_typ changes from parent pot to all children recursively, converting amounts
  (detailliert→einfach: sum into budget_gesamt; einfach→detailliert: zero all for redistribution)
- Migrate NextcloudTalkWidget to use shared WidgetCard template for consistent header styling

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthias Hochmeister
2026-04-13 16:15:28 +02:00
parent a0b3c0ec5c
commit b477e5dbe0
32 changed files with 485 additions and 49 deletions

View File

@@ -11,6 +11,7 @@ import {
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useParams, useNavigate } from 'react-router-dom';
import DashboardLayout from '../components/dashboard/DashboardLayout';
import { PageBreadcrumbs } from '../components/common';
import { useNotification } from '../contexts/NotificationContext';
import { usePermissionContext } from '../contexts/PermissionContext';
import { ausruestungsanfrageApi } from '../services/ausruestungsanfrage';
@@ -285,6 +286,10 @@ export default function AusruestungsanfrageArtikelDetail() {
return (
<DashboardLayout>
<PageBreadcrumbs items={[
{ label: 'Ausrüstungsanfragen', href: '/ausruestungsanfrage' },
{ label: isCreate ? 'Neuer Katalogartikel' : (artikel?.bezeichnung ?? 'Artikel') },
]} />
{/* Header */}
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 3 }}>
<IconButton onClick={() => navigate('/ausruestungsanfrage?tab=2')}>