feat: localize license status labels and display detailed status reasons in LicenseCard

This commit is contained in:
estifanos
2026-08-28 07:37:43 +00:00
parent 6d2c01ae73
commit 82b316e90b
3 changed files with 41 additions and 3 deletions

View File

@@ -81,6 +81,11 @@ export function LicenseCard({
// only for a cached response from before those fields existed.
const days = license.daysUntilExpiry ?? daysUntil(license.expiryDate);
const expired = license.status === 'EXPIRED' || days < 0;
// Suspended, cancelled and superseded are none of them "valid until" their
// expiry date — the card used to say exactly that, because only EXPIRED was
// treated as not-current. A suspended licence read as a live one with a grey
// badge.
const current = license.status === 'ACTIVE' && !expired;
const renewable = license.renewable ?? false;
const showDate = useDateDisplayer();
const localized = useLocalized();
@@ -100,9 +105,15 @@ export function LicenseCard({
<Badge
size="sm"
variant="light"
color={expired ? 'red' : license.status === 'ACTIVE' ? 'teal' : 'gray'}
color={expired ? 'red' : current ? 'teal' : 'gray'}
>
{expired ? t('licensing.card.expired') : license.status}
{/* The raw enum was rendered here, so an Amharic page showed
"SUSPENDED" among otherwise translated text. */}
{expired
? t('licensing.card.expired')
: t(`licensing.card.status.${license.status}`, {
defaultValue: license.status,
})}
</Badge>
</Group>
@@ -113,8 +124,19 @@ export function LicenseCard({
<Text size="sm" fw={500}>
{expired
? t('licensing.card.expiredOn', { date: showDate(license.expiryDate) })
: t('licensing.card.validUntil', { date: showDate(license.expiryDate) })}
: current
? t('licensing.card.validUntil', { date: showDate(license.expiryDate) })
: t(`licensing.card.status.${license.status}`, {
defaultValue: license.status,
})}
</Text>
{/* Why it stopped being current. The API returns it; the card threw
it away, leaving the holder to guess. */}
{!current && license.statusReason && (
<Text size="xs" c="dimmed" mt={2}>
{t('licensing.card.statusReason', { reason: license.statusReason })}
</Text>
)}
</Box>
<RequirePermission
anyOf={[

View File

@@ -802,6 +802,14 @@ export const am: Translations = {
renewDays_one: 'አድስ — በ{{count}} ቀን ውስጥ ያበቃል',
renewDays_other: 'አድስ — በ{{count}} ቀናት ውስጥ ያበቃል',
renewFailed: 'ዕድሳት መጀመር አልተቻለም',
status: {
ACTIVE: 'የፀና',
EXPIRED: 'ጊዜው ያለፈበት',
SUSPENDED: 'የታገደ',
CANCELLED: 'የተሰረዘ',
SUPERSEDED: 'በአዲስ የምስክር ወረቀት የተተካ',
},
statusReason: 'ምክንያት፦ {{reason}}',
},
catalogue: {
emptyTitle: 'የሚሰሩበትን የስራ ዘርፍ ይንገሩን',

View File

@@ -802,6 +802,14 @@ export const en = {
renewDays_one: 'Renew — expires in {{count}} day',
renewDays_other: 'Renew — expires in {{count}} days',
renewFailed: 'Could not start the renewal',
status: {
ACTIVE: 'Active',
EXPIRED: 'Expired',
SUSPENDED: 'Suspended',
CANCELLED: 'Cancelled',
SUPERSEDED: 'Replaced by a newer certificate',
},
statusReason: 'Reason: {{reason}}',
},
catalogue: {
emptyTitle: 'Tell us what you operate as',