Extract components and hooks from oversized pages into colocated _components/ and _hooks/ subdirectories to enforce the 500-LOC hard cap. page.tsx files reduced to 205, 121, and 136 LOC respectively. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect, useCallback } from 'react'
|
|
import {
|
|
GCIResult,
|
|
GCIBreakdown,
|
|
GCIHistoryResponse,
|
|
GCIMatrixResponse,
|
|
NIS2Score,
|
|
ISOGapAnalysis,
|
|
WeightProfile,
|
|
} from '@/lib/sdk/gci/types'
|
|
import {
|
|
getGCIScore,
|
|
getGCIBreakdown,
|
|
getGCIHistory,
|
|
getGCIMatrix,
|
|
getNIS2Score,
|
|
getISOGapAnalysis,
|
|
getWeightProfiles,
|
|
} from '@/lib/sdk/gci/api'
|
|
import { TabId } from '../_components/GCIHelpers'
|
|
|
|
export function useGCI() {
|
|
const [activeTab, setActiveTab] = useState<TabId>('overview')
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
const [gci, setGCI] = useState<GCIResult | null>(null)
|
|
const [breakdown, setBreakdown] = useState<GCIBreakdown | null>(null)
|
|
const [history, setHistory] = useState<GCIHistoryResponse | null>(null)
|
|
const [matrix, setMatrix] = useState<GCIMatrixResponse | null>(null)
|
|
const [nis2, setNIS2] = useState<NIS2Score | null>(null)
|
|
const [iso, setISO] = useState<ISOGapAnalysis | null>(null)
|
|
const [profiles, setProfiles] = useState<WeightProfile[]>([])
|
|
const [selectedProfile, setSelectedProfile] = useState('default')
|
|
|
|
const loadData = useCallback(async (profile?: string) => {
|
|
setLoading(true)
|
|
setError(null)
|
|
try {
|
|
const [gciRes, historyRes, profilesRes] = await Promise.all([
|
|
getGCIScore(profile),
|
|
getGCIHistory(),
|
|
getWeightProfiles(),
|
|
])
|
|
setGCI(gciRes)
|
|
setHistory(historyRes)
|
|
setProfiles(profilesRes.profiles || [])
|
|
} catch (err: any) {
|
|
setError(err.message || 'Fehler beim Laden der GCI-Daten')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
loadData(selectedProfile)
|
|
}, [selectedProfile, loadData])
|
|
|
|
useEffect(() => {
|
|
if (activeTab === 'breakdown' && !breakdown && gci) {
|
|
getGCIBreakdown(selectedProfile).then(setBreakdown).catch(() => {})
|
|
}
|
|
if (activeTab === 'nis2' && !nis2) {
|
|
getNIS2Score().then(setNIS2).catch(() => {})
|
|
}
|
|
if (activeTab === 'iso' && !iso) {
|
|
getISOGapAnalysis().then(setISO).catch(() => {})
|
|
}
|
|
if (activeTab === 'matrix' && !matrix) {
|
|
getGCIMatrix().then(setMatrix).catch(() => {})
|
|
}
|
|
}, [activeTab, breakdown, nis2, iso, matrix, gci, selectedProfile])
|
|
|
|
const handleProfileChange = (profile: string) => {
|
|
setSelectedProfile(profile)
|
|
setBreakdown(null)
|
|
}
|
|
|
|
return {
|
|
activeTab,
|
|
setActiveTab,
|
|
loading,
|
|
error,
|
|
gci,
|
|
breakdown,
|
|
history,
|
|
matrix,
|
|
nis2,
|
|
iso,
|
|
profiles,
|
|
selectedProfile,
|
|
loadData,
|
|
handleProfileChange,
|
|
}
|
|
}
|