263 lines
8.5 KiB
TypeScript
263 lines
8.5 KiB
TypeScript
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.light',
|
|
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;
|