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

@@ -0,0 +1,44 @@
import { Breadcrumbs, Typography, Link as MuiLink } from '@mui/material';
import NavigateNextIcon from '@mui/icons-material/NavigateNext';
import { Link } from 'react-router-dom';
export interface BreadcrumbItem {
label: string;
href?: string;
}
interface Props {
items: BreadcrumbItem[];
}
export const PageBreadcrumbs = ({ items }: Props) => {
return (
<Breadcrumbs
separator={<NavigateNextIcon fontSize="small" />}
sx={{ mb: 2, fontSize: '0.8125rem' }}
>
{items.map((item, index) => {
const isLast = index === items.length - 1;
if (isLast || !item.href) {
return (
<Typography key={index} variant="body2" color="text.primary" fontWeight={500}>
{item.label}
</Typography>
);
}
return (
<MuiLink
key={index}
component={Link}
to={item.href}
underline="hover"
color="text.secondary"
variant="body2"
>
{item.label}
</MuiLink>
);
})}
</Breadcrumbs>
);
};

View File

@@ -0,0 +1,2 @@
export { PageBreadcrumbs } from './PageBreadcrumbs';
export type { BreadcrumbItem } from './PageBreadcrumbs';