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

@@ -1,5 +1,5 @@
import React, { createContext, useCallback, useContext, useState, useEffect, ReactNode } from 'react';
import { AuthContextType, AuthState } from '../types/auth.types';
import { AuthContextType, AuthState, LoginResult } from '../types/auth.types';
import { authService } from '../services/auth';
import { getToken, setToken, removeToken, getUser, setUser, removeUser, setRefreshToken, removeRefreshToken } from '../utils/storage';
import { useNotification } from './NotificationContext';
@@ -67,11 +67,11 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
initializeAuth();
}, []);
const login = useCallback(async (code: string): Promise<void> => {
const login = useCallback(async (code: string): Promise<LoginResult> => {
try {
setState((prev) => ({ ...prev, isLoading: true }));
const { token, refreshToken, user } = await authService.handleCallback(code);
const { token, refreshToken, user, isNewUser } = await authService.handleCallback(code);
// Save to localStorage
setToken(token);
@@ -88,6 +88,8 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({ children }) => {
// Show success notification
notification.showSuccess('Anmeldung erfolgreich');
return { isNewUser };
} catch (error) {
console.error('Login failed:', error);
setState({