'use client'; import { useCallback, useEffect, useState } from 'react'; import Link from 'next/link'; import { useTranslations } from 'next-intl'; import { type CustomModule, listCustomModules } from '@/lib/custom-modules-api'; import { useMarketplaceStore } from '@/lib/stores/marketplace-store'; import { useAuthStore } from '@/lib/stores/auth-store'; import { useCategoryLabel } from '@/lib/use-category-label'; import { CustomModuleFormModal } from './components/CustomModuleFormModal'; import { DeleteCustomModuleDialog } from './components/DeleteCustomModuleDialog'; /** * Verwaltung „Eigene Module“ (quick-260929-9wc, D-07, Vorbild * `admin/groups`). ADMIN und SUPER_ADMIN; die Rollenpruefung hier ist nur * Anzeige — durchgesetzt wird sie serverseitig durch `@Roles` an POST, PATCH * und DELETE von `/custom-modules`. Nach jedem erfolgreichen Anlegen, * Aendern oder Loeschen zieht die Seitenleiste ueber `bumpSidebarRefresh` * ohne Neuladen nach (D-05). */ export default function AdminCustomModulesPage() { const t = useTranslations('admin.customModules'); const tCommon = useTranslations('common'); const categoryLabel = useCategoryLabel(); const currentUser = useAuthStore((s) => s.user); const bumpSidebarRefresh = useMarketplaceStore((s) => s.bumpSidebarRefresh); const [modules, setModules] = useState([]); const [loading, setLoading] = useState(true); const [loadFailed, setLoadFailed] = useState(false); const [showFormModal, setShowFormModal] = useState(false); const [editing, setEditing] = useState(null); const [deleteTarget, setDeleteTarget] = useState(null); const hasAccess = currentUser?.role === 'ADMIN' || currentUser?.role === 'SUPER_ADMIN'; const fetchModules = useCallback(async () => { try { setModules(await listCustomModules()); setLoadFailed(false); } catch { setLoadFailed(true); } finally { setLoading(false); } }, []); useEffect(() => { if (hasAccess) { fetchModules(); } else { setLoading(false); } }, [hasAccess, fetchModules]); const handleChanged = () => { fetchModules(); bumpSidebarRefresh(); }; const openCreate = () => { setEditing(null); setShowFormModal(true); }; const openEdit = (mod: CustomModule) => { setEditing(mod); setShowFormModal(true); }; if (!hasAccess) { return (

{tCommon('accessDenied')}

); } return (

{t('title')}

{t('description')}

{loadFailed && (
{t('loadError')}
)} {loading ? (

{tCommon('loading')}

) : modules.length === 0 ? (

{t('noModules')}

{t('noModulesBody')}

) : (
{modules.map((mod) => ( ))}
{t('name')} {t('url')} {t('category')} {t('actions')}
{mod.name} {mod.url} {categoryLabel(mod.category)}
)} {showFormModal && ( setShowFormModal(false)} onSaved={handleChanged} /> )} {deleteTarget && ( setDeleteTarget(null)} onDeleted={handleChanged} /> )}
); }