diff --git a/.gitignore b/.gitignore index 6339b74..653a6a6 100644 --- a/.gitignore +++ b/.gitignore @@ -61,4 +61,4 @@ tmp/ #.claude Konfiguration .claude/ -.claude/settings.local.json \ No newline at end of file +.claude/settings.local.jsonfrontend/package-lock.json diff --git a/frontend/src/pages/AdminUserRestrictionsPage.jsx b/frontend/src/pages/AdminUserRestrictionsPage.jsx index aad3476..6376145 100644 --- a/frontend/src/pages/AdminUserRestrictionsPage.jsx +++ b/frontend/src/pages/AdminUserRestrictionsPage.jsx @@ -77,37 +77,48 @@ export default function AdminUserRestrictionsPage() { function handleChange(featureId, value) { const newChanges = { ...changes } - // Empty string means: remove override (if exists) or do nothing + // Empty string means: remove override if (value === '') { - newChanges[featureId] = { action: 'remove' } - } else { - // Parse value - let parsedValue = null - const lowerValue = value.toLowerCase().trim() - - // Accept multiple formats for unlimited - if (lowerValue === 'unlimited' || lowerValue === 'unbegrenzt' || - value === '∞' || lowerValue === 'inf' || lowerValue === '999999') { - parsedValue = null - } else if (value === '0') { - parsedValue = 0 - } else { - const num = parseInt(value) - if (!isNaN(num) && num >= 0) { - parsedValue = num - } else { - return // invalid - } - } - newChanges[featureId] = { action: 'set', value: parsedValue } + newChanges[featureId] = { action: 'remove', tempValue: '' } + setChanges(newChanges) + return } + // Parse value (EXACTLY like TierLimitsPage) + let parsedValue = null + if (value === 'unlimited' || value === '∞') { + parsedValue = null // unlimited + } else if (value === '0' || value === 'disabled') { + parsedValue = 0 // disabled + } else { + const num = parseInt(value) + if (!isNaN(num) && num >= 0) { + parsedValue = num + } else { + return // invalid input, ignore + } + } + + newChanges[featureId] = { action: 'set', value: parsedValue, tempValue: value } setChanges(newChanges) } - function handleToggle(featureId, currentEnabled) { + function handleToggle(featureId) { + // Get current state + const restriction = restrictions.find(r => r.feature_id === featureId) + let currentValue = restriction?.limit_value ?? null + + // Check if there's a pending change + if (featureId in changes && changes[featureId].action === 'set') { + currentValue = changes[featureId].value + } + + // Toggle between 1 (enabled) and 0 (disabled) + const isCurrentlyEnabled = currentValue !== 0 && currentValue !== '0' + const newValue = isCurrentlyEnabled ? 0 : 1 + const newChanges = { ...changes } - newChanges[featureId] = { action: 'toggle', enabled: !currentEnabled } + newChanges[featureId] = { action: 'set', value: newValue, tempValue: newValue.toString() } setChanges(newChanges) } @@ -147,24 +158,6 @@ export default function AdminUserRestrictionsPage() { }) } changeCount++ - } else if (change.action === 'toggle') { - // Toggle enabled state - if (existingRestriction) { - await api.updateUserRestriction(existingRestriction.id, { - enabled: change.enabled - }) - changeCount++ - } else { - // Create new restriction with toggle state - await api.createUserRestriction({ - profile_id: selectedUserId, - feature_id: featureId, - limit_value: change.enabled ? 1 : 0, - enabled: true, - reason: 'Admin override' - }) - changeCount++ - } } } @@ -182,28 +175,42 @@ export default function AdminUserRestrictionsPage() { if (featureId in changes) { const change = changes[featureId] if (change.action === 'remove') return '' - if (change.action === 'set') return change.value === null ? '' : change.value - if (change.action === 'toggle') return change.enabled ? 1 : 0 + if (change.action === 'set') { + // Use tempValue for display if available, otherwise format the value + return change.tempValue !== undefined ? change.tempValue : formatValue(change.value) + } } // Show existing restriction value (or empty if no restriction) const restriction = restrictions.find(r => r.feature_id === featureId) if (!restriction) return '' // No override = empty input - return restriction.limit_value === null ? '' : restriction.limit_value + return formatValue(restriction.limit_value) + } + + function formatValue(val) { + if (val === '' || val === null || val === undefined) return '' + if (val === '∞' || val === 'unlimited') return '∞' + if (val === 0 || val === '0') return '0' + return val.toString() } function getToggleState(featureId) { // Check pending changes first - if (featureId in changes && changes[featureId].action === 'toggle') { - return changes[featureId].enabled + if (featureId in changes && changes[featureId].action === 'set') { + const val = changes[featureId].value + return val !== 0 && val !== '0' } // Check existing restriction const restriction = restrictions.find(r => r.feature_id === featureId) - if (!restriction) return true // Default: enabled + if (!restriction) { + // No override: use tier default + const tierLimit = tierLimits[featureId] + return tierLimit !== 0 && tierLimit !== '0' + } // For boolean features: limit_value determines state - return restriction.limit_value !== 0 + return restriction.limit_value !== 0 && restriction.limit_value !== '0' } function hasOverride(featureId) { @@ -427,7 +434,7 @@ export default function AdminUserRestrictionsPage() { {feature.limit_type === 'boolean' ? (