import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:eatvio_app/core/utils/localization_utils.dart'; import 'package:eatvio_app/core/utils/string_extentions.dart'; import 'package:eatvio_app/core/widgets/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/custom_divider.dart'; import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/author_card.dart'; import 'package:eatvio_app/core/widgets/cpfc_container.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/expandable_text.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/core/widgets/main_background_bouble.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_portal/flutter_portal.dart'; import 'package:flutter_svg/svg.dart'; class DietPreviewScreen extends StatefulWidget { final Diet diet; late final List selectedIndexes; static const name = 'createDietScreenPreview'; static const path = '/create-diet-screen/preview'; DietPreviewScreen({ super.key, required this.diet, }) { selectedIndexes = List.generate(diet.dailySchedule.length, (_) => 0); } @override State createState() => _DietPreviewScreenState(); } class _DietPreviewScreenState extends State { final ScrollController scrollController = ScrollController(); final textEditingController = TextEditingController(); bool isMoreOptionsVisible = false; late final Uint8List imageData; @override void initState() { super.initState(); imageData = base64.decode(widget.diet.image); scrollController.addListener(() { if (isMoreOptionsVisible) { setState(() { isMoreOptionsVisible = false; }); } }); } @override Widget build(BuildContext context) { final s = S.of(context); return Scaffold( backgroundColor: appTheme.gray100, resizeToAvoidBottomInset: true, bottomSheet: Container( padding: EdgeInsets.symmetric(vertical: 12) + (Platform.isIOS ? const EdgeInsets.only(bottom: 16) : EdgeInsets.zero), decoration: BoxDecoration( color: Colors.white, border: Border( top: BorderSide( color: Colors.black.withValues(alpha: 0.1), ), ), ), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Expanded( child: SizedBox( child: FloatingActionButton.extended( heroTag: 'nextButtonRegistration', highlightElevation: 0, elevation: 0, focusElevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), backgroundColor: appTheme.greenA700, onPressed: () {}, label: Text( s.startDiet, style: TextStyles.textMSemibold.copyWith(color: appTheme.whiteA700), ), ), ), ), SizedBox(width: 8), BookmarkButton( isFavorite: widget.diet.isFavorite, onTap: () {}, width: 52, height: 52, size: 24, shape: BoxShape.circle, color: appTheme.gray50, ), ], ), SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Expanded( child: SizedBox( child: TextFormField( onChanged: (_) { setState(() {}); }, controller: textEditingController, maxLines: 5, minLines: 1, keyboardType: TextInputType.multiline, style: TextStyles.textMMedium.copyWith(color: appTheme.black), decoration: InputDecoration( isDense: true, contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), hintText: s.comment.capitalize(), hintStyle: TextStyles.textMMedium.copyWith(color: appTheme.lightGray600), filled: true, border: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide( color: Color(0xFFD1D1D6), width: 1, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide( color: Color(0xFFD1D1D6), width: 1, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(16), borderSide: BorderSide( color: Color(0xFFD1D1D6), width: 1, ), ), ), ), ), ), SizedBox(width: 8), GestureDetector( onTap: () {}, child: Container( decoration: BoxDecoration( color: textEditingController.text.length > 2 ? appTheme.blueA400 : appTheme.gray50, shape: BoxShape.circle, ), height: 32, width: 32, child: Icon( Icons.send_rounded, size: 18, color: textEditingController.text.length > 2 ? appTheme.whiteA700 : appTheme.black, ), ), ), ], ), ], ), ), ), appBar: AppBar( centerTitle: true, title: Text( widget.diet.name, maxLines: 2, textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, softWrap: true, style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), actions: [ PortalTarget( visible: isMoreOptionsVisible, portalFollower: MoreOptions( disableActions: true, path: 'diet/${widget.diet.id}', ), anchor: Aligned( shiftToWithinBound: AxisFlag(x: true, y: true), follower: Alignment.topRight, target: Alignment.bottomRight, ), child: IconButton( onPressed: () { setState(() { isMoreOptionsVisible = !isMoreOptionsVisible; }); }, icon: SvgPicture.asset( 'assets/icons/more_button.svg', width: 20, height: 20, ), ), ), ], ), body: SingleChildScrollView( controller: scrollController, padding: EdgeInsets.only(bottom: 160), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox(height: 8), MainBackgroundBouble( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ Image.memory( imageData, height: 300, width: MediaQuery.sizeOf(context).width, fit: BoxFit.fill, ), // CachedNetworkImage( // imageUrl: baseUrl + '/storage/' + widget.diet.image, // ), Positioned( bottom: 16, left: 0, right: 0, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ InfoBouble( children: [ SvgPicture.asset('assets/icons/eye.svg', width: 18, height: 12), SizedBox(width: 8), Text( widget.diet.totalViews.toString(), style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), ), ], backgroundColor: appTheme.whiteA700, ), SizedBox(width: 12), GestureDetector( onTap: () {}, child: InfoBouble( children: [ SvgPicture.asset( 'assets/icons/heart.svg', width: 14, height: 12, colorFilter: widget.diet.wasLikedByMe ? ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn) : null, ), SizedBox(width: 8), Text( widget.diet.totalLikes.toString(), style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), ), ], backgroundColor: appTheme.whiteA700, ), ), SizedBox(width: 12), InfoBouble( children: [ SvgPicture.asset('assets/icons/comment2.svg', width: 13, height: 12), SizedBox(width: 8), Text( widget.diet.totalComments.toString(), style: TextStyles.textXSSemibold.copyWith(color: appTheme.black), ), ], backgroundColor: appTheme.whiteA700, ), ], ), ), ], ), SizedBox(height: 16), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( s.about_diet, style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black), ), ), SizedBox(height: 12), InfoRow(diet: widget.diet), ExpandableText( text: widget.diet.details, ), SizedBox(height: 20), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: AuthorCard( author: widget.diet.author, title: s.diet_author, ), ), SizedBox(height: 16), ], ), ), SizedBox(height: 16), MainBackgroundBouble( child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0), child: Center( child: Text( s.diet_plan + '(${widget.diet.duration.toString()} ' + getDayForm(widget.diet.duration, s) + ')', style: TextStyles.headingXLSemibold.copyWith( color: appTheme.black, ), ), ), ), ), SizedBox(height: 8), ListView.builder( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (context, index) { return _dayOfPlan(widget.diet.dailySchedule[index], index, s); }, itemCount: widget.diet.dailySchedule.length, ), MainBackgroundBouble( padding: EdgeInsets.symmetric(vertical: 16), child: Column( children: [ Container( padding: EdgeInsets.symmetric(horizontal: 16), alignment: Alignment.centerLeft, child: Text( '0' + ' ' + getCommentForm(widget.diet.totalComments, s), style: TextStyles.textMMedium.copyWith( color: appTheme.gray500, ), ), ), SizedBox(height: 16), ], ), ), ], ), ), ); } _dayOfPlan(List> day, int dayNumber, S s) { _choiceChipWidget(int index) { return ChoiceChip( selectedColor: appTheme.blueA400, pressElevation: 0, showCheckmark: false, side: BorderSide.none, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), label: Text((index + 1).toString()), labelStyle: TextStyles.textXSSemibold.copyWith( color: index == widget.selectedIndexes[dayNumber] ? Colors.white : appTheme.gray600, ), selected: widget.selectedIndexes[dayNumber] == index, backgroundColor: appTheme.gray100, onSelected: (bool selected) { setState(() { widget.selectedIndexes[dayNumber] = index; }); }, ); } return Padding( padding: const EdgeInsets.only(bottom: 8), child: MainBackgroundBouble( padding: EdgeInsets.only( top: 16, ), child: Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( s.day + ' ' + (dayNumber + 1).toString(), style: TextStyles.headingXLSemibold.copyWith( color: appTheme.black, ), ), Padding( padding: const EdgeInsets.symmetric(vertical: 12), child: CustomDivider(), ), Text( s.meal, style: TextStyles.textMMedium.copyWith( color: appTheme.black, ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _choiceChipWidget(0), _choiceChipWidget(1), _choiceChipWidget(2), _choiceChipWidget(3), _choiceChipWidget(4), ], ), SizedBox(height: 8), ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemBuilder: (context, index) => _daily(day[widget.selectedIndexes[dayNumber]][index], s), itemCount: day[widget.selectedIndexes[dayNumber]].length, ), SizedBox(height: 8), ], ), ), CpfcContainer( calories: widget.diet.dailyNutrition[dayNumber].energy, proteins: widget.diet.dailyNutrition[dayNumber].proteins, fats: widget.diet.dailyNutrition[dayNumber].fats, carbohydrates: widget.diet.dailyNutrition[dayNumber].carbohydrates, ), ], ), ), ); } _daily(DailySchedule daily, S s) { return Padding( padding: const EdgeInsets.only(bottom: 12), child: Row( children: [ SizedBox( width: MediaQuery.sizeOf(context).width * 0.6, child: Text( daily.name, style: TextStyles.textMMedium.copyWith( color: appTheme.black, ), ), ), Spacer(), Text( daily.quantity.toString() + ' ' + getLocalizedMeasurementUnits(s, daily.portion), style: TextStyles.textMSemibold.copyWith( color: appTheme.black, ), ), ], ), ); } }