-
Stufen (Bezeichnungen)
-
- Reihenfolge muss lückenlos 1…N sein. Stufenanzahl ändern passt die Tabelle an; danach speichern.
+
+
+ 2
+
Stufen (Bezeichnungen)
+
+
+ Nummern 1…N lückenlos. Stufenanzahl ändert die Matrix; danach „Stufen speichern“.
-
+
Stufenanzahl (3–10)
onLevelCountChange(e.target.value)}
/>
-
-
+
+
- Nr.
- Name
- Beschreibung
- Sort
+ Nr.
+ Name
+ Beschreibung
+ Sort
{levelsForm.map((row, idx) => (
-
- {row.level_number}
-
+
+ {row.level_number}
+
-
+
-
+
{
const next = [...levelsForm]
@@ -584,19 +511,21 @@ export default function MaturityModelsAdminPanel() {
Stufen speichern
-
+
-
-
Fähigkeiten im Modell
-
-
+
+
+ 3
+
Fähigkeiten im Modell
+
+
+
Fähigkeit hinzufügen
-
+
Hinzufügen
-
+
{(detail.model_skills || []).map((ms) => (
-
-
-
{ms.skill_name}
- {' '}
+
+
+ {ms.skill_name}
handleRemoveSkill(ms.skill_id)}
>
- entfernen
+ Entfernen
{(ms.skill_main_category_name || ms.skill_subcategory_name) ? (
-
+
{ms.skill_main_category_name}
{ms.skill_subcategory_name ? ` › ${ms.skill_subcategory_name}` : ''}
@@ -637,26 +569,23 @@ export default function MaturityModelsAdminPanel() {
))}
-
+
-
-
Matrix (Zielbild je Stufe)
-
- Leere Zellen werden beim Speichern aus der Datenbank entfernt. Beobachtungskriterien optional in
- zweiter Zeile (nach Speichern mit Beschreibung).
+
+
+ 4
+
Matrix (Zielbild je Stufe)
+
+
+ Leere Zellen werden beim Speichern entfernt. Unten: Beobachtungskriterien (optional).
-
-
+
+
-
- Fähigkeit
-
+ Fähigkeit
{(detail.levels || []).map((l) => (
-
+
{l.level_number}. {l.name}
))}
@@ -665,21 +594,10 @@ export default function MaturityModelsAdminPanel() {
{(detail.model_skills || []).map((ms) => (
-
+
{ms.skill_name}
{(ms.skill_main_category_name || ms.skill_subcategory_name) ? (
-
+
{ms.skill_main_category_name || '—'}
{ms.skill_subcategory_name ? ` › ${ms.skill_subcategory_name}` : ''}
@@ -689,22 +607,20 @@ export default function MaturityModelsAdminPanel() {
const key = `${ms.skill_id}-${l.level_number}`
const d = cellDraft[key] || { description: '', observable_criteria: '' }
return (
-
+
)
@@ -716,14 +632,13 @@ export default function MaturityModelsAdminPanel() {
Matrix speichern
-
+
>
)}
diff --git a/frontend/src/components/admin/SkillsCatalogAdmin.jsx b/frontend/src/components/admin/SkillsCatalogAdmin.jsx
index 8fb2a0c..3ff2ea6 100644
--- a/frontend/src/components/admin/SkillsCatalogAdmin.jsx
+++ b/frontend/src/components/admin/SkillsCatalogAdmin.jsx
@@ -9,17 +9,29 @@ function bySortThenName(a, b) {
return String(a.name || '').localeCompare(String(b.name || ''), 'de')
}
-async function swapNeighborSort(list, index, delta, updateId) {
- const sorted = [...list].sort(bySortThenName)
- const i = sorted.findIndex((x) => x.id === list[index]?.id)
+/** Tauscht sort_order mit dem direkten Nachbarn in der aktuellen Sortierung (stabil per ID). */
+async function swapNeighborSortById(sortedList, rowId, delta, updateId) {
+ const sorted = [...sortedList].sort(bySortThenName)
+ const i = sorted.findIndex((x) => x.id === rowId)
const j = i + delta
if (i < 0 || j < 0 || j >= sorted.length) return
const a = sorted[i]
const b = sorted[j]
- const oa = a.sort_order != null ? Number(a.sort_order) : (i + 1) * 10
- const ob = b.sort_order != null ? Number(b.sort_order) : (j + 1) * 10
- await updateId(a.id, { sort_order: ob })
- await updateId(b.id, { sort_order: oa })
+ let oa = a.sort_order
+ let ob = b.sort_order
+ if (oa == null || oa === '') oa = (i + 1) * 10
+ else oa = Number(oa)
+ if (ob == null || ob === '') ob = (j + 1) * 10
+ else ob = Number(ob)
+ await Promise.all([
+ updateId(a.id, { sort_order: ob }),
+ updateId(b.id, { sort_order: oa })
+ ])
+}
+
+function stop(e) {
+ e.preventDefault()
+ e.stopPropagation()
}
export default function SkillsCatalogAdmin() {
@@ -66,6 +78,9 @@ export default function SkillsCatalogAdmin() {
const [newCategoryName, setNewCategoryName] = useState('')
const [newSkillName, setNewSkillName] = useState('')
+ /** Aktives Bearbeiten-Modal: Typ + Entitäts-ID */
+ const [editDialog, setEditDialog] = useState(null)
+
const refreshCategories = useCallback(async (mainId) => {
if (mainId == null) {
setCategories([])
@@ -118,76 +133,59 @@ export default function SkillsCatalogAdmin() {
.sort(bySortThenName)
}, [catalog, selectedCategoryId])
- const selectedMain = useMemo(
- () => mains.find((m) => m.id === selectedMainId) || null,
- [mains, selectedMainId]
- )
- const selectedCategory = useMemo(
- () => categories.find((c) => c.id === selectedCategoryId) || null,
- [categories, selectedCategoryId]
- )
- const selectedSkill = useMemo(
- () => catalog.find((s) => s.id === selectedSkillId) || null,
- [catalog, selectedSkillId]
- )
-
useEffect(() => {
- if (!selectedMain) {
- setMainForm({ name: '', slug: '', description: '', sort_order: '' })
- return
+ if (!editDialog) return
+ const onKey = (ev) => {
+ if (ev.key === 'Escape') setEditDialog(null)
}
+ document.addEventListener('keydown', onKey)
+ const prev = document.body.style.overflow
+ document.body.style.overflow = 'hidden'
+ return () => {
+ document.removeEventListener('keydown', onKey)
+ document.body.style.overflow = prev
+ }
+ }, [editDialog])
+
+ function openEditMain(m) {
setMainForm({
- name: selectedMain.name || '',
- slug: selectedMain.slug || '',
- description: selectedMain.description || '',
- sort_order: selectedMain.sort_order ?? ''
+ name: m.name || '',
+ slug: m.slug || '',
+ description: m.description || '',
+ sort_order: m.sort_order ?? ''
})
- }, [selectedMain])
+ setEditDialog({ type: 'main', id: m.id })
+ }
- useEffect(() => {
- if (!selectedCategory) {
- setCategoryForm({
- name: '',
- slug: '',
- description: '',
- main_category_id: '',
- sort_order: ''
- })
- return
- }
+ function openEditCategory(c) {
setCategoryForm({
- name: selectedCategory.name || '',
- slug: selectedCategory.slug || '',
- description: selectedCategory.description || '',
- main_category_id: selectedCategory.main_category_id ?? '',
- sort_order: selectedCategory.sort_order ?? ''
+ name: c.name || '',
+ slug: c.slug || '',
+ description: c.description || '',
+ main_category_id: c.main_category_id ?? '',
+ sort_order: c.sort_order ?? ''
})
- }, [selectedCategory])
+ setEditDialog({ type: 'category', id: c.id })
+ }
- useEffect(() => {
- if (!selectedSkill) {
- setSkillForm({
- name: '',
- description: '',
- category: '',
- keywords: '',
- status: 'active',
- sort_order: '',
- category_id: ''
- })
- return
- }
+ function openEditSkill(s) {
setSkillForm({
- name: selectedSkill.name || '',
- description: selectedSkill.description || '',
- category: selectedSkill.category || '',
- keywords: selectedSkill.keywords || '',
- status: selectedSkill.status || 'active',
- sort_order: selectedSkill.sort_order ?? '',
- category_id: selectedSkill.category_id ?? ''
+ name: s.name || '',
+ description: s.description || '',
+ category: s.category || '',
+ keywords: s.keywords || '',
+ status: s.status || 'active',
+ sort_order: s.sort_order ?? '',
+ category_id: s.category_id ?? ''
})
- }, [selectedSkill])
+ setEditDialog({ type: 'skill', id: s.id })
+ }
+ function closeEditDialog() {
+ setEditDialog(null)
+ }
+
+ /** @returns {Promise} true bei Erfolg */
async function run(op) {
setBusy(true)
setMessage('')
@@ -196,8 +194,10 @@ export default function SkillsCatalogAdmin() {
await bootstrap()
if (selectedMainId) await refreshCategories(selectedMainId)
setMessage('Gespeichert.')
+ return true
} catch (e) {
setError(e.message || String(e))
+ return false
} finally {
setBusy(false)
}
@@ -214,37 +214,34 @@ export default function SkillsCatalogAdmin() {
setSelectedSkillId(null)
}
- async function handleSwapMain(row, delta) {
- const idx = sortedMains.findIndex((m) => m.id === row.id)
+ async function handleSwapMain(rowId, delta) {
await run(async () => {
- await swapNeighborSort(sortedMains, idx, delta, (id, data) =>
+ await swapNeighborSortById(sortedMains, rowId, delta, (id, data) =>
api.updateSkillMainCategory(id, data)
)
})
}
- async function handleSwapCategory(row, delta) {
- const idx = sortedCategories.findIndex((c) => c.id === row.id)
+ async function handleSwapCategory(rowId, delta) {
await run(async () => {
- await swapNeighborSort(sortedCategories, idx, delta, (id, data) =>
+ await swapNeighborSortById(sortedCategories, rowId, delta, (id, data) =>
api.updateSkillCategory(id, data)
)
})
}
- async function handleSwapSkill(row, delta) {
+ async function handleSwapSkill(rowId, delta) {
const sorted = [...skillsInCategory].sort(bySortThenName)
- const idx = sorted.findIndex((s) => s.id === row.id)
await run(async () => {
- await swapNeighborSort(sorted, idx, delta, (id, data) => api.updateSkill(id, data))
+ await swapNeighborSortById(sorted, rowId, delta, (id, data) => api.updateSkill(id, data))
})
}
async function handleSaveMain(e) {
e.preventDefault()
- if (!selectedMainId) return
- await run(async () => {
- await api.updateSkillMainCategory(selectedMainId, {
+ if (!editDialog || editDialog.type !== 'main') return
+ const ok = await run(async () => {
+ await api.updateSkillMainCategory(editDialog.id, {
name: mainForm.name.trim(),
slug: (mainForm.slug || '').trim() || undefined,
description: mainForm.description || null,
@@ -254,17 +251,18 @@ export default function SkillsCatalogAdmin() {
: Number(mainForm.sort_order)
})
})
+ if (ok) closeEditDialog()
}
async function handleSaveCategory(e) {
e.preventDefault()
- if (!selectedCategoryId) return
+ if (!editDialog || editDialog.type !== 'category') return
const mid =
categoryForm.main_category_id === '' || categoryForm.main_category_id == null
? null
: Number(categoryForm.main_category_id)
- await run(async () => {
- await api.updateSkillCategory(selectedCategoryId, {
+ const ok = await run(async () => {
+ await api.updateSkillCategory(editDialog.id, {
name: categoryForm.name.trim(),
slug: (categoryForm.slug || '').trim() || undefined,
description: categoryForm.description || null,
@@ -275,24 +273,28 @@ export default function SkillsCatalogAdmin() {
: Number(categoryForm.sort_order)
})
})
- if (mid != null && mid !== selectedMainId) {
- setSelectedMainId(mid)
- setSelectedSkillId(null)
+ if (ok) {
+ if (mid != null && mid !== selectedMainId) {
+ setSelectedMainId(mid)
+ setSelectedSkillId(null)
+ }
+ closeEditDialog()
}
}
async function handleSaveSkill(e) {
e.preventDefault()
- if (!selectedSkillId) return
+ if (!editDialog || editDialog.type !== 'skill') return
let cid =
skillForm.category_id === '' || skillForm.category_id == null
? null
: Number(skillForm.category_id)
- if (cid == null && selectedSkill?.category_id) {
- cid = selectedSkill.category_id
+ const skillRow = catalog.find((s) => s.id === editDialog.id)
+ if (cid == null && skillRow?.category_id) {
+ cid = skillRow.category_id
}
- await run(async () => {
- await api.updateSkill(selectedSkillId, {
+ const ok = await run(async () => {
+ await api.updateSkill(editDialog.id, {
name: skillForm.name.trim(),
description: skillForm.description || null,
category: skillForm.category || null,
@@ -305,12 +307,15 @@ export default function SkillsCatalogAdmin() {
category_id: cid
})
})
- if (cid != null && cid !== selectedCategoryId) {
- const cat = allCategories.find((c) => c.id === cid)
- if (cat?.main_category_id) {
- setSelectedMainId(cat.main_category_id)
- setSelectedCategoryId(cid)
+ if (ok) {
+ if (cid != null && cid !== selectedCategoryId) {
+ const cat = allCategories.find((c) => c.id === cid)
+ if (cat?.main_category_id) {
+ setSelectedMainId(cat.main_category_id)
+ setSelectedCategoryId(cid)
+ }
}
+ closeEditDialog()
}
}
@@ -358,43 +363,45 @@ export default function SkillsCatalogAdmin() {
}
async function handleDeleteMain() {
- if (!selectedMainId || !isSuperadmin) return
+ if (!editDialog || editDialog.type !== 'main' || !isSuperadmin) return
if (!window.confirm('Hauptkategorie wirklich löschen?')) return
- await run(async () => {
- await api.deleteSkillMainCategory(selectedMainId)
- setSelectedMainId(null)
- setSelectedCategoryId(null)
- setSelectedSkillId(null)
+ const id = editDialog.id
+ const ok = await run(async () => {
+ await api.deleteSkillMainCategory(id)
+ if (selectedMainId === id) {
+ setSelectedMainId(null)
+ setSelectedCategoryId(null)
+ setSelectedSkillId(null)
+ }
})
+ if (ok) closeEditDialog()
}
async function handleDeleteCategory() {
- if (!selectedCategoryId || !isSuperadmin) return
+ if (!editDialog || editDialog.type !== 'category' || !isSuperadmin) return
if (!window.confirm('Kategorie wirklich löschen?')) return
- await run(async () => {
- await api.deleteSkillCategory(selectedCategoryId)
- setSelectedCategoryId(null)
- setSelectedSkillId(null)
+ const id = editDialog.id
+ const ok = await run(async () => {
+ await api.deleteSkillCategory(id)
+ if (selectedCategoryId === id) {
+ setSelectedCategoryId(null)
+ setSelectedSkillId(null)
+ }
})
+ if (ok) closeEditDialog()
}
async function handleDeleteSkill() {
- if (!selectedSkillId || !isSuperadmin) return
+ if (!editDialog || editDialog.type !== 'skill' || !isSuperadmin) return
if (!window.confirm('Fähigkeit wirklich löschen?')) return
- await run(async () => {
- await api.deleteSkill(selectedSkillId)
- setSelectedSkillId(null)
+ const id = editDialog.id
+ const ok = await run(async () => {
+ await api.deleteSkill(id)
+ if (selectedSkillId === id) setSelectedSkillId(null)
})
+ if (ok) closeEditDialog()
}
- const detailMode = selectedSkillId
- ? 'skill'
- : selectedCategoryId
- ? 'category'
- : selectedMainId
- ? 'main'
- : 'none'
-
if (loading) {
return (
@@ -407,8 +414,8 @@ export default function SkillsCatalogAdmin() {
Struktur: Hauptkategorie → Kategorie →{' '}
- Fähigkeit . Reihenfolge mit den Pfeiltasten; Zuordnungen und Texte im
- Bereich „Bearbeiten“.
+ Fähigkeit . Reihenfolge mit Pfeilen; Details über das Stift-Symbol (öffnet
+ ein Fenster — auf dem iPhone nach unten scrollen, falls nötig).
{error ? (
@@ -454,7 +461,11 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach oben"
- onClick={() => handleSwapMain(m, -1)}
+ aria-label="Nach oben sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapMain(m.id, -1)
+ }}
>
↑
@@ -463,10 +474,27 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach unten"
- onClick={() => handleSwapMain(m, 1)}
+ aria-label="Nach unten sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapMain(m.id, 1)
+ }}
>
↓
+
{
+ stop(e)
+ openEditMain(m)
+ }}
+ >
+ ✎
+
@@ -515,7 +543,11 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach oben"
- onClick={() => handleSwapCategory(c, -1)}
+ aria-label="Nach oben sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapCategory(c.id, -1)
+ }}
>
↑
@@ -524,10 +556,27 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach unten"
- onClick={() => handleSwapCategory(c, 1)}
+ aria-label="Nach unten sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapCategory(c.id, 1)
+ }}
>
↓
+
{
+ stop(e)
+ openEditCategory(c)
+ }}
+ >
+ ✎
+
@@ -581,7 +630,11 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach oben"
- onClick={() => handleSwapSkill(s, -1)}
+ aria-label="Nach oben sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapSkill(s.id, -1)
+ }}
>
↑
@@ -590,10 +643,27 @@ export default function SkillsCatalogAdmin() {
className="btn btn-secondary btn-tiny"
disabled={busy}
title="Nach unten"
- onClick={() => handleSwapSkill(s, 1)}
+ aria-label="Nach unten sortieren"
+ onClick={(e) => {
+ stop(e)
+ handleSwapSkill(s.id, 1)
+ }}
>
↓
+ {
+ stop(e)
+ openEditSkill(s)
+ }}
+ >
+ ✎
+
@@ -617,222 +687,279 @@ export default function SkillsCatalogAdmin() {
-
- Bearbeiten
- {detailMode === 'none' ? (
-
- Wählen Sie eine Hauptkategorie, Kategorie oder Fähigkeit in den Spalten oben.
-
- ) : null}
-
- {detailMode === 'main' ? (
-
- Hauptkategorie
- Name
- setMainForm((f) => ({ ...f, name: e.target.value }))}
- disabled={busy}
- />
- Slug
- setMainForm((f) => ({ ...f, slug: e.target.value }))}
- disabled={busy}
- />
- Beschreibung
- setMainForm((f) => ({ ...f, description: e.target.value }))}
- disabled={busy}
- />
- Sortierung (Zahl, optional)
- setMainForm((f) => ({ ...f, sort_order: e.target.value }))}
- disabled={busy}
- />
-
-
- Speichern
+ {editDialog ? (
+
+
e.stopPropagation()}
+ >
+
+
+ {editDialog.type === 'main'
+ ? 'Hauptkategorie bearbeiten'
+ : editDialog.type === 'category'
+ ? 'Kategorie bearbeiten'
+ : 'Fähigkeit bearbeiten'}
+
+
+ ✕
- {isSuperadmin ? (
-
- Löschen
-
+
+
+ {editDialog.type === 'main' ? (
+
+ Name
+ setMainForm((f) => ({ ...f, name: e.target.value }))}
+ disabled={busy}
+ autoComplete="off"
+ />
+ Slug
+ setMainForm((f) => ({ ...f, slug: e.target.value }))}
+ disabled={busy}
+ />
+ Beschreibung
+ setMainForm((f) => ({ ...f, description: e.target.value }))}
+ disabled={busy}
+ />
+ Sortierung (Zahl, optional)
+ setMainForm((f) => ({ ...f, sort_order: e.target.value }))}
+ disabled={busy}
+ />
+
+
+ Speichern
+
+
+ Abbrechen
+
+ {isSuperadmin ? (
+
+ Löschen
+
+ ) : null}
+
+
+ ) : null}
+
+ {editDialog.type === 'category' ? (
+
+ Name
+ setCategoryForm((f) => ({ ...f, name: e.target.value }))}
+ disabled={busy}
+ />
+ Slug
+ setCategoryForm((f) => ({ ...f, slug: e.target.value }))}
+ disabled={busy}
+ />
+ Hauptkategorie (verschieben)
+
+ setCategoryForm((f) => ({
+ ...f,
+ main_category_id: e.target.value === '' ? '' : e.target.value
+ }))
+ }
+ disabled={busy}
+ >
+ — keine —
+ {sortedMains.map((m) => (
+
+ {m.name}
+
+ ))}
+
+ Beschreibung
+ setCategoryForm((f) => ({ ...f, description: e.target.value }))}
+ disabled={busy}
+ />
+ Sortierung (optional)
+ setCategoryForm((f) => ({ ...f, sort_order: e.target.value }))}
+ disabled={busy}
+ />
+
+
+ Speichern
+
+
+ Abbrechen
+
+ {isSuperadmin ? (
+
+ Löschen
+
+ ) : null}
+
+
+ ) : null}
+
+ {editDialog.type === 'skill' ? (
+
+ Name
+ setSkillForm((f) => ({ ...f, name: e.target.value }))}
+ disabled={busy}
+ />
+ Kategorie (verschieben)
+
+ setSkillForm((f) => ({
+ ...f,
+ category_id: e.target.value === '' ? '' : e.target.value
+ }))
+ }
+ disabled={busy}
+ required
+ >
+ {allCategories.map((c) => (
+
+ {(c.main_category_name ? c.main_category_name + ' · ' : '') + c.name}
+
+ ))}
+
+ Legacy-Kurzlabel „category“ (optional)
+ setSkillForm((f) => ({ ...f, category: e.target.value }))}
+ disabled={busy}
+ />
+ Stichwörter
+ setSkillForm((f) => ({ ...f, keywords: e.target.value }))}
+ disabled={busy}
+ />
+ Status
+ setSkillForm((f) => ({ ...f, status: e.target.value }))}
+ disabled={busy}
+ >
+ active
+ inactive
+
+ Beschreibung
+ setSkillForm((f) => ({ ...f, description: e.target.value }))}
+ disabled={busy}
+ />
+ Sortierung (optional)
+ setSkillForm((f) => ({ ...f, sort_order: e.target.value }))}
+ disabled={busy}
+ />
+
+
+ Speichern
+
+
+ Abbrechen
+
+ {isSuperadmin ? (
+
+ Löschen
+
+ ) : null}
+
+
) : null}
-
- ) : null}
-
- {detailMode === 'category' ? (
-
- Kategorie
- Name
- setCategoryForm((f) => ({ ...f, name: e.target.value }))}
- disabled={busy}
- />
- Slug
- setCategoryForm((f) => ({ ...f, slug: e.target.value }))}
- disabled={busy}
- />
- Hauptkategorie (verschieben)
-
- setCategoryForm((f) => ({
- ...f,
- main_category_id: e.target.value === '' ? '' : e.target.value
- }))
- }
- disabled={busy}
- >
- — keine —
- {sortedMains.map((m) => (
-
- {m.name}
-
- ))}
-
- Beschreibung
- setCategoryForm((f) => ({ ...f, description: e.target.value }))}
- disabled={busy}
- />
- Sortierung (optional)
- setCategoryForm((f) => ({ ...f, sort_order: e.target.value }))}
- disabled={busy}
- />
-
-
- Speichern
-
- {isSuperadmin ? (
-
- Löschen
-
- ) : null}
-
-
- ) : null}
-
- {detailMode === 'skill' ? (
-
- Fähigkeit
- Name
- setSkillForm((f) => ({ ...f, name: e.target.value }))}
- disabled={busy}
- />
- Kategorie (verschieben)
-
- setSkillForm((f) => ({
- ...f,
- category_id: e.target.value === '' ? '' : e.target.value
- }))
- }
- disabled={busy}
- required
- >
- {allCategories.map((c) => (
-
- {(c.main_category_name ? c.main_category_name + ' · ' : '') + c.name}
-
- ))}
-
- Legacy-Kurzlabel „category“ (optional)
- setSkillForm((f) => ({ ...f, category: e.target.value }))}
- disabled={busy}
- />
- Stichwörter
- setSkillForm((f) => ({ ...f, keywords: e.target.value }))}
- disabled={busy}
- />
- Status
- setSkillForm((f) => ({ ...f, status: e.target.value }))}
- disabled={busy}
- >
- active
- inactive
-
- Beschreibung
- setSkillForm((f) => ({ ...f, description: e.target.value }))}
- disabled={busy}
- />
- Sortierung (optional)
- setSkillForm((f) => ({ ...f, sort_order: e.target.value }))}
- disabled={busy}
- />
-
-
- Speichern
-
- {isSuperadmin ? (
-
- Löschen
-
- ) : null}
-
-
- ) : null}
-
+
+
+ ) : null}
)
}