import 'package:flutter/material.dart'; import '../core/app_theme.dart'; class AppPage extends StatelessWidget { const AppPage({ super.key, required this.child, this.appBar, this.bottomNavigationBar, this.scrollController, }); final Widget child; final PreferredSizeWidget? appBar; final Widget? bottomNavigationBar; final ScrollController? scrollController; @override Widget build(BuildContext context) { return Scaffold( appBar: appBar, bottomNavigationBar: bottomNavigationBar, body: SafeArea( top: appBar == null, child: SingleChildScrollView( controller: scrollController, padding: const EdgeInsets.fromLTRB(16, 20, 16, 24), child: child, ), ), ); } } class SectionCard extends StatelessWidget { const SectionCard({ super.key, required this.child, this.tint, this.onTap, this.padding = const EdgeInsets.all(14), }); final Widget child; final Color? tint; final VoidCallback? onTap; final EdgeInsets padding; @override Widget build(BuildContext context) { final content = Padding(padding: padding, child: child); return Material( color: tint ?? AppColors.surface, borderRadius: BorderRadius.circular(16), child: InkWell( onTap: onTap, borderRadius: BorderRadius.circular(16), child: Container( decoration: BoxDecoration( border: Border.all(color: AppColors.line), borderRadius: BorderRadius.circular(16), ), child: content, ), ), ); } } class PrimaryButton extends StatelessWidget { const PrimaryButton({ super.key, required this.label, required this.onPressed, this.icon, }); final String label; final VoidCallback? onPressed; final IconData? icon; @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, height: 50, child: FilledButton.icon( onPressed: onPressed, icon: icon == null ? const SizedBox.shrink() : Icon(icon), label: Text(label), style: FilledButton.styleFrom( backgroundColor: AppColors.green, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), ), ); } } class SecondaryButton extends StatelessWidget { const SecondaryButton({ super.key, required this.label, required this.onPressed, }); final String label; final VoidCallback? onPressed; @override Widget build(BuildContext context) { return SizedBox( width: double.infinity, height: 48, child: OutlinedButton( onPressed: onPressed, style: OutlinedButton.styleFrom( foregroundColor: AppColors.ink, side: BorderSide(color: AppColors.line), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), child: Text(label), ), ); } } class Eyebrow extends StatelessWidget { const Eyebrow(this.text, {super.key}); final String text; @override Widget build(BuildContext context) => Text( text, style: TextStyle( color: AppColors.green, fontWeight: FontWeight.w600, fontSize: 13, ), ); } class SpacedColumn extends StatelessWidget { const SpacedColumn({ super.key, required this.children, this.spacing = 12, this.crossAxisAlignment = CrossAxisAlignment.start, }); final List children; final double spacing; final CrossAxisAlignment crossAxisAlignment; @override Widget build(BuildContext context) => Column( crossAxisAlignment: crossAxisAlignment, children: [ for (var index = 0; index < children.length; index++) ...[ children[index], if (index < children.length - 1) SizedBox(height: spacing), ], ], ); }