shinkan-jinkendo/frontend/src/components/FeatureUsageBadge.jsx
Lars 8404a42b6c
Some checks failed
Deploy Development / deploy (push) Successful in 43s
Test Suite / pytest-backend (push) Failing after 2s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 13s
Test Suite / k6 /health Baseline (push) Successful in 42s
Test Suite / playwright-tests (push) Successful in 1m19s
Implement Club Feature Quota Bypass and Update Versioning
- Added support for club feature quota bypass based on portal roles and profile grants in the capabilities check.
- Introduced new functions to handle quota bypass logic in club feature access and consumption.
- Updated the FeatureUsageBadge component to reflect platform exemptions for features.
- Incremented application version to 0.8.195 and database schema version to 20260606083 to reflect these changes.
- Enhanced backend routers to include new logic for consuming club features during AI-related actions.
2026-06-07 07:43:35 +02:00

68 lines
1.8 KiB
JavaScript

import { useEntitlements } from '../context/EntitlementsContext'
/**
* Zeigt Vereins-Kontingent für ein Feature (M4 UsageBadge).
* Unbegrenzt (limit null) → nichts rendern.
*/
export default function FeatureUsageBadge({ featureId = 'ai_calls', label = 'KI-Kontingent' }) {
const { entitlements, loading, error, getFeature } = useEntitlements()
const feat = getFeature(featureId)
if (loading && !feat) {
return (
<span className="feature-usage-badge muted" style={{ fontSize: '0.8rem' }}>
{label}:
</span>
)
}
if (!feat) {
if (error) {
return (
<span
className="feature-usage-badge muted"
style={{ fontSize: '0.8rem', color: 'var(--text3)' }}
title={error}
>
{label}:
</span>
)
}
return null
}
const { used = 0, limit, remaining, allowed, platform_exempt: platformExempt, reason } = feat
if (platformExempt || reason === 'platform_exempt' || reason === 'capability_quota_bypass') {
return (
<span
className="feature-usage-badge"
style={{ fontSize: '0.8rem', color: 'var(--accent-dark)' }}
title="Plattform-Ausnahme: zählt nicht gegen das Vereins-Kontingent"
>
{label}: Plattform (unbegrenzt)
</span>
)
}
// limit === 0 (z. B. Free-Plan ai_calls) anzeigen; nur echtes Unbegrenzt (null) ausblenden
if (limit == null) return null
const tone = !allowed || remaining === 0 ? 'var(--danger)' : 'var(--text2)'
return (
<span
className="feature-usage-badge"
style={{ fontSize: '0.8rem', color: tone }}
title={
entitlements?.plan_id
? `Plan: ${entitlements.plan_id}`
: undefined
}
>
{label}: {used}/{limit}
{remaining != null ? ` (${remaining} übrig)` : ''}
</span>
)
}