Dummydaten und Sprache angepasst

Dieser Commit ist enthalten in:
Claude Project Manager
2025-09-29 00:35:31 +02:00
Ursprung b462f69281
Commit e275b8fcd6
32 geänderte Dateien mit 122 neuen und 175 gelöschten Zeilen

Datei anzeigen

@ -46,9 +46,9 @@ export default function CreateEmployee() {
case 'stellvertreter':
return 'Stellvertretung'
case 'beauftragter':
return 'Beauftragte:r'
return 'Beauftragte Person'
default:
return 'Mitarbeiter:in'
return 'Teammitglied'
}
}
@ -73,9 +73,9 @@ export default function CreateEmployee() {
if (response.data.data?.temporaryPassword) {
setCreatedUser({ password: response.data.data.temporaryPassword })
setSuccess(`Mitarbeiter und Benutzerkonto erfolgreich erstellt!`)
setSuccess(`Profil und Benutzerkonto erfolgreich erstellt!`)
} else {
setSuccess('Mitarbeiter erfolgreich erstellt!')
setSuccess('Profil erfolgreich erstellt!')
}
} catch (err: any) {
console.error('Error:', err.response?.data)
@ -96,8 +96,8 @@ export default function CreateEmployee() {
const getRoleDescription = (role: UserRole): string => {
const descriptions = {
admin: 'Vollzugriff auf alle Funktionen inklusive Admin Panel und Benutzerverwaltung',
superuser: 'Kann Mitarbeiter anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeiter durchsuchen'
superuser: 'Kann Mitarbeitende anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeitende durchsuchen'
}
return descriptions[role]
}
@ -112,10 +112,10 @@ export default function CreateEmployee() {
Zurück zur Benutzerverwaltung
</button>
<h1 className="text-title-lg font-poppins font-bold text-primary">
Neuen Mitarbeiter & Benutzer anlegen
Neues Mitarbeitendenprofil & Benutzer anlegen
</h1>
<p className="text-body text-secondary mt-2">
Erstellen Sie einen neuen Mitarbeiter-Datensatz und optional ein Benutzerkonto
Erstellen Sie ein neues Profil und optional ein Benutzerkonto
</p>
</div>
@ -141,7 +141,7 @@ export default function CreateEmployee() {
{createdUser.password}
</code>
<p className="text-sm mt-2 text-green-700">
Bitte notieren Sie dieses Passwort und geben Sie es sicher an den Mitarbeiter weiter.
Bitte notieren Sie dieses Passwort und geben Sie es sicher an die betreffende Person weiter.
Das Passwort muss beim ersten Login geändert werden.
</p>
<div className="mt-4 flex justify-end">
@ -160,7 +160,7 @@ export default function CreateEmployee() {
<div className="card mb-6">
<h2 className="text-title-card font-poppins font-semibold text-primary mb-6">
Mitarbeiter-Grunddaten
Grunddaten des Profils
</h2>
<div className="grid grid-cols-2 gap-4">
@ -251,7 +251,7 @@ export default function CreateEmployee() {
}}
/>
<p className="text-sm text-secondary-light mt-2">
Wählen Sie die primäre Organisationseinheit für den neuen Mitarbeiter. Die Abteilung wird automatisch anhand der Auswahl gesetzt.
Wählen Sie die primäre Organisationseinheit für die neue Person. Die Abteilung wird automatisch anhand der Auswahl gesetzt.
</p>
</div>
@ -265,10 +265,10 @@ export default function CreateEmployee() {
onChange={event => setSelectedUnitRole(event.target.value as EmployeeUnitRole)}
className="input-field w-full"
>
<option value="leiter">Leiter:in</option>
<option value="leiter">Leitung</option>
<option value="stellvertreter">Stellvertretung</option>
<option value="mitarbeiter">Mitarbeiter:in</option>
<option value="beauftragter">Beauftragte:r</option>
<option value="mitarbeiter">Teammitglied</option>
<option value="beauftragter">Beauftragte Person</option>
</select>
<p className="text-sm text-secondary-light mt-2">
Diese Rolle wird für Vertretungs- und Organigramm-Funktionen verwendet.
@ -296,7 +296,7 @@ export default function CreateEmployee() {
</span>
</label>
<p className="text-sm text-secondary-light mt-2 ml-7">
Erstellt ein Benutzerkonto, mit dem sich der Mitarbeiter im System anmelden kann.
Erstellt ein Benutzerkonto, mit dem sich die angelegte Person im System anmelden kann.
Ein sicheres temporäres Passwort wird automatisch generiert.
</p>
</div>
@ -327,10 +327,10 @@ export default function CreateEmployee() {
📋 Was passiert als Nächstes?
</h3>
<ul className="space-y-2 text-body text-secondary">
<li> Der Mitarbeiter wird mit Grunddaten angelegt (Position: "Mitarbeiter", Telefon: "Nicht angegeben")</li>
<li> Die Person wird mit Grunddaten angelegt (Position: "Teammitglied", Telefon: "Nicht angegeben")</li>
<li> {watchCreateUser ? 'Ein Benutzerkonto wird erstellt und ein temporäres Passwort generiert' : 'Kein Benutzerkonto wird erstellt'}</li>
<li> {selectedUnitId ? `Die Organisationseinheit ${selectedUnitName} (${getUnitRoleLabel(selectedUnitRole)}) wird als primäre Zuordnung hinterlegt` : 'Organisationseinheit kann später im Organigramm zugewiesen werden'}</li>
<li> Der Mitarbeiter kann später im Frontend seine Profildaten vervollständigen</li>
<li> Die Person kann später im Frontend das Profil vervollständigen</li>
<li> Alle Daten werden verschlüsselt in der Datenbank gespeichert</li>
</ul>
</div>
@ -349,7 +349,7 @@ export default function CreateEmployee() {
className="btn-primary"
disabled={loading}
>
{loading ? 'Erstelle...' : 'Mitarbeiter erstellen'}
{loading ? 'Erstelle...' : 'Profil erstellen'}
</button>
</div>
</form>

Datei anzeigen

@ -1,19 +1,15 @@
import { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { api } from '../services/api'
import SyncStatus from '../components/SyncStatus'
interface DashboardStats {
totalEmployees: number
totalSkills: number
totalUsers: number
lastSync?: {
timestamp: string
success: boolean
itemsSynced: number
}
}
export default function Dashboard() {
const navigate = useNavigate()
const [stats, setStats] = useState<DashboardStats>({
totalEmployees: 0,
totalSkills: 0,
@ -65,23 +61,19 @@ export default function Dashboard() {
const statsCards = [
{
title: 'Mitarbeiter',
title: 'Mitarbeitende',
value: stats.totalEmployees,
color: 'text-primary-blue',
bgColor: 'bg-bg-accent',
path: '/users'
},
{
title: 'Skills',
value: stats.totalSkills,
color: 'text-success',
bgColor: 'bg-success-bg',
},
{
title: 'Benutzer',
value: stats.totalUsers,
color: 'text-info',
bgColor: 'bg-info-bg',
},
path: '/skills'
}
]
return (
@ -90,9 +82,14 @@ export default function Dashboard() {
Dashboard
</h1>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
{statsCards.map((stat, index) => (
<div key={index} className="card">
<button
key={index}
type="button"
onClick={() => navigate(stat.path)}
className="card text-left transition hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-primary-blue"
>
<div className={`w-16 h-16 rounded-card ${stat.bgColor} flex items-center justify-center mb-4`}>
<span className={`text-2xl font-bold ${stat.color}`}>
{stat.value}
@ -101,60 +98,11 @@ export default function Dashboard() {
<h3 className="text-body font-medium text-tertiary">
{stat.title}
</h3>
</div>
</button>
))}
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<div className="card">
<h2 className="text-title-card font-poppins font-semibold text-primary mb-4">
Letzte Synchronisation
</h2>
{stats.lastSync ? (
<div className="space-y-2">
<p className="text-body text-secondary">
<span className="font-medium">Zeitpunkt:</span>{' '}
{new Date(stats.lastSync.timestamp).toLocaleString('de-DE')}
</p>
<p className="text-body text-secondary">
<span className="font-medium">Status:</span>{' '}
<span className={stats.lastSync.success ? 'text-success' : 'text-error'}>
{stats.lastSync.success ? 'Erfolgreich' : 'Fehlgeschlagen'}
</span>
</p>
<p className="text-body text-secondary">
<span className="font-medium">Synchronisierte Elemente:</span>{' '}
{stats.lastSync.itemsSynced}
</p>
</div>
) : (
<p className="text-body text-tertiary">
Noch keine Synchronisation durchgeführt
</p>
)}
</div>
<div className="card">
<h2 className="text-title-card font-poppins font-semibold text-primary mb-4">
Systemstatus
</h2>
<div className="space-y-2">
<p className="text-body text-secondary">
<span className="font-medium">Backend:</span>{' '}
<span className="text-success">Online</span>
</p>
<p className="text-body text-secondary">
<span className="font-medium">Datenbank:</span>{' '}
<span className="text-success">Verbunden</span>
</p>
<p className="text-body text-secondary">
<span className="font-medium">Version:</span> 1.0.0
</p>
</div>
</div>
</div>
<SyncStatus />
</div>
)
}

Datei anzeigen

@ -44,7 +44,7 @@ export default function EmployeeForm() {
})
} catch (error) {
console.error('Failed to fetch employee:', error)
setError('Mitarbeiter konnte nicht geladen werden')
setError('Profil konnte nicht geladen werden')
}
}
@ -80,8 +80,8 @@ export default function EmployeeForm() {
const getRoleDescription = (role: UserRole): string => {
const descriptions = {
admin: 'Vollzugriff auf alle Funktionen inklusive Admin Panel und Benutzerverwaltung',
superuser: 'Kann Mitarbeiter anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeiter durchsuchen'
superuser: 'Kann Mitarbeitende anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeitende durchsuchen'
}
return descriptions[role]
}
@ -96,7 +96,7 @@ export default function EmployeeForm() {
Zurück zur Übersicht
</button>
<h1 className="text-title-lg font-poppins font-bold text-primary">
{isEdit ? 'Mitarbeiter bearbeiten' : 'Neuer Mitarbeiter'}
{isEdit ? 'Mitarbeitendenprofil bearbeiten' : 'Neues Mitarbeitendenprofil'}
</h1>
</div>
@ -109,7 +109,7 @@ export default function EmployeeForm() {
<div className="card mb-6">
<h2 className="text-title-card font-poppins font-semibold text-primary mb-6">
Mitarbeiterdaten
Profilinformationen
</h2>
<div className="grid grid-cols-2 gap-4">
@ -192,7 +192,7 @@ export default function EmployeeForm() {
className="w-5 h-5 rounded border-border-input text-primary-blue focus:ring-primary-blue"
/>
<span className="text-body text-secondary">
Benutzerkonto für diesen Mitarbeiter erstellen
Benutzerkonto für diese Person erstellen
</span>
</label>
<p className="text-small text-tertiary mt-1">
@ -242,10 +242,10 @@ export default function EmployeeForm() {
disabled={loading}
className="btn-primary disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? 'Speichern...' : (isEdit ? 'Änderungen speichern' : 'Mitarbeiter anlegen')}
{loading ? 'Speichern...' : (isEdit ? 'Änderungen speichern' : 'Profil anlegen')}
</button>
</div>
</form>
</div>
)
}
}

Datei anzeigen

@ -66,7 +66,7 @@ export default function EmployeeFormComplete() {
})
} catch (error) {
console.error('Failed to fetch employee:', error)
setError('Mitarbeiter konnte nicht geladen werden')
setError('Profil konnte nicht geladen werden')
}
}
@ -97,15 +97,15 @@ export default function EmployeeFormComplete() {
let response
if (isEdit) {
response = await api.put(`/employees/${id}`, payload)
setSuccess('Mitarbeiter erfolgreich aktualisiert!')
setSuccess('Profil erfolgreich aktualisiert!')
} else {
response = await api.post('/employees', payload)
if (response.data.data.temporaryPassword) {
setCreatedUser({ password: response.data.data.temporaryPassword })
setSuccess(`Mitarbeiter erfolgreich erstellt! Temporäres Passwort: ${response.data.data.temporaryPassword}`)
setSuccess(`Profil erfolgreich erstellt! Temporäres Passwort: ${response.data.data.temporaryPassword}`)
} else {
setSuccess('Mitarbeiter erfolgreich erstellt!')
setSuccess('Profil erfolgreich erstellt!')
}
}
@ -131,8 +131,8 @@ export default function EmployeeFormComplete() {
const getRoleDescription = (role: UserRole): string => {
const descriptions = {
admin: 'Vollzugriff auf alle Funktionen inklusive Admin Panel und Benutzerverwaltung',
superuser: 'Kann Mitarbeiter anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeiter durchsuchen'
superuser: 'Kann Mitarbeitende anlegen und verwalten, aber kein Zugriff auf Admin Panel',
user: 'Kann nur das eigene Profil bearbeiten und Mitarbeitende durchsuchen'
}
return descriptions[role]
}
@ -147,7 +147,7 @@ export default function EmployeeFormComplete() {
Zurück zur Übersicht
</button>
<h1 className="text-title-lg font-poppins font-bold text-primary">
{isEdit ? 'Mitarbeiter bearbeiten' : 'Neuer Mitarbeiter'}
{isEdit ? 'Mitarbeitendenprofil bearbeiten' : 'Neues Mitarbeitendenprofil'}
</h1>
</div>
@ -207,10 +207,10 @@ export default function EmployeeFormComplete() {
<div>
<label className="block text-body font-medium text-secondary mb-2">
Mitarbeiternummer *
Personalnummer *
</label>
<input
{...register('employeeNumber', { required: 'Mitarbeiternummer ist erforderlich' })}
{...register('employeeNumber', { required: 'Personalnummer ist erforderlich' })}
className="input-field w-full"
placeholder="EMP001"
/>
@ -346,7 +346,7 @@ export default function EmployeeFormComplete() {
className="w-5 h-5 rounded border-border-input text-primary-blue focus:ring-primary-blue"
/>
<span className="text-body font-medium text-secondary">
Benutzerkonto für diesen Mitarbeiter erstellen
Benutzerkonto für diese Person erstellen
</span>
</label>
<p className="text-sm text-secondary-light mt-1 ml-7">
@ -395,4 +395,4 @@ export default function EmployeeFormComplete() {
</form>
</div>
)
}
}

Datei anzeigen

@ -33,7 +33,7 @@ export default function EmployeeManagement() {
if (loading) {
return (
<div className="flex items-center justify-center h-full">
<p className="text-tertiary">Mitarbeiter werden geladen...</p>
<p className="text-tertiary">Mitarbeitende werden geladen...</p>
</div>
)
}
@ -42,13 +42,13 @@ export default function EmployeeManagement() {
<div>
<div className="flex justify-between items-center mb-8">
<h1 className="text-title-lg font-poppins font-bold text-primary">
Mitarbeiterverwaltung
Mitarbeitendenverwaltung
</h1>
<button
onClick={() => navigate('/employees/new')}
className="btn-primary"
>
Neuer Mitarbeiter
Neues Mitarbeitendenprofil
</button>
</div>
@ -110,10 +110,10 @@ export default function EmployeeManagement() {
{filteredEmployees.length === 0 && (
<div className="text-center py-8">
<p className="text-tertiary">Keine Mitarbeiter gefunden</p>
<p className="text-tertiary">Keine Mitarbeitenden gefunden</p>
</div>
)}
</div>
</div>
)
}
}

Datei anzeigen

@ -68,7 +68,7 @@ const OrganizationNode = ({ data }: { data: any }) => {
</h4>
{data.employeeCount !== undefined && (
<p className="text-[11px] text-slate-600 mt-1">
👥 {data.employeeCount} Mitarbeiter
👥 {data.employeeCount} Mitarbeitende
</p>
)}
{data.hasFuehrungsstelle && (

Datei anzeigen

@ -454,7 +454,7 @@ export default function SyncSettings() {
checked={syncSettings.syncEmployees}
onChange={(e) => setSyncSettings({ ...syncSettings, syncEmployees: e.target.checked })}
/>
<span className="text-sm">Mitarbeiterdaten</span>
<span className="text-sm">Daten der Mitarbeitenden</span>
</label>
<label className="flex items-center">
<input
@ -514,4 +514,4 @@ export default function SyncSettings() {
</div>
</div>
)
}
}

Datei anzeigen

@ -277,7 +277,7 @@ export default function UserManagement() {
onClick={() => navigate('/users/create-employee')}
className="btn-primary"
>
+ Neuen Mitarbeiter anlegen
+ Neues Mitarbeitendenprofil anlegen
</button>
</div>
@ -303,7 +303,7 @@ export default function UserManagement() {
Benutzer
</th>
<th className="text-left py-3 px-4 font-poppins font-medium text-secondary">
Mitarbeiter
Mitarbeitende
</th>
<th className="text-left py-3 px-4 font-poppins font-medium text-secondary">
Rolle
@ -483,9 +483,9 @@ export default function UserManagement() {
</h3>
<ul className="space-y-2 text-body text-secondary">
<li> <strong>Administrator:</strong> Vollzugriff auf alle Funktionen und Einstellungen</li>
<li> <strong>Poweruser:</strong> Kann Mitarbeiter und Skills verwalten, aber keine Systemeinstellungen ändern</li>
<li> <strong>Poweruser:</strong> Kann Mitarbeitende und Skills verwalten, aber keine Systemeinstellungen ändern</li>
<li> <strong>Benutzer:</strong> Kann nur eigenes Profil bearbeiten und Daten einsehen</li>
<li> Neue Benutzer können über den Import oder die Mitarbeiterverwaltung angelegt werden</li>
<li> Neue Benutzer können über den Import oder die Mitarbeitendenverwaltung angelegt werden</li>
<li> Der Admin-Benutzer kann nicht gelöscht werden</li>
</ul>
</div>