This commit is contained in:
Matthias Hochmeister
2026-03-13 14:31:58 +01:00
parent 4c7c8f72d3
commit 1cdfde0128

View File

@@ -15,10 +15,10 @@ import {
CircularProgress, CircularProgress,
Button, Button,
Chip, Chip,
TextField,
} from '@mui/material'; } from '@mui/material';
import { Settings as SettingsIcon, Notifications, Palette, Language, SettingsBrightness, LightMode, DarkMode, Widgets, Cloud, LinkOff, Forum, Badge } from '@mui/icons-material'; import { Settings as SettingsIcon, Notifications, Palette, Language, SettingsBrightness, LightMode, DarkMode, Widgets, Cloud, LinkOff, Forum, Person, OpenInNew } from '@mui/icons-material';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import DashboardLayout from '../components/dashboard/DashboardLayout'; import DashboardLayout from '../components/dashboard/DashboardLayout';
import { useThemeMode } from '../contexts/ThemeContext'; import { useThemeMode } from '../contexts/ThemeContext';
import { preferencesApi } from '../services/settings'; import { preferencesApi } from '../services/settings';
@@ -26,7 +26,6 @@ import { WIDGETS, WidgetKey } from '../constants/widgets';
import { nextcloudApi } from '../services/nextcloud'; import { nextcloudApi } from '../services/nextcloud';
import { useNotification } from '../contexts/NotificationContext'; import { useNotification } from '../contexts/NotificationContext';
import { useAuth } from '../contexts/AuthContext'; import { useAuth } from '../contexts/AuthContext';
import { membersService } from '../services/members';
const POLL_INTERVAL = 2000; const POLL_INTERVAL = 2000;
const POLL_TIMEOUT = 5 * 60 * 1000; const POLL_TIMEOUT = 5 * 60 * 1000;
@@ -34,35 +33,9 @@ const POLL_TIMEOUT = 5 * 60 * 1000;
function Settings() { function Settings() {
const { themeMode, setThemeMode } = useThemeMode(); const { themeMode, setThemeMode } = useThemeMode();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const { showInfo, showSuccess, showError } = useNotification(); const { showInfo } = useNotification();
const { user } = useAuth(); const { user } = useAuth();
const navigate = useNavigate();
// FDISK Standesbuchnummer
const [standesNr, setStandesNr] = useState('');
const [standesNrEdited, setStandesNrEdited] = useState(false);
const { data: memberProfile, isLoading: profileLoading } = useQuery({
queryKey: ['member', user?.id],
queryFn: () => membersService.getMember(user!.id),
enabled: !!user?.id,
});
useEffect(() => {
if (memberProfile?.profile?.fdisk_standesbuch_nr != null) {
setStandesNr(memberProfile.profile.fdisk_standesbuch_nr);
}
}, [memberProfile]);
const standesNrMutation = useMutation({
mutationFn: (value: string) =>
membersService.updateMember(user!.id, { fdisk_standesbuch_nr: value || undefined }),
onSuccess: () => {
showSuccess('Standesbuchnummer gespeichert');
setStandesNrEdited(false);
queryClient.invalidateQueries({ queryKey: ['member', user?.id] });
},
onError: () => showError('Speichern fehlgeschlagen'),
});
const { data: preferences, isLoading: prefsLoading } = useQuery({ const { data: preferences, isLoading: prefsLoading } = useQuery({
queryKey: ['user-preferences'], queryKey: ['user-preferences'],
@@ -282,45 +255,27 @@ function Settings() {
</Card> </Card>
</Grid> </Grid>
{/* FDISK-Profil */} {/* Mitgliedsprofil */}
<Grid item xs={12} md={6}> <Grid item xs={12} md={6}>
<Card> <Card>
<CardContent> <CardContent>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}> <Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<Badge color="primary" sx={{ mr: 2 }} /> <Person color="primary" sx={{ mr: 2 }} />
<Typography variant="h6">FDISK-Profil</Typography> <Typography variant="h6">Mitgliedsprofil</Typography>
</Box> </Box>
<Divider sx={{ mb: 2 }} /> <Divider sx={{ mb: 2 }} />
<Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}> <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
Die Standesbuchnummer wird für die automatische FDISK-Synchronisation verwendet. Persönliche Daten, Standesbuchnummer und weitere Profileinstellungen.
</Typography> </Typography>
{profileLoading ? (
<Box sx={{ display: 'flex', justifyContent: 'center', py: 1 }}>
<CircularProgress size={24} />
</Box>
) : (
<Box sx={{ display: 'flex', gap: 1, alignItems: 'center' }}>
<TextField
label="Standesbuchnummer"
size="small"
value={standesNr}
onChange={(e) => {
setStandesNr(e.target.value);
setStandesNrEdited(true);
}}
placeholder="z.B. 123456"
sx={{ flex: 1 }}
/>
<Button <Button
variant="outlined" variant="outlined"
size="small" size="small"
disabled={!standesNrEdited || standesNrMutation.isPending} startIcon={<OpenInNew />}
onClick={() => standesNrMutation.mutate(standesNr)} onClick={() => navigate(`/mitglieder/${user?.id}`)}
disabled={!user?.id}
> >
Speichern Zum Mitgliedsprofil
</Button> </Button>
</Box>
)}
</CardContent> </CardContent>
</Card> </Card>
</Grid> </Grid>