Files
Client/lib/view/login/widgets/login_form_parts.dart
T

110 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
/// Filled, borderless text field look shared by both login cards.
InputDecoration loginInputDecoration(
ThemeData theme,
String label,
IconData icon,
) => InputDecoration(
labelText: label,
prefixIcon: Icon(icon),
filled: true,
fillColor: theme.colorScheme.surfaceContainerHighest.withValues(alpha: 0.4),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide(color: theme.colorScheme.primary, width: 1.5),
),
);
/// Card frame with heading and hint line shared by both login cards.
class LoginCardFrame extends StatelessWidget {
final String title;
final String hint;
final List<Widget> children;
const LoginCardFrame({
required this.title,
required this.hint,
required this.children,
super.key,
});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
return Card(
elevation: 8,
shadowColor: Colors.black.withValues(alpha: 0.35),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
color: theme.colorScheme.surface,
child: Padding(
padding: const EdgeInsets.fromLTRB(24, 24, 24, 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
title,
style: theme.textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 6),
Text(
hint,
style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurfaceVariant,
),
),
const SizedBox(height: 20),
...children,
],
),
),
);
}
}
/// Full-width primary button that swaps its label for a spinner while busy.
class LoginSubmitButton extends StatelessWidget {
final String label;
final bool loading;
final VoidCallback onPressed;
const LoginSubmitButton({
required this.label,
required this.loading,
required this.onPressed,
super.key,
});
@override
Widget build(BuildContext context) => SizedBox(
height: 50,
child: FilledButton(
onPressed: loading ? null : onPressed,
style: FilledButton.styleFrom(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
textStyle: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
),
child: loading
? const SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2.5,
color: Colors.white,
),
)
: Text(label),
),
);
}