diff --git a/frontend/src/components/shared/AvailabilityStatusBadge.test.tsx b/frontend/src/components/shared/AvailabilityStatusBadge.test.tsx
index 6ce0f47..f903cc2 100644
--- a/frontend/src/components/shared/AvailabilityStatusBadge.test.tsx
+++ b/frontend/src/components/shared/AvailabilityStatusBadge.test.tsx
@@ -34,7 +34,23 @@ describe('AvailabilityStatusBadge', () => {
expect(badge.querySelector('.bg-red-100')).toBeTruthy();
});
- it('shows message subtitle when message is non-empty', () => {
+ it('Available always shows the default translated message, ignoring any backend message', () => {
+ renderWithProviders();
+
+ expect(screen.getByTestId('availability-message')).toHaveTextContent(
+ 'System is running normally.',
+ );
+ });
+
+ it('Available shows the default translated message when no message is provided', () => {
+ renderWithProviders();
+
+ expect(screen.getByTestId('availability-message')).toHaveTextContent(
+ 'System is running normally.',
+ );
+ });
+
+ it('Maintenance shows a custom reason when provided', () => {
renderWithProviders(
,
);
@@ -44,16 +60,30 @@ describe('AvailabilityStatusBadge', () => {
);
});
- it('hides message element when message is empty string', () => {
- renderWithProviders();
+ it('Maintenance falls back to default translated message when no reason is provided', () => {
+ renderWithProviders();
- expect(screen.queryByTestId('availability-message')).toBeNull();
+ expect(screen.getByTestId('availability-message')).toHaveTextContent(
+ 'System is undergoing scheduled maintenance.',
+ );
});
- it('hides message element when message prop is omitted', () => {
- renderWithProviders();
+ it('Unavailable shows a custom reason when provided', () => {
+ renderWithProviders(
+ ,
+ );
- expect(screen.queryByTestId('availability-message')).toBeNull();
+ expect(screen.getByTestId('availability-message')).toHaveTextContent(
+ 'Emergency shutdown in progress',
+ );
+ });
+
+ it('Unavailable falls back to default translated message when no reason is provided', () => {
+ renderWithProviders();
+
+ expect(screen.getByTestId('availability-message')).toHaveTextContent(
+ 'System is currently unavailable.',
+ );
});
it('shows stale indicator when stale={true}', () => {
diff --git a/frontend/src/components/shared/AvailabilityStatusBadge.tsx b/frontend/src/components/shared/AvailabilityStatusBadge.tsx
index cae3f66..c43f0b7 100644
--- a/frontend/src/components/shared/AvailabilityStatusBadge.tsx
+++ b/frontend/src/components/shared/AvailabilityStatusBadge.tsx
@@ -10,24 +10,34 @@ interface AvailabilityStatusBadgeProps {
const STATUS_CONFIG: Record<
AvailabilityStatus,
- { labelKey: string; colorClass: string; Icon: React.ComponentType<{ className?: string }> }
+ {
+ labelKey: string;
+ defaultMessageKey: string;
+ /** When true the default translated message is always shown, ignoring any backend message. */
+ alwaysDefault: boolean;
+ colorClass: string;
+ Icon: React.ComponentType<{ className?: string }>;
+ }
> = {
Available: {
labelKey: 'availability.available',
- colorClass:
- 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
+ defaultMessageKey: 'availability.messageAvailable',
+ alwaysDefault: true,
+ colorClass: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200',
Icon: CheckCircle,
},
Maintenance: {
labelKey: 'availability.maintenance',
- colorClass:
- 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200',
+ defaultMessageKey: 'availability.messageMaintenance',
+ alwaysDefault: false,
+ colorClass: 'bg-amber-100 text-amber-800 dark:bg-amber-900 dark:text-amber-200',
Icon: AlertTriangle,
},
Unavailable: {
labelKey: 'availability.unavailable',
- colorClass:
- 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
+ defaultMessageKey: 'availability.messageUnavailable',
+ alwaysDefault: false,
+ colorClass: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200',
Icon: XCircle,
},
};
@@ -38,7 +48,8 @@ export function AvailabilityStatusBadge({
stale = false,
}: AvailabilityStatusBadgeProps) {
const { t } = useTranslation();
- const { labelKey, colorClass, Icon } = STATUS_CONFIG[status];
+ const { labelKey, defaultMessageKey, alwaysDefault, colorClass, Icon } = STATUS_CONFIG[status];
+ const displayMessage = alwaysDefault ? t(defaultMessageKey) : (message || t(defaultMessageKey));
return (
{t(labelKey)}
- {message && message.length > 0 && (
-
- {message}
-
- )}
+
+ {displayMessage}
+
{stale && (
+/// Status en optionele admin-melding van de systeembeschikbaarheid.
+///
+public record AvailabilityStatusDetails(AvailabilityStatus Status, string? Message);
diff --git a/src/SlpModularCms.Core/Availability/IAvailabilityService.cs b/src/SlpModularCms.Core/Availability/IAvailabilityService.cs
index 3860c2c..149fe0e 100644
--- a/src/SlpModularCms.Core/Availability/IAvailabilityService.cs
+++ b/src/SlpModularCms.Core/Availability/IAvailabilityService.cs
@@ -10,4 +10,9 @@ public interface IAvailabilityService
///
///
De huidige .
Task
IsAvailableAsync();
+
+ ///
+ /// Geeft de huidige status inclusief de optionele admin-melding terug.
+ ///
+ Task GetStatusDetailsAsync();
}
diff --git a/src/SlpModularCms.Modules.Availability/Controllers/AvailabilityController.cs b/src/SlpModularCms.Modules.Availability/Controllers/AvailabilityController.cs
index 71284c0..533ca6b 100644
--- a/src/SlpModularCms.Modules.Availability/Controllers/AvailabilityController.cs
+++ b/src/SlpModularCms.Modules.Availability/Controllers/AvailabilityController.cs
@@ -20,12 +20,12 @@ public class AvailabilityController : ControllerBase
[AllowAnonymous]
public async Task GetStatus()
{
- var status = await _availabilityService.IsAvailableAsync();
+ var details = await _availabilityService.GetStatusDetailsAsync();
return Ok(new
{
- Status = status.ToString(),
+ Status = details.Status.ToString(),
CheckedAt = DateTimeOffset.UtcNow,
- Message = string.Empty,
+ Message = details.Message ?? string.Empty,
});
}
diff --git a/src/SlpModularCms.Modules.Availability/Services/PersistentAvailabilityService.cs b/src/SlpModularCms.Modules.Availability/Services/PersistentAvailabilityService.cs
index 57ec202..4ec129e 100644
--- a/src/SlpModularCms.Modules.Availability/Services/PersistentAvailabilityService.cs
+++ b/src/SlpModularCms.Modules.Availability/Services/PersistentAvailabilityService.cs
@@ -54,6 +54,24 @@ public class PersistentAvailabilityService : IAvailabilityService
}
}
+ public async Task GetStatusDetailsAsync()
+ {
+ try
+ {
+ var state = await _context.AvailabilityStates.FirstOrDefaultAsync();
+ if (state == null)
+ return new AvailabilityStatusDetails(AvailabilityStatus.Available, null);
+
+ return new AvailabilityStatusDetails(state.Status, state.Message);
+ }
+ catch (Exception)
+ {
+ _lastErrorTime = DateTimeOffset.UtcNow;
+ _cachedStatus = AvailabilityStatus.Available;
+ return new AvailabilityStatusDetails(_cachedStatus, null);
+ }
+ }
+
///
/// Update de globale systeemstatus.
///