diff --git a/frontend/src/pages/AdminFeaturesPage.jsx b/frontend/src/pages/AdminFeaturesPage.jsx
index 4c9b90c..6125d8c 100644
--- a/frontend/src/pages/AdminFeaturesPage.jsx
+++ b/frontend/src/pages/AdminFeaturesPage.jsx
@@ -1,5 +1,5 @@
import { useState, useEffect } from 'react'
-import { Save, Plus, Edit2, Trash2, X } from 'lucide-react'
+import { Save, Edit2, X, Info } from 'lucide-react'
import { api } from '../utils/api'
export default function AdminFeaturesPage() {
@@ -8,9 +8,7 @@ export default function AdminFeaturesPage() {
const [success, setSuccess] = useState('')
const [features, setFeatures] = useState([])
const [editingId, setEditingId] = useState(null)
- const [showAddForm, setShowAddForm] = useState(false)
const [formData, setFormData] = useState({
- id: '',
name: '',
category: 'data',
description: '',
@@ -42,7 +40,6 @@ export default function AdminFeaturesPage() {
function resetForm() {
setFormData({
- id: '',
name: '',
category: 'data',
description: '',
@@ -55,12 +52,10 @@ export default function AdminFeaturesPage() {
active: true
})
setEditingId(null)
- setShowAddForm(false)
}
function startEdit(feature) {
setFormData({
- id: feature.id,
name: feature.name,
category: feature.category,
description: feature.description || '',
@@ -73,7 +68,6 @@ export default function AdminFeaturesPage() {
active: feature.active
})
setEditingId(feature.id)
- setShowAddForm(false)
}
async function handleSave() {
@@ -81,7 +75,6 @@ export default function AdminFeaturesPage() {
setError('')
setSuccess('')
- // Validation
if (!formData.name.trim()) {
setError('Name erforderlich')
return
@@ -100,21 +93,8 @@ export default function AdminFeaturesPage() {
active: formData.active
}
- if (editingId) {
- // Update existing
- await api.updateFeature(editingId, payload)
- setSuccess('Feature aktualisiert')
- } else {
- // Create new
- if (!formData.id.trim()) {
- setError('ID erforderlich')
- return
- }
- payload.id = formData.id.trim()
- await api.createFeature(payload)
- setSuccess('Feature erstellt')
- }
-
+ await api.updateFeature(editingId, payload)
+ setSuccess('Feature aktualisiert')
await loadFeatures()
resetForm()
} catch (e) {
@@ -122,18 +102,6 @@ export default function AdminFeaturesPage() {
}
}
- async function handleDelete(featureId) {
- if (!confirm('Feature wirklich löschen?')) return
- try {
- setError('')
- await api.deleteFeature(featureId)
- setSuccess('Feature gelöscht')
- await loadFeatures()
- } catch (e) {
- setError(e.message)
- }
- }
-
if (loading) return (
@@ -148,7 +116,7 @@ export default function AdminFeaturesPage() {
]
const resetPeriodOptions = [
- { value: 'never', label: 'Nie' },
+ { value: 'never', label: 'Nie (akkumuliert)' },
{ value: 'daily', label: 'Täglich' },
{ value: 'monthly', label: 'Monatlich' }
]
@@ -161,26 +129,27 @@ export default function AdminFeaturesPage() {
return (
{/* Header */}
-
-
-
- Feature-Registry
-
-
- Verfügbare Features verwalten
-
+
+
+ Feature-Konfiguration
+
+
+ Limitierungs-Einstellungen für registrierte Features
+
+
+
+ {/* Info Box */}
+
+
+
+ Hinweis: Features werden automatisch via Code registriert.
+ Hier können nur Basis-Einstellungen (Limit-Typ, Reset-Periode, Standards) angepasst werden.
+ Neue Features hinzuzufügen erfordert Code-Änderungen im Backend.
- {!showAddForm && !editingId && (
-
setShowAddForm(true)}
- >
- Neues Feature
-
- )}
{/* Messages */}
@@ -201,15 +170,15 @@ export default function AdminFeaturesPage() {
)}
- {/* Add/Edit Form */}
- {(showAddForm || editingId) && (
+ {/* Edit Form */}
+ {editingId && (
- {editingId ? 'Feature bearbeiten' : 'Neues Feature erstellen'}
+ Feature konfigurieren
- {/* ID (nur bei Neuanlage) */}
- {!editingId && (
-
- ID (Slug) *
- setFormData({ ...formData, id: e.target.value })}
- placeholder="z.B. weight_entries"
- />
-
- )}
+ {/* Feature ID (read-only) */}
+
+ Feature ID
+
+
{/* Name */}
@@ -261,7 +228,7 @@ export default function AdminFeaturesPage() {
- Typ
+ Limit-Typ
setFormData({ ...formData, default_limit: e.target.value })}
placeholder="Leer = unbegrenzt"
/>
+
+ Fallback wenn kein Tier-Limit gesetzt
+
@@ -351,14 +321,14 @@ export default function AdminFeaturesPage() {
checked={formData.active}
onChange={(e) => setFormData({ ...formData, active: e.target.checked })}
/>
- Aktiv
+ Feature aktiviert
{/* Actions */}
- {editingId ? 'Aktualisieren' : 'Erstellen'}
+ Speichern
Abbrechen
@@ -373,21 +343,20 @@ export default function AdminFeaturesPage() {
- Name
- ID
+ Feature
Kategorie
- Typ
+ Limit-Typ
Reset
- Std-Limit
- Aktiv
- Aktionen
+ Standard
+ Status
+ Aktion
{features.length === 0 && (
-
- Keine Features vorhanden
+
+ Keine Features registriert
)}
@@ -396,20 +365,21 @@ export default function AdminFeaturesPage() {
key={feature.id}
style={{
borderBottom: idx === features.length - 1 ? 'none' : '1px solid var(--border)',
- background: feature.active ? 'transparent' : 'var(--surface)'
+ background: feature.active ? 'transparent' : 'var(--surface)',
+ opacity: feature.active ? 1 : 0.6
}}
>
-
- {feature.name}
+
+ {feature.name}
+
+ {feature.id}
+
{feature.description && (
{feature.description}
)}
-
- {feature.id}
-
-
- {feature.limit_type === 'boolean' ? '✓/✗' : '123'}
+
+
+ {feature.limit_type === 'boolean' ? '✓/✗' : '123'}
+
- {feature.reset_period}
+ {feature.reset_period === 'never' ? '∞' : feature.reset_period === 'daily' ? '1d' : '1m'}
{feature.default_limit === null ? '∞' : feature.default_limit}
{feature.active ? (
- ✓
+ ✓ Aktiv
) : (
- ✗
+ ✗ Inaktiv
)}
-
- startEdit(feature)}
- style={{ padding: '4px 8px', fontSize: 11 }}
- >
-
-
- handleDelete(feature.id)}
- style={{ padding: '4px 8px', fontSize: 11, color: 'var(--danger)' }}
- >
-
-
-
+ startEdit(feature)}
+ style={{ padding: '6px 12px', fontSize: 12 }}
+ >
+ Konfigurieren
+
))}
+
+ {/* Legend */}
+
+
Limit-Typ:
+
+ Boolean (✓/✗): Feature ist entweder verfügbar oder nicht (z.B. "KI aktiviert")
+
+
+ Count (123): Feature hat ein Nutzungs-Limit (z.B. "max. 50 Einträge")
+
+
+ Reset-Periode: ∞ = nie, 1d = täglich, 1m = monatlich
+
+
)
}