refactor(admin): split control-library, iace/mitigations, iace/components pages
Extract hooks, sub-components, and constants into colocated files to bring all three page.tsx files under the 500-LOC hard cap (225, 134, 111 LOC). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import { Component, LibraryComponent, EnergySource, ComponentFormData, buildTree } from '../_components/types'
|
||||
|
||||
export function useComponents(projectId: string) {
|
||||
const [components, setComponents] = useState<Component[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [showForm, setShowForm] = useState(false)
|
||||
const [editingComponent, setEditingComponent] = useState<Component | null>(null)
|
||||
const [addingParentId, setAddingParentId] = useState<string | null>(null)
|
||||
const [showLibrary, setShowLibrary] = useState(false)
|
||||
|
||||
useEffect(() => { fetchComponents() }, [projectId])
|
||||
|
||||
async function fetchComponents() {
|
||||
try {
|
||||
const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components`)
|
||||
if (res.ok) { const json = await res.json(); setComponents(json.components || json || []) }
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch components:', err)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSubmit(data: ComponentFormData) {
|
||||
try {
|
||||
const url = editingComponent
|
||||
? `/api/sdk/v1/iace/projects/${projectId}/components/${editingComponent.id}`
|
||||
: `/api/sdk/v1/iace/projects/${projectId}/components`
|
||||
const method = editingComponent ? 'PUT' : 'POST'
|
||||
const res = await fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) })
|
||||
if (res.ok) { setShowForm(false); setEditingComponent(null); setAddingParentId(null); await fetchComponents() }
|
||||
} catch (err) { console.error('Failed to save component:', err) }
|
||||
}
|
||||
|
||||
async function handleDelete(id: string) {
|
||||
if (!confirm('Komponente wirklich loeschen? Unterkomponenten werden ebenfalls entfernt.')) return
|
||||
try {
|
||||
const res = await fetch(`/api/sdk/v1/iace/projects/${projectId}/components/${id}`, { method: 'DELETE' })
|
||||
if (res.ok) await fetchComponents()
|
||||
} catch (err) { console.error('Failed to delete component:', err) }
|
||||
}
|
||||
|
||||
function handleEdit(component: Component) {
|
||||
setEditingComponent(component); setAddingParentId(null); setShowForm(true)
|
||||
}
|
||||
|
||||
function handleAddChild(parentId: string) {
|
||||
setAddingParentId(parentId); setEditingComponent(null); setShowForm(true)
|
||||
}
|
||||
|
||||
async function handleAddFromLibrary(libraryComps: LibraryComponent[], energySrcs: EnergySource[]) {
|
||||
setShowLibrary(false)
|
||||
const energySourceIds = energySrcs.map(e => e.id)
|
||||
for (const comp of libraryComps) {
|
||||
try {
|
||||
await fetch(`/api/sdk/v1/iace/projects/${projectId}/components`, {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
name: comp.name_de, type: comp.maps_to_component_type,
|
||||
description: comp.description_de, safety_relevant: false,
|
||||
library_component_id: comp.id, energy_source_ids: energySourceIds, tags: comp.tags,
|
||||
}),
|
||||
})
|
||||
} catch (err) { console.error(`Failed to add component ${comp.id}:`, err) }
|
||||
}
|
||||
await fetchComponents()
|
||||
}
|
||||
|
||||
const tree = buildTree(components)
|
||||
|
||||
return {
|
||||
components, loading, tree,
|
||||
showForm, setShowForm, editingComponent, setEditingComponent,
|
||||
addingParentId, setAddingParentId, showLibrary, setShowLibrary,
|
||||
handleSubmit, handleDelete, handleEdit, handleAddChild, handleAddFromLibrary,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user