Some checks failed
Deploy Development / deploy (push) Successful in 35s
Test Suite / pytest-backend (push) Successful in 6s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 6s
Test Suite / playwright-tests (push) Failing after 28s
- Removed the useLocation hook as it was unnecessary for the component's functionality. - Updated the navigation styling to use CSS classes instead of inline styles, enhancing maintainability and readability. - Improved accessibility by adding aria-labels to navigation elements.
148 lines
4.1 KiB
JavaScript
148 lines
4.1 KiB
JavaScript
import React, { useState, useEffect } from 'react'
|
|
import { TreePine, FolderTree, Link2 } from 'lucide-react'
|
|
import { api } from '../utils/api'
|
|
import AdminPageNav from '../components/AdminPageNav'
|
|
import AppSubnavShell from '../components/AppSubnavShell'
|
|
import HierarchyTab from '../components/admin/HierarchyTab'
|
|
import CatalogsTab from '../components/admin/CatalogsTab'
|
|
import AssignmentsTab from '../components/admin/AssignmentsTab'
|
|
|
|
function AdminHierarchyPage() {
|
|
const [activeTab, setActiveTab] = useState('hierarchy')
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState('')
|
|
|
|
const [hierarchy, setHierarchy] = useState([])
|
|
const [expandedNodes, setExpandedNodes] = useState(new Set())
|
|
const [selectedItem, setSelectedItem] = useState(null)
|
|
|
|
const [targetGroups, setTargetGroups] = useState([])
|
|
const [skillCategories, setSkillCategories] = useState([])
|
|
const [trainingCharacters, setTrainingCharacters] = useState([])
|
|
|
|
const [styleDirections, setStyleDirections] = useState([])
|
|
const [assignments, setAssignments] = useState([])
|
|
|
|
useEffect(() => {
|
|
loadData()
|
|
}, [activeTab])
|
|
|
|
async function loadData() {
|
|
setLoading(true)
|
|
setError('')
|
|
try {
|
|
if (activeTab === 'hierarchy') {
|
|
const data = await api.getAdminHierarchy()
|
|
setHierarchy(data)
|
|
} else if (activeTab === 'catalogs') {
|
|
const [tgs, scs, tcs] = await Promise.all([
|
|
api.listTargetGroups(),
|
|
api.listSkillCategories(),
|
|
api.listTrainingCharacters()
|
|
])
|
|
setTargetGroups(tgs)
|
|
setSkillCategories(scs)
|
|
setTrainingCharacters(tcs)
|
|
} else if (activeTab === 'assignments') {
|
|
const [sds, tgs, assns] = await Promise.all([
|
|
api.listStyleDirections(),
|
|
api.listTargetGroups(),
|
|
api.listStyleDirectionTargetGroups()
|
|
])
|
|
setStyleDirections(sds)
|
|
setTargetGroups(tgs)
|
|
setAssignments(assns)
|
|
}
|
|
} catch (e) {
|
|
setError(e.message)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
function handleToggleNode(nodeId) {
|
|
setExpandedNodes((prev) => {
|
|
const newSet = new Set(prev)
|
|
if (newSet.has(nodeId)) {
|
|
newSet.delete(nodeId)
|
|
} else {
|
|
newSet.add(nodeId)
|
|
}
|
|
return newSet
|
|
})
|
|
}
|
|
|
|
function handleSelectItem(item, type) {
|
|
if (item) {
|
|
setSelectedItem({ ...item, _type: type })
|
|
} else {
|
|
setSelectedItem(null)
|
|
}
|
|
}
|
|
|
|
function handleUpdate() {
|
|
setSelectedItem(null)
|
|
loadData()
|
|
}
|
|
|
|
const subnavItems = [
|
|
{ id: 'hierarchy', label: 'Hierarchie', icon: TreePine },
|
|
{ id: 'catalogs', label: 'Kataloge', icon: FolderTree },
|
|
{ id: 'assignments', label: 'Zuordnungen', icon: Link2 }
|
|
]
|
|
|
|
return (
|
|
<div className="app-page admin-hierarchy-page">
|
|
<AdminPageNav />
|
|
|
|
<h1 className="page-title" style={{ marginBottom: '12px' }}>
|
|
Katalog & Hierarchie
|
|
</h1>
|
|
|
|
<AppSubnavShell
|
|
ariaLabel="Bereich Katalogadministration"
|
|
items={subnavItems}
|
|
value={activeTab}
|
|
onChange={setActiveTab}
|
|
>
|
|
{activeTab === 'hierarchy' && (
|
|
<HierarchyTab
|
|
hierarchy={hierarchy}
|
|
expandedNodes={expandedNodes}
|
|
selectedItem={selectedItem}
|
|
loading={loading}
|
|
error={error}
|
|
onToggleNode={handleToggleNode}
|
|
onSelectItem={handleSelectItem}
|
|
onUpdate={handleUpdate}
|
|
/>
|
|
)}
|
|
|
|
{activeTab === 'catalogs' && (
|
|
<CatalogsTab
|
|
targetGroups={targetGroups}
|
|
skillCategories={skillCategories}
|
|
trainingCharacters={trainingCharacters}
|
|
loading={loading}
|
|
error={error}
|
|
onUpdate={handleUpdate}
|
|
/>
|
|
)}
|
|
|
|
{activeTab === 'assignments' && (
|
|
<AssignmentsTab
|
|
styleDirections={styleDirections}
|
|
targetGroups={targetGroups}
|
|
assignments={assignments}
|
|
loading={loading}
|
|
error={error}
|
|
onUpdate={handleUpdate}
|
|
/>
|
|
)}
|
|
</AppSubnavShell>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default AdminHierarchyPage
|