import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../../core/constants/error_whitelist.dart'; import '../../../core/i18n/locale_utils.dart'; import '../../../core/services/auth_proxy_service.dart'; import '../../../core/widgets/theme_toggle_button.dart'; import 'package:userfront/i18n.dart'; class ErrorScreen extends StatelessWidget { final String? errorId; final String? errorCode; final String? description; final bool? isProdOverride; const ErrorScreen({ super.key, this.errorId, this.errorCode, this.description, this.isProdOverride, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; final isProd = isProdOverride ?? AuthProxyService.isProdEnv; final normalizedCode = (errorCode ?? '').trim(); final hasCode = normalizedCode.isNotEmpty; final internalWhitelistFallback = internalErrorWhitelistMessages[normalizedCode]; final isInternalWhitelisted = internalWhitelistFallback != null; final isOryBypass = hasCode && oryBypassErrorCodes.contains(normalizedCode); final isKnownProdCode = hasCode && (isInternalWhitelisted || isOryBypass); final errorType = isProd ? (isKnownProdCode ? normalizedCode : 'unknown_error') : (hasCode ? normalizedCode : 'unknown_error'); final title = isProd ? tr('msg.userfront.error.title') : (hasCode ? tr( 'msg.userfront.error.title_with_code', params: {'code': normalizedCode}, ) : tr('msg.userfront.error.title_generic')); final detail = isProd ? (isInternalWhitelisted ? tr( 'msg.userfront.error.whitelist.$normalizedCode', fallback: internalWhitelistFallback, ) : (isOryBypass ? tr( 'msg.userfront.error.ory.$normalizedCode', fallback: (description?.isNotEmpty == true) ? description : tr('msg.userfront.error.detail_request'), ) : tr('msg.userfront.error.detail_contact'))) : ((description?.isNotEmpty == true) ? description! : (hasCode ? tr('msg.userfront.error.detail_generic') : tr('msg.userfront.error.detail_request'))); return Scaffold( backgroundColor: colorScheme.surfaceContainerLowest, body: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 560), child: Card( margin: const EdgeInsets.symmetric(horizontal: 24), elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), side: BorderSide(color: colorScheme.outlineVariant), ), child: Padding( padding: const EdgeInsets.fromLTRB(28, 28, 28, 24), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Text( title, style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.w700, color: colorScheme.onSurface, ), ), ), const ThemeToggleButton(compact: true), ], ), const SizedBox(height: 12), Text( detail, style: theme.textTheme.bodyMedium?.copyWith( color: colorScheme.onSurfaceVariant, height: 1.5, ), ), const SizedBox(height: 12), Text( tr('msg.userfront.error.type', params: {'type': errorType}), style: theme.textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant, ), ), if (errorId != null && errorId!.isNotEmpty) ...[ const SizedBox(height: 12), Text( tr('msg.userfront.error.id', params: {'id': errorId!}), style: theme.textTheme.bodySmall?.copyWith( color: colorScheme.onSurfaceVariant, ), ), ], const SizedBox(height: 20), Wrap( spacing: 12, runSpacing: 12, children: [ ElevatedButton( onPressed: () => context.go('/login'), style: ElevatedButton.styleFrom( backgroundColor: colorScheme.primary, foregroundColor: colorScheme.onPrimary, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Text(tr('ui.userfront.error.go_login')), ), OutlinedButton( onPressed: () => context.go(buildLocalizedHomePath(Uri.base)), style: OutlinedButton.styleFrom( foregroundColor: colorScheme.onSurface, padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 12, ), side: BorderSide(color: colorScheme.outline), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), child: Text(tr('ui.userfront.error.go_home')), ), ], ), ], ), ), ), ), ), ); } }