Skip to content

Instantly share code, notes, and snippets.

@mondoktamas
Created March 18, 2022 17:04
Show Gist options
  • Save mondoktamas/e24699d7bc30b4df0567f14798d2aa36 to your computer and use it in GitHub Desktop.
Save mondoktamas/e24699d7bc30b4df0567f14798d2aa36 to your computer and use it in GitHub Desktop.
import 'dart:math';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:sas/application/di/injection.dart';
import 'package:sas/application/domain/entity/initiate_api/passenger_entity.dart';
import 'package:sas/application/domain/entity/traveler/selected_travelers_entity.dart';
import 'package:sas/application/domain/entity/traveler/traveler_entity.dart';
import 'package:sas/application/presentation/features/main/features/book/cubit/select_traveler_cubit/select_travelers_cubit.dart';
import 'package:sas/application/presentation/features/main/features/book/widgets/user_icon_widget.dart';
import 'package:sas/application/presentation/resources/colors.dart';
import 'package:sas/application/presentation/router/router.gr.dart';
import 'package:sas/application/presentation/widgets/button/close_button_for_bottom_sheet.dart';
import 'package:sas/application/presentation/widgets/expansion_container.dart';
import 'package:sas/application/presentation/widgets/ink_button_widget.dart';
class SelectTravelersBottomSheet extends StatelessWidget with AutoRouteWrapper {
const SelectTravelersBottomSheet(
this._numberOfTravelersModel, {
final Key? key,
}) : super(key: key);
final SelectedTravelersEntity _numberOfTravelersModel;
@override
Widget wrappedRoute(final BuildContext context) => BlocProvider<SelectTravelersCubit>(
create: (_) => getIt<SelectTravelersCubit>()..initSelectTravelerBloc(_numberOfTravelersModel),
child: ClipRRect(
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(18),
topRight: Radius.circular(18),
),
child: ColoredBox(
color: cffF8F6F6,
child: this,
),
),
);
@override
Widget build(final BuildContext context) => Stack(
children: [
SingleChildScrollView(
physics: const ClampingScrollPhysics(),
padding: EdgeInsets.only(bottom: 64 + max(16, MediaQuery.of(context).viewPadding.bottom)),
child: Column(
children: [
const _SelectTravelersHeader(),
Divider(
height: 1,
color: darkGrey.withOpacity(0.30),
),
const _SavedTravelers(),
Divider(
height: 1,
color: darkGrey.withOpacity(0.30),
),
Column(
children: const [
SizedBox(
height: 36,
),
_AdultAndChildrenSelector(),
SizedBox(
height: 16,
),
_YouthSelector(),
SizedBox(
height: 32,
),
],
),
],
),
),
Positioned(
bottom: max(16.0, MediaQuery.of(context).viewPadding.bottom),
left: 20.0,
right: 20.0,
child: InkButtonWidget(
onTap: () => context.router.pop(context.read<SelectTravelersCubit>().state.getNumberOfTravelersModel),
backgroundColor: buttonColor,
borderRadius: 4,
padding: 18,
child: Text(
AppLocalizations.of(context)!.select,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.button!.copyWith(
color: accentColor,
fontSize: 18,
),
),
),
),
],
);
}
class _SelectTravelersHeader extends StatelessWidget {
const _SelectTravelersHeader({final Key? key}) : super(key: key);
@override
Widget build(final BuildContext context) => Container(
color: white,
padding: const EdgeInsets.fromLTRB(26, 30, 26, 26),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.who_is_traveling,
style: Theme.of(context).textTheme.headline6!.copyWith(
color: dark,
fontSize: 18,
height: 24 / 18,
),
),
const CloseButtonForBottomSheet(),
],
),
);
}
class _AdultAndChildrenSelector extends StatelessWidget {
const _AdultAndChildrenSelector({final Key? key}) : super(key: key);
@override
Widget build(final BuildContext context) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: BlocBuilder<SelectTravelersCubit, SelectTravelersState>(
builder: (context, state) => Container(
decoration: BoxDecoration(
color: white,
borderRadius: BorderRadius.circular(5),
boxShadow: const [
tabBoxShadow,
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: ExpansionContainer(
isExpanded: state.adultCategoryExpanded,
onExpansionChanged: context.read<SelectTravelersCubit>().onAdultCategoryExpanded,
showChildrenDivider: false,
childrenPadding: const EdgeInsets.only(
top: 21.5,
left: 21,
bottom: 16,
right: 14.5,
),
title: state.adultCategoryExpanded
? null
: Padding(
padding: const EdgeInsets.only(
top: 18,
bottom: 17,
left: 21,
),
child: Text(
AppLocalizations.of(context)!.adult_children_title,
style: Theme.of(context).textTheme.subtitle2!.copyWith(color: darkGrey),
),
),
children: [
_TravelerItem(
title: AppLocalizations.of(context)!.adults,
bodyText: AppLocalizations.of(context)!.adults_conditions,
value: state.adults,
isIncrement: state.isIncrementAdults,
isDecrement: state.isDecrementAdults,
travelerType: TravelerType.ADT,
),
const SizedBox(height: 18),
_TravelerItem(
title: AppLocalizations.of(context)!.children,
bodyText: AppLocalizations.of(context)!.children_conditions,
value: state.children,
isIncrement: state.isIncrementChildren,
isDecrement: state.isDecrementChildren,
travelerType: TravelerType.CHD,
),
const SizedBox(height: 18),
_TravelerItem(
title: AppLocalizations.of(context)!.infants,
bodyText: AppLocalizations.of(context)!.infants_conditions,
value: state.infants,
isIncrement: state.isIncrementInfants,
isDecrement: state.isDecrementInfants,
travelerType: TravelerType.INF,
),
],
),
),
),
),
);
}
class _YouthSelector extends StatelessWidget {
const _YouthSelector({final Key? key}) : super(key: key);
@override
Widget build(final BuildContext context) => Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: BlocBuilder<SelectTravelersCubit, SelectTravelersState>(
builder: (context, state) => Container(
decoration: BoxDecoration(
color: white,
borderRadius: BorderRadius.circular(5),
boxShadow: const [
tabBoxShadow,
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(5),
child: ExpansionContainer(
childrenPadding: const EdgeInsets.only(
top: 21.5,
left: 21,
bottom: 16,
right: 14.5,
),
isExpanded: state.youthCategoryExpanded,
onExpansionChanged: context.read<SelectTravelersCubit>().onYouthCategoryExpanded,
showChildrenDivider: false,
title: state.youthCategoryExpanded
? null
: Padding(
padding: const EdgeInsets.only(
top: 18,
bottom: 17,
left: 21,
),
child: Text(
AppLocalizations.of(context)!.youth_tickets_title,
style: Theme.of(context).textTheme.subtitle2!.copyWith(color: darkGrey),
),
),
children: [
_TravelerItem(
title: AppLocalizations.of(context)!.youths,
bodyText: AppLocalizations.of(context)!.youth_conditions,
value: state.youths,
isIncrement: state.isIncrementYouth,
isDecrement: state.isDecrementYouth,
travelerType: TravelerType.YTH,
),
const SizedBox(
height: 24,
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: lightBlue4,
),
padding: const EdgeInsets.symmetric(
vertical: 10.5,
horizontal: 24,
),
child: Text(
AppLocalizations.of(context)!.youth_ticket_booking_note,
style: Theme.of(context).textTheme.bodyText1!.copyWith(
height: 18 / 14,
),
),
),
],
),
),
),
),
);
}
class _SavedTravelers extends StatelessWidget {
const _SavedTravelers({
final Key? key,
}) : super(key: key);
Future<void> _openNewTravelerBottomSheet(final BuildContext context) async {
final bloc = context.read<SelectTravelersCubit>();
final result = await context.router.push(AddAndEditTravelerRoute());
if (result != null && result is bool) {
if (result) await bloc.loadSavedTravelers();
}
}
@override
Widget build(final BuildContext context) => Container(
color: white,
padding: const EdgeInsets.only(top: 17, bottom: 26),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 27),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
AppLocalizations.of(context)!.saved_travelers,
style: Theme.of(context).textTheme.headline5,
),
InkButtonWidget(
onTap: () => _openNewTravelerBottomSheet(context),
padding: 5,
child: Row(
children: [
const Padding(
padding: EdgeInsets.only(top: 3),
child: Icon(
Icons.add_outlined,
color: dark,
size: 19,
),
),
Text(
AppLocalizations.of(context)!.add,
style: Theme.of(context).textTheme.subtitle1!.copyWith(height: 20 / 14),
),
],
),
),
],
),
),
BlocBuilder<SelectTravelersCubit, SelectTravelersState>(
builder: (context, state) => state.savedTravelers.isEmpty
? const SizedBox.shrink()
: Container(
margin: const EdgeInsets.only(top: 34),
height: 103,
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(right: 21),
shrinkWrap: true,
itemCount: state.savedTravelers.length,
itemBuilder: (context, index) {
var isIncrement = state.isIncrementAdults;
var isDecrement = state.isDecrementAdults;
switch (state.savedTravelers[index].travelerType) {
case TravelerType.ADT:
isIncrement = state.isIncrementAdults;
isDecrement = state.isDecrementAdults;
break;
case TravelerType.CHD:
isIncrement = state.isIncrementChildren;
isDecrement = state.isDecrementChildren;
break;
case TravelerType.INF:
isIncrement = state.isIncrementInfants;
isDecrement = state.isDecrementInfants;
break;
case TravelerType.YTH:
isIncrement = state.isIncrementYouth;
isDecrement = state.isDecrementYouth;
break;
}
return _SavedTravelerItem(
traveler: state.savedTravelers[index],
isSelected: state.selectedSavedTravelers.contains(state.savedTravelers[index]),
isIncrement: isIncrement,
isDecrement: isDecrement,
);
},
),
),
),
],
),
);
}
class _SavedTravelerItem extends StatelessWidget {
const _SavedTravelerItem({
Key? key,
required this.traveler,
required this.isSelected,
required this.isIncrement,
required this.isDecrement,
}) : super(key: key);
final TravelerEntity traveler;
final bool isSelected;
final bool isIncrement;
final bool isDecrement;
@override
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.only(left: 27),
child: InkButtonWidget(
onTap: () {
if (isSelected) {
if (isDecrement) {
context.read<SelectTravelersCubit>().removeFromSelectedSavedTraveler(traveler);
}
} else {
if (isIncrement) {
context.read<SelectTravelersCubit>().addToSelectedSavedTraveler(traveler);
}
}
},
borderRadius: 10,
width: 87,
child: Column(
children: [
UserIconWidget(
isSelected: isSelected,
userInitials: traveler.initials,
),
Padding(
padding: const EdgeInsets.only(top: 7),
child: Text(
traveler.isMe
? AppLocalizations.of(context)!.me_capital_case_with_name(traveler.shortName)
: traveler.shortName,
maxLines: 1,
style: Theme.of(context).textTheme.subtitle2,
overflow: TextOverflow.ellipsis,
),
),
],
),
),
);
}
class _TravelerItem extends StatelessWidget {
const _TravelerItem({
Key? key,
required this.title,
required this.bodyText,
required this.value,
required this.travelerType,
required this.isIncrement,
required this.isDecrement,
}) : super(key: key);
final String title;
final String bodyText;
final int value;
final bool isIncrement;
final bool isDecrement;
final TravelerType travelerType;
@override
Widget build(BuildContext context) => Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style: Theme.of(context).textTheme.headline6!.copyWith(
color: dark,
fontSize: 16,
height: 20 / 18,
),
),
const SizedBox(height: 4),
Text(
bodyText,
style: Theme.of(context).textTheme.subtitle1!.copyWith(height: 18 / 14),
),
],
),
Row(
children: [
IconButton(
icon: Icon(
Icons.remove_circle,
color: !isDecrement ? grey4 : daysColor,
),
splashRadius: 20,
iconSize: 25,
onPressed:
!isDecrement ? null : () => context.read<SelectTravelersCubit>().removeTraveler(travelerType),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 17),
child: Text(
value.toString(),
style: Theme.of(context).textTheme.headline6!.copyWith(
color: dark,
fontSize: 16,
height: 20 / 16,
),
),
),
IconButton(
icon: Icon(
Icons.add_circle,
color: !isIncrement ? grey4 : daysColor,
),
splashRadius: 20,
iconSize: 25,
onPressed: !isIncrement ? null : () => context.read<SelectTravelersCubit>().addTraveler(travelerType),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
),
],
),
],
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment