Files
Client/lib/view/login/widgets/login_error_banner.dart
T
2026-05-08 20:12:40 +02:00

82 lines
2.8 KiB
Dart

import 'package:flutter/material.dart';
import '../../../widget/info_dialog.dart';
/// Tappable error banner shown beneath the login form. Animates in/out via
/// AnimatedSize. When [details] is non-null, tapping opens an InfoDialog
/// with the technical error text.
class LoginErrorBanner extends StatelessWidget {
final String? message;
final String? details;
const LoginErrorBanner({
required this.message,
required this.details,
super.key,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return AnimatedSize(
duration: const Duration(milliseconds: 180),
curve: Curves.easeOut,
child: message == null
? const SizedBox(height: 0, width: double.infinity)
: Padding(
padding: const EdgeInsets.only(top: 14),
child: Material(
color: theme.colorScheme.errorContainer.withValues(alpha: 0.6),
borderRadius: BorderRadius.circular(12),
child: InkWell(
onTap: details != null
? () => InfoDialog.show(
context,
details!,
copyable: true,
title: 'Fehlerdetails',
)
: null,
borderRadius: BorderRadius.circular(12),
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 10,
),
child: Row(
children: [
Icon(
Icons.error_outline,
size: 20,
color: theme.colorScheme.onErrorContainer,
),
const SizedBox(width: 10),
Expanded(
child: Text(
message!,
style: TextStyle(
color: theme.colorScheme.onErrorContainer,
fontSize: 13,
height: 1.3,
),
),
),
if (details != null) ...[
const SizedBox(width: 8),
Icon(
Icons.chevron_right,
size: 20,
color: theme.colorScheme.onErrorContainer
.withValues(alpha: 0.7),
),
],
],
),
),
),
),
),
);
}
}