This commit is contained in:
Matthias Hochmeister
2026-02-23 17:08:58 +01:00
commit f09748f4a1
97 changed files with 17729 additions and 0 deletions

View File

@@ -0,0 +1,262 @@
import {
Container,
Paper,
Box,
Typography,
Avatar,
Grid,
TextField,
Card,
CardContent,
Divider,
Chip,
} from '@mui/material';
import { Person, Email, Badge, Group, AccessTime } from '@mui/icons-material';
import { useAuth } from '../contexts/AuthContext';
import DashboardLayout from '../components/dashboard/DashboardLayout';
function Profile() {
const { user } = useAuth();
if (!user) {
return null;
}
// Get initials for large avatar
const getInitials = () => {
const initials = (user.given_name?.[0] || '') + (user.family_name?.[0] || '');
return initials || user.name?.[0] || '?';
};
// Format date (if we had lastLogin)
const formatDate = (date?: Date | string) => {
if (!date) return 'Nicht verfügbar';
const d = typeof date === 'string' ? new Date(date) : date;
return d.toLocaleDateString('de-DE', {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
};
return (
<DashboardLayout>
<Container maxWidth="lg">
<Typography variant="h4" gutterBottom sx={{ mb: 4 }}>
Mein Profil
</Typography>
<Grid container spacing={3}>
{/* User Info Card */}
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
py: 2,
}}
>
<Avatar
sx={{
bgcolor: 'primary.main',
width: 120,
height: 120,
fontSize: '3rem',
mb: 2,
}}
>
{getInitials()}
</Avatar>
<Typography variant="h5" gutterBottom>
{user.name}
</Typography>
<Typography variant="body2" color="text.secondary" gutterBottom>
{user.email}
</Typography>
{user.preferred_username && (
<Typography
variant="body2"
color="text.secondary"
sx={{ display: 'flex', alignItems: 'center', gap: 0.5, mt: 1 }}
>
<Badge fontSize="small" />
@{user.preferred_username}
</Typography>
)}
</Box>
<Divider sx={{ my: 2 }} />
{/* Groups/Roles */}
{user.groups && user.groups.length > 0 && (
<Box sx={{ mt: 2 }}>
<Typography
variant="subtitle2"
color="text.secondary"
gutterBottom
sx={{ display: 'flex', alignItems: 'center', gap: 0.5 }}
>
<Group fontSize="small" />
Gruppen
</Typography>
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, mt: 1 }}>
{user.groups.map((group) => (
<Chip key={group} label={group} size="small" color="primary" />
))}
</Box>
</Box>
)}
</CardContent>
</Card>
</Grid>
{/* Personal Information */}
<Grid item xs={12} md={8}>
<Card>
<CardContent>
<Typography variant="h6" gutterBottom sx={{ mb: 3 }}>
Persönliche Informationen
</Typography>
<Grid container spacing={3}>
<Grid item xs={12} sm={6}>
<TextField
fullWidth
label="Vorname"
value={user.given_name || ''}
InputProps={{
readOnly: true,
startAdornment: (
<Person sx={{ mr: 1, color: 'text.secondary' }} />
),
}}
variant="outlined"
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
fullWidth
label="Nachname"
value={user.family_name || ''}
InputProps={{
readOnly: true,
startAdornment: (
<Person sx={{ mr: 1, color: 'text.secondary' }} />
),
}}
variant="outlined"
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth
label="E-Mail-Adresse"
value={user.email}
InputProps={{
readOnly: true,
startAdornment: (
<Email sx={{ mr: 1, color: 'text.secondary' }} />
),
}}
variant="outlined"
helperText="E-Mail-Adresse wird von Authentik verwaltet"
/>
</Grid>
{user.preferred_username && (
<Grid item xs={12}>
<TextField
fullWidth
label="Benutzername"
value={user.preferred_username}
InputProps={{
readOnly: true,
startAdornment: (
<Badge sx={{ mr: 1, color: 'text.secondary' }} />
),
}}
variant="outlined"
/>
</Grid>
)}
</Grid>
<Box
sx={{
mt: 3,
p: 2,
backgroundColor: 'info.lighter',
borderRadius: 1,
}}
>
<Typography variant="body2" color="info.dark">
Diese Informationen werden von Authentik verwaltet und können hier nicht
bearbeitet werden. Bitte wenden Sie sich an Ihren Administrator, um
Änderungen vorzunehmen.
</Typography>
</Box>
</CardContent>
</Card>
{/* Activity Information */}
<Card sx={{ mt: 3 }}>
<CardContent>
<Typography variant="h6" gutterBottom sx={{ mb: 3 }}>
Aktivitätsinformationen
</Typography>
<Grid container spacing={2}>
<Grid item xs={12}>
<Box
sx={{
display: 'flex',
alignItems: 'center',
gap: 2,
p: 2,
backgroundColor: 'background.default',
borderRadius: 1,
}}
>
<AccessTime color="primary" />
<Box>
<Typography variant="body2" color="text.secondary">
Letzte Anmeldung
</Typography>
<Typography variant="body1">
{formatDate(new Date())}
</Typography>
</Box>
</Box>
</Grid>
</Grid>
</CardContent>
</Card>
{/* User Preferences */}
<Card sx={{ mt: 3 }}>
<CardContent>
<Typography variant="h6" gutterBottom sx={{ mb: 3 }}>
Benutzereinstellungen
</Typography>
<Typography variant="body2" color="text.secondary">
Kommende Features: Benachrichtigungseinstellungen, Anzeigeoptionen,
Spracheinstellungen
</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
</Container>
</DashboardLayout>
);
}
export default Profile;