gdpr audit implemented, email log, vollmachten, pdf delete cancel data privacy and vollmachten, removed message no id card in engergy car, and other contracts that are not telecom contracts, added insert counter for engery

This commit is contained in:
2026-03-21 11:59:53 +01:00
parent 09e87c951b
commit c3edb8ad2e
1491 changed files with 265550 additions and 1292 deletions
+70 -5
View File
@@ -7,7 +7,7 @@ import Button from '../../components/ui/Button';
import Input from '../../components/ui/Input';
import Modal from '../../components/ui/Modal';
import Badge from '../../components/ui/Badge';
import { Plus, Edit, Trash2, Search, Code, AlertTriangle, ArrowLeft, Info } from 'lucide-react';
import { Plus, Edit, Trash2, Search, Code, Shield, AlertTriangle, ArrowLeft, Info } from 'lucide-react';
import { Link } from 'react-router-dom';
import type { User, Role } from '../../types';
@@ -121,7 +121,7 @@ export default function UserList() {
<td className="py-3 px-4">{user.email}</td>
<td className="py-3 px-4">
<div className="flex gap-1 flex-wrap">
{user.roles?.filter((role: any) => role.name !== 'Developer').map((role: any) => (
{user.roles?.filter((role: any) => !['Developer', 'Kunde', 'DSGVO'].includes(role.name)).map((role: any) => (
<Badge key={role.id || role.name} variant="info">
{role.name}
</Badge>
@@ -139,6 +139,12 @@ export default function UserList() {
Dev
</Badge>
)}
{(user as any).hasGdprAccess && (
<Badge variant="info" className="flex items-center gap-1">
<Shield className="w-3 h-3" />
DSGVO
</Badge>
)}
</div>
</td>
<td className="py-3 px-4 text-right">
@@ -237,6 +243,10 @@ function UserModal({
roleIds: [] as number[],
isActive: true,
hasDeveloperAccess: false,
hasGdprAccess: false,
whatsappNumber: '',
telegramUsername: '',
signalNumber: '',
});
// Reset form when modal opens or user changes
@@ -249,9 +259,13 @@ function UserModal({
password: '',
firstName: user.firstName,
lastName: user.lastName,
roleIds: user.roles?.filter((r: any) => r.name !== 'Developer').map((r: any) => r.id) || [],
roleIds: user.roles?.filter((r: any) => !['Developer', 'Kunde', 'DSGVO'].includes(r.name)).map((r: any) => r.id) || [],
isActive: (user as any).isActive ?? true,
hasDeveloperAccess: (user as any).hasDeveloperAccess ?? false,
hasGdprAccess: (user as any).hasGdprAccess ?? false,
whatsappNumber: (user as any).whatsappNumber || '',
telegramUsername: (user as any).telegramUsername || '',
signalNumber: (user as any).signalNumber || '',
});
} else {
setFormData({
@@ -262,6 +276,10 @@ function UserModal({
roleIds: [],
isActive: true,
hasDeveloperAccess: false,
hasGdprAccess: false,
whatsappNumber: '',
telegramUsername: '',
signalNumber: '',
});
}
}
@@ -300,6 +318,10 @@ function UserModal({
roleIds: formData.roleIds,
isActive: formData.isActive,
hasDeveloperAccess: formData.hasDeveloperAccess,
hasGdprAccess: formData.hasGdprAccess,
whatsappNumber: formData.whatsappNumber || undefined,
telegramUsername: formData.telegramUsername || undefined,
signalNumber: formData.signalNumber || undefined,
};
if (formData.password) {
updateData.password = formData.password;
@@ -313,6 +335,10 @@ function UserModal({
lastName: formData.lastName,
roleIds: formData.roleIds,
hasDeveloperAccess: formData.hasDeveloperAccess,
hasGdprAccess: formData.hasGdprAccess,
whatsappNumber: formData.whatsappNumber || undefined,
telegramUsername: formData.telegramUsername || undefined,
signalNumber: formData.signalNumber || undefined,
});
}
};
@@ -372,10 +398,34 @@ function UserModal({
required={!user}
/>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Messaging-Kanäle (für Datenschutz-Versand)</label>
<div className="space-y-3">
<Input
label="WhatsApp-Nummer"
placeholder="+49..."
value={formData.whatsappNumber}
onChange={(e) => setFormData({ ...formData, whatsappNumber: e.target.value })}
/>
<Input
label="Telegram-Benutzername"
placeholder="@username"
value={formData.telegramUsername}
onChange={(e) => setFormData({ ...formData, telegramUsername: e.target.value })}
/>
<Input
label="Signal-Nummer"
placeholder="+49..."
value={formData.signalNumber}
onChange={(e) => setFormData({ ...formData, signalNumber: e.target.value })}
/>
</div>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-2">Rollen</label>
<div className="space-y-2">
{roles.filter((role) => role.name !== 'Developer').map((role) => (
{roles.filter((role) => !['Developer', 'Kunde', 'DSGVO'].includes(role.name)).map((role) => (
<label key={role.id} className="flex items-center gap-2">
<input
type="checkbox"
@@ -389,7 +439,22 @@ function UserModal({
)}
</label>
))}
{/* Entwicklerzugriff direkt unter den Rollen */}
</div>
<label className="block text-sm font-medium text-gray-700 mt-4 mb-2">Zusätzliche Berechtigungen</label>
<div className="space-y-2">
<label className="flex items-center gap-2">
<input
type="checkbox"
checked={formData.hasGdprAccess}
onChange={(e) => setFormData({ ...formData, hasGdprAccess: e.target.checked })}
className="rounded border-blue-300 text-blue-600 focus:ring-blue-500"
/>
<span className="flex items-center gap-1">
<Shield className="w-4 h-4 text-blue-600" />
DSGVO-Zugriff
</span>
<span className="text-sm text-gray-500">(Audit-Logs, Datenschutz)</span>
</label>
<label className="flex items-center gap-2">
<input
type="checkbox"