import 'package:flutter/material.dart'; import 'package:pshared/models/payment/status.dart'; import 'package:pweb/generated/i18n/app_localizations.dart'; class StatusView { final String label; final Color backgroundColor; final Color foregroundColor; StatusView({ required this.label, required this.backgroundColor, Color? foregroundColor, }) : foregroundColor = foregroundColor ?? (backgroundColor.computeLuminance() > 0.5 ? Colors.black : Colors.white); Color get color => backgroundColor; } StatusView operationStatusView( AppLocalizations l10n, ColorScheme scheme, OperationStatus status, ) { return operationStatusViewFromToken( l10n, scheme, operationStatusTokenFromEnum(status), ); } StatusView operationStatusViewFromToken( AppLocalizations l10n, ColorScheme scheme, String? rawState, { String? fallbackLabel, }) { final token = normalizeOperationStatusToken(rawState); switch (token) { case 'success': case 'succeeded': case 'completed': case 'confirmed': case 'settled': return StatusView( label: l10n.operationStatusSuccessful, backgroundColor: scheme.tertiaryContainer, foregroundColor: scheme.onTertiaryContainer, ); case 'skipped': return StatusView( label: l10n.operationStepStateSkipped, backgroundColor: scheme.secondaryContainer, foregroundColor: scheme.onSecondaryContainer, ); case 'error': case 'failed': case 'rejected': case 'aborted': return StatusView( label: l10n.operationStatusUnsuccessful, backgroundColor: scheme.errorContainer, foregroundColor: scheme.onErrorContainer, ); case 'cancelled': case 'canceled': return StatusView( label: l10n.paymentStatusCancelled, backgroundColor: scheme.surfaceContainerHighest, foregroundColor: scheme.onSurfaceVariant, ); case 'processing': case 'running': case 'executing': case 'in_progress': case 'started': return StatusView( label: l10n.paymentStatusProcessing, backgroundColor: scheme.primaryContainer, foregroundColor: scheme.onPrimaryContainer, ); case 'pending': case 'queued': case 'waiting': case 'created': case 'scheduled': return StatusView( label: l10n.operationStatusPending, backgroundColor: scheme.secondary, foregroundColor: scheme.onSecondary, ); case 'needs_attention': return StatusView( label: l10n.operationStepStateNeedsAttention, backgroundColor: scheme.tertiary, foregroundColor: scheme.onTertiary, ); case 'retrying': return StatusView( label: l10n.operationStepStateRetrying, backgroundColor: scheme.primary, foregroundColor: scheme.onPrimary, ); default: return StatusView( label: fallbackLabel ?? humanizeOperationStatusToken(token), backgroundColor: scheme.surfaceContainerHighest, foregroundColor: scheme.onSurfaceVariant, ); } } String operationStatusTokenFromEnum(OperationStatus status) { switch (status) { case OperationStatus.pending: return 'pending'; case OperationStatus.processing: return 'processing'; case OperationStatus.retrying: return 'retrying'; case OperationStatus.success: return 'success'; case OperationStatus.skipped: return 'skipped'; case OperationStatus.cancelled: return 'cancelled'; case OperationStatus.needsAttention: return 'needs_attention'; case OperationStatus.error: return 'error'; } } String normalizeOperationStatusToken(String? state) { final normalized = (state ?? '').trim().toLowerCase(); if (normalized.isEmpty) return 'pending'; return normalized .replaceFirst(RegExp(r'^step_execution_state_'), '') .replaceFirst(RegExp(r'^orchestration_state_'), ''); } String humanizeOperationStatusToken(String token) { final parts = token.split('_').where((part) => part.isNotEmpty).toList(); if (parts.isEmpty) return token; return parts .map( (part) => '${part[0].toUpperCase()}${part.substring(1).toLowerCase()}', ) .join(' '); }