Files
breakpilot-compliance/admin-compliance/app/sdk/dsr/[requestId]/_hooks/useDSRDetail.ts
Sharang Parnerkar cc3a9a37dc refactor(admin): split dsr/[requestId] page.tsx into colocated components
Split the 854-line DSR detail page into colocated components under
_components/ and a data-loading hook under _hooks/. No behavior changes.

page.tsx is now 172 LOC, all extracted files under 300 LOC.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 08:20:24 +02:00

205 lines
6.1 KiB
TypeScript

'use client'
import { useState, useEffect } from 'react'
import {
DSRRequest,
DSRCommunication,
DSRVerifyIdentityRequest,
} from '@/lib/sdk/dsr/types'
import {
fetchSDKDSR,
verifyDSRIdentity,
assignDSR,
extendDSRDeadline,
completeDSR,
rejectDSR,
fetchDSRCommunications,
sendDSRCommunication,
fetchDSRExceptionChecks,
initDSRExceptionChecks,
updateDSRExceptionCheck,
fetchDSRHistory,
} from '@/lib/sdk/dsr/api'
export function useDSRDetail(requestId: string) {
const [request, setRequest] = useState<DSRRequest | null>(null)
const [communications, setCommunications] = useState<DSRCommunication[]>([])
const [history, setHistory] = useState<any[]>([])
const [exceptionChecks, setExceptionChecks] = useState<any[]>([])
const [isLoading, setIsLoading] = useState(true)
// Load data from SDK backend
useEffect(() => {
const loadData = async () => {
setIsLoading(true)
try {
const found = await fetchSDKDSR(requestId)
if (found) {
setRequest(found)
// Load communications, history, and exception checks in parallel
const [comms, hist] = await Promise.all([
fetchDSRCommunications(requestId).catch(() => []),
fetchDSRHistory(requestId).catch(() => []),
])
setCommunications(comms.map((c: any) => ({
id: c.id,
dsrId: c.dsr_id,
type: c.communication_type,
channel: c.channel,
subject: c.subject,
content: c.content,
createdAt: c.created_at,
createdBy: c.created_by,
sentAt: c.sent_at,
sentBy: c.sent_by,
})))
setHistory(hist)
// Load exception checks for erasure requests
if (found.type === 'erasure') {
try {
const checks = await fetchDSRExceptionChecks(requestId)
if (checks.length === 0) {
// Auto-initialize if none exist
const initialized = await initDSRExceptionChecks(requestId)
setExceptionChecks(initialized)
} else {
setExceptionChecks(checks)
}
} catch {
setExceptionChecks([])
}
}
}
} catch (error) {
console.error('Failed to load DSR:', error)
} finally {
setIsLoading(false)
}
}
loadData()
}, [requestId])
const handleVerifyIdentity = async (verification: DSRVerifyIdentityRequest) => {
if (!request) return
try {
const updated = await verifyDSRIdentity(request.id, {
method: verification.method,
notes: verification.notes,
document_ref: verification.documentRef,
})
setRequest(updated)
fetchDSRHistory(requestId).then(setHistory).catch(() => {})
} catch (err) {
console.error('Failed to verify identity:', err)
}
}
const handleAssign = async () => {
if (!request) return
const assignee = prompt('Zuweisen an (Name/ID):')
if (!assignee) return
try {
const updated = await assignDSR(request.id, assignee)
setRequest(updated)
fetchDSRHistory(requestId).then(setHistory).catch(() => {})
} catch (err) {
console.error('Failed to assign:', err)
}
}
const handleExtendDeadline = async () => {
if (!request) return
const reason = prompt('Grund fuer die Fristverlaengerung:')
if (!reason) return
const daysStr = prompt('Um wie viele Tage verlaengern? (Standard: 60)', '60')
const days = parseInt(daysStr || '60', 10) || 60
try {
const updated = await extendDSRDeadline(request.id, reason, days)
setRequest(updated)
fetchDSRHistory(requestId).then(setHistory).catch(() => {})
} catch (err) {
console.error('Failed to extend deadline:', err)
}
}
const handleComplete = async () => {
if (!request) return
const summary = prompt('Zusammenfassung der Bearbeitung:')
if (summary === null) return
try {
const updated = await completeDSR(request.id, summary || undefined)
setRequest(updated)
fetchDSRHistory(requestId).then(setHistory).catch(() => {})
} catch (err) {
console.error('Failed to complete:', err)
}
}
const handleReject = async () => {
if (!request) return
const reason = prompt('Ablehnungsgrund:')
if (!reason) return
const legalBasis = prompt('Rechtsgrundlage (optional):')
try {
const updated = await rejectDSR(request.id, reason, legalBasis || undefined)
setRequest(updated)
fetchDSRHistory(requestId).then(setHistory).catch(() => {})
} catch (err) {
console.error('Failed to reject:', err)
}
}
const handleSendCommunication = async (message: any) => {
if (!request) return
try {
const result = await sendDSRCommunication(requestId, {
communication_type: message.type || 'outgoing',
channel: message.channel || 'email',
subject: message.subject,
content: message.content,
})
const newComm: DSRCommunication = {
id: result.id,
dsrId: result.dsr_id,
type: result.communication_type,
channel: result.channel,
subject: result.subject,
content: result.content,
createdAt: result.created_at,
createdBy: result.created_by || 'Current User',
sentAt: result.sent_at,
sentBy: result.sent_by,
}
setCommunications(prev => [newComm, ...prev])
} catch (err) {
console.error('Failed to send communication:', err)
}
}
const handleExceptionCheckChange = async (checkId: string, applies: boolean, notes?: string) => {
try {
const updated = await updateDSRExceptionCheck(requestId, checkId, { applies, notes })
setExceptionChecks(prev => prev.map(c => c.id === checkId ? updated : c))
} catch (err) {
console.error('Failed to update exception check:', err)
}
}
return {
request,
setRequest,
communications,
history,
exceptionChecks,
isLoading,
handleVerifyIdentity,
handleAssign,
handleExtendDeadline,
handleComplete,
handleReject,
handleSendCommunication,
handleExceptionCheckChange,
}
}