Deliver localized auth app with verification and go_router
Integrate themed login/signup, EN/RU localization, shared dummy providers, verification recovery screens and named URL routes. Store frontend guidelines, workflow skills, validation and delivery documentation. Related to #2, #3, #5 and #6.
This commit is contained in:
1 parent
27424ed886
commit
10a278c65a
44 files changed
+4128
-28
No files matched your search
@@ -0,0 +1,158 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../generated/i18n/app_localizations.dart';
|
||||
|
||||
class BrandWordmark extends StatelessWidget {
|
||||
const BrandWordmark({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.primary,
|
||||
borderRadius: BorderRadius.circular(9),
|
||||
),
|
||||
child: Icon(Icons.bolt, color: theme.colorScheme.onPrimary, size: 26),
|
||||
),
|
||||
const SizedBox(width: 9),
|
||||
Flexible(
|
||||
child: Text(
|
||||
'sxchnge',
|
||||
style: theme.textTheme.headlineMedium!.copyWith(
|
||||
letterSpacing: -1.5,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class BrandPanel extends StatelessWidget {
|
||||
const BrandPanel({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l = AppLocalizations.of(context)!;
|
||||
final theme = Theme.of(context);
|
||||
final colors = theme.colorScheme;
|
||||
return ColoredBox(
|
||||
color: colors.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(48),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const BrandWordmark(),
|
||||
const SizedBox(height: 64),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
l.brandEyebrow,
|
||||
style: theme.textTheme.labelMedium!.copyWith(
|
||||
letterSpacing: 1.5,
|
||||
color: colors.primary,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
l.brandHeading,
|
||||
style: theme.textTheme.displayLarge!.copyWith(
|
||||
fontSize: 68,
|
||||
height: 1.03,
|
||||
letterSpacing: -3,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
Text(
|
||||
l.brandIntro,
|
||||
style: theme.textTheme.bodyLarge!.copyWith(
|
||||
color: colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 48),
|
||||
const _MotionCard(),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 64),
|
||||
Text(
|
||||
l.brandFooter,
|
||||
style: theme.textTheme.labelSmall!.copyWith(
|
||||
letterSpacing: 1,
|
||||
color: colors.onSurfaceVariant,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _MotionCard extends StatelessWidget {
|
||||
const _MotionCard();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l = AppLocalizations.of(context)!;
|
||||
final theme = Theme.of(context);
|
||||
final colors = theme.colorScheme;
|
||||
return TweenAnimationBuilder<double>(
|
||||
tween: Tween(begin: 0, end: 1),
|
||||
duration: MediaQuery.disableAnimationsOf(context)
|
||||
? Duration.zero
|
||||
: const Duration(milliseconds: 700),
|
||||
curve: Curves.easeOutCubic,
|
||||
builder: (context, value, child) => Opacity(
|
||||
opacity: value,
|
||||
child: Transform.translate(
|
||||
offset: Offset(0, (1 - value) * 24),
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
child: Transform.rotate(
|
||||
angle: -0.035,
|
||||
child: Card(
|
||||
color: colors.primaryContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(28),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
l.brandCard,
|
||||
style: theme.textTheme.headlineSmall!.copyWith(
|
||||
color: colors.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(18),
|
||||
decoration: BoxDecoration(
|
||||
color: colors.tertiaryContainer,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
Icons.north_east,
|
||||
size: 38,
|
||||
color: colors.onTertiaryContainer,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user