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:
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useParams, Link, useNavigate, useLocation } from 'react-router-dom';
|
||||
import { useParams, Link, useNavigate } from 'react-router-dom';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { contractApi, uploadApi, meterApi, contractTaskApi, appSettingsApi } from '../../services/api';
|
||||
import { contractApi, uploadApi, meterApi, contractTaskApi, appSettingsApi, gdprApi } from '../../services/api';
|
||||
import { ContractEmailsSection } from '../../components/email';
|
||||
import { ContractDetailModal, ContractHistorySection } from '../../components/contracts';
|
||||
import InvoicesSection from '../../components/contracts/InvoicesSection';
|
||||
@@ -12,7 +12,7 @@ import Badge from '../../components/ui/Badge';
|
||||
import Input from '../../components/ui/Input';
|
||||
import Modal from '../../components/ui/Modal';
|
||||
import FileUpload from '../../components/ui/FileUpload';
|
||||
import { Edit, Trash2, Copy, Eye, EyeOff, ArrowLeft, ArrowRight, Download, ExternalLink, Plus, ChevronDown, ChevronUp, Gauge, CheckCircle, Circle, ClipboardList, MessageSquare, Calculator, Info, X, BellOff } from 'lucide-react';
|
||||
import { Edit, Trash2, Copy, Eye, EyeOff, ArrowLeft, ArrowRight, Download, ExternalLink, Plus, ChevronDown, ChevronUp, Gauge, CheckCircle, Circle, ClipboardList, MessageSquare, Calculator, Info, X, BellOff, Lock, Shield } from 'lucide-react';
|
||||
import { calculateConsumption, calculateCosts } from '../../utils/energyCalculations';
|
||||
import CopyButton, { CopyableBlock } from '../../components/ui/CopyButton';
|
||||
import type { ContractType, ContractStatus, SimCard, MeterReading, ContractTask, ContractTaskSubtask } from '../../types';
|
||||
@@ -1207,17 +1207,9 @@ function ContractTaskModal({
|
||||
);
|
||||
}
|
||||
|
||||
interface LocationState {
|
||||
from?: 'customer' | 'contracts' | 'cockpit';
|
||||
customerId?: string;
|
||||
filter?: string; // Für Cockpit-Filter
|
||||
}
|
||||
|
||||
export default function ContractDetail() {
|
||||
const { id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const locationState = location.state as LocationState | null;
|
||||
const queryClient = useQueryClient();
|
||||
const { hasPermission, isCustomer, isCustomerPortal } = useAuth();
|
||||
const contractId = parseInt(id!);
|
||||
@@ -1251,6 +1243,15 @@ export default function ContractDetail() {
|
||||
queryFn: () => contractApi.getById(contractId),
|
||||
});
|
||||
|
||||
// Consent-Check für den Kunden des Vertrags (nur für Mitarbeiter relevant)
|
||||
const contractCustomerId = data?.data?.customerId;
|
||||
const { data: consentStatusData } = useQuery({
|
||||
queryKey: ['consent-status', contractCustomerId],
|
||||
queryFn: () => gdprApi.checkConsentStatus(contractCustomerId!),
|
||||
enabled: !!contractCustomerId && !isCustomerPortal,
|
||||
});
|
||||
const hasConsentApproval = isCustomerPortal || (consentStatusData?.data?.hasConsent ?? true);
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: () => contractApi.delete(contractId),
|
||||
onSuccess: () => {
|
||||
@@ -1422,6 +1423,38 @@ export default function ContractDetail() {
|
||||
|
||||
const c = data.data;
|
||||
|
||||
// Consent-Sperrung: Vertrag nicht anzeigen wenn Kunde keine Einwilligung hat
|
||||
if (!hasConsentApproval) {
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center gap-4 mb-6">
|
||||
<Button variant="ghost" size="sm" onClick={() => navigate(-1)}>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
</Button>
|
||||
<h1 className="text-2xl font-bold">Vertrag {c.contractNumber}</h1>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center py-16 text-center">
|
||||
<div className="bg-amber-50 border border-amber-200 rounded-full p-4 mb-4">
|
||||
<Lock className="w-8 h-8 text-amber-500" />
|
||||
</div>
|
||||
<h2 className="text-lg font-semibold text-gray-800 mb-2">
|
||||
Datenschutz-Einwilligung erforderlich
|
||||
</h2>
|
||||
<p className="text-sm text-gray-600 mb-6 max-w-md">
|
||||
Die Vertragsdaten können nicht angezeigt werden, da der Kunde der Datenschutzerklärung noch nicht zugestimmt hat.
|
||||
</p>
|
||||
<Link
|
||||
to={`/customers/${c.customerId}?tab=consents`}
|
||||
className="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm"
|
||||
>
|
||||
<Shield className="w-4 h-4" />
|
||||
Zum Kunden: Einwilligungen / Datenschutz
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
@@ -1430,26 +1463,7 @@ export default function ContractDetail() {
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
// Zurück zur Herkunftsseite navigieren
|
||||
if (locationState?.from === 'customer' && locationState?.customerId) {
|
||||
// Kam von Kundendetail -> zurück zum Kunden mit Verträge-Tab
|
||||
navigate(`/customers/${locationState.customerId}?tab=contracts`);
|
||||
} else if (locationState?.from === 'cockpit') {
|
||||
// Kam vom Cockpit -> zurück zum Cockpit (mit Filter falls vorhanden)
|
||||
const filterParam = locationState.filter ? `?filter=${locationState.filter}` : '';
|
||||
navigate(`/contracts/cockpit${filterParam}`);
|
||||
} else if (locationState?.from === 'contracts') {
|
||||
// Kam von Vertragsliste -> zurück zur Vertragsliste (URL-Parameter bleiben erhalten)
|
||||
navigate('/contracts');
|
||||
} else if (c.customer) {
|
||||
// Fallback: Wenn Kunde vorhanden, zum Kunden
|
||||
navigate(`/customers/${c.customer.id}?tab=contracts`);
|
||||
} else {
|
||||
// Fallback: Zur Vertragsliste
|
||||
navigate('/contracts');
|
||||
}
|
||||
}}
|
||||
onClick={() => navigate(-1)}
|
||||
>
|
||||
<ArrowLeft className="w-4 h-4" />
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user