import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:line_icons/line_icons.dart'; import 'package:loader_overlay/loader_overlay.dart'; import '../../../application/auth/auth_bloc.dart'; import '../../../application/auth/logout_form/logout_form_bloc.dart'; import '../../../common/extension/extension.dart'; import '../../../common/theme/theme.dart'; import '../../../injection.dart'; import '../../components/button/button.dart'; import '../../components/spacer/spacer.dart'; import '../../components/toast/flushbar.dart'; import '../../router/app_router.gr.dart'; import 'widgets/account_info.dart'; import 'widgets/app_setting.dart'; import 'widgets/business_setting.dart'; import 'widgets/danger_zone.dart'; import 'widgets/header.dart'; import 'widgets/support.dart'; @RoutePage() class ProfilePage extends StatelessWidget implements AutoRouteWrapper { const ProfilePage({super.key}); @override Widget build(BuildContext context) { return MultiBlocListener( listeners: [ BlocListener( listener: (context, state) { state.failureOrAuthOption.fold( () => null, (either) => either.fold( (f) => AppFlushbar.showAuthFailureToast(context, f), (_) => context.router.replace(const LoginRoute()), ), ); }, ), BlocListener( listenWhen: (previous, current) => previous.isSubmitting != current.isSubmitting, listener: (context, state) { if (state.isSubmitting) { context.loaderOverlay.show(); } else { context.loaderOverlay.hide(); } }, ), ], child: BlocBuilder( builder: (context, state) { return Scaffold( backgroundColor: AppColor.background, body: CustomScrollView( slivers: [ SliverAppBar( backgroundColor: AppColor.primary, elevation: 0, pinned: true, expandedHeight: 264.0, flexibleSpace: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { // Calculate the collapse ratio final double top = constraints.biggest.height; final double collapsedHeight = MediaQuery.of(context).padding.top + kToolbarHeight; final double expandedHeight = 264.0; final double shrinkRatio = ((expandedHeight - top) / (expandedHeight - collapsedHeight)) .clamp(0.0, 1.0); return FlexibleSpaceBar( background: ProfileHeader(user: state.user), titlePadding: const EdgeInsets.only( left: 20, right: 12, bottom: 16, ), title: Opacity( opacity: shrinkRatio, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( context.lang.profile, style: AppStyle.xl.copyWith( fontWeight: FontWeight.w700, fontSize: 18, letterSpacing: -0.5, color: AppColor.white, ), ), ActionIconButton( onTap: () => context.router.push( ProfileEditRoute(user: state.user), ), icon: LineIcons.userEdit, ), ], ), ), ); }, ), ), SliverToBoxAdapter( child: Column( children: [ const SpaceHeight(20), ProfileAccountInfo(user: state.user), const SpaceHeight(12), ProfileBusinessSetting(), const SpaceHeight(12), ProfileAppSetting(), const SpaceHeight(12), ProfileSupport(), const SpaceHeight(12), ProfileDangerZone(), const SpaceHeight(30), ], ), ), ], ), ); }, ), ); } @override Widget wrappedRoute(BuildContext context) => BlocProvider(create: (_) => getIt(), child: this); }