import 'package:cached_network_image/cached_network_image.dart'; import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/core/enums/product_type.dart'; import 'package:eatvio_app/core/widgets/bookmark_button.dart'; import 'package:eatvio_app/core/widgets/info_row.dart'; import 'package:eatvio_app/core/widgets/feed_icon_button.dart'; import 'package:eatvio_app/features/diets/presentation/widgets/info_bouble.dart'; import 'package:eatvio_app/features/feed/models/plan_pagination_model.dart'; import 'package:eatvio_app/core/theme/custom_text_style.dart'; import 'package:eatvio_app/core/theme/theme_helper.dart'; import 'package:eatvio_app/features/feed/presentation/bloc/plans_cubit/plans_cubit.dart'; import 'package:eatvio_app/generated/l10n.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_html/flutter_html.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; import 'package:share_plus/share_plus.dart'; class PlanWidget extends StatefulWidget { final PlanModel plan; final int index; const PlanWidget({ super.key, required this.plan, required this.index, }); @override State createState() => _PlanWidgetState(); } class _PlanWidgetState extends State { @override Widget build(BuildContext context) { final s = S.of(context); return InkWell( onTap: () => GoRouter.of(context).pushNamed( 'aboutPlanScreen', extra: { 'plan': widget.plan, 'index': widget.index, 'navigateToComments': false, }, ), child: Ink( decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white, ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Stack( children: [ ClipRRect( borderRadius: BorderRadius.vertical(top: Radius.circular(12)), child: CachedNetworkImage( imageUrl: baseUrl + '/storage/' + widget.plan.image, fit: BoxFit.fitWidth, width: MediaQuery.of(context).size.width, ), ), Positioned( right: 14, child: BookmarkButton( onTap: () async { if (widget.plan.isFavorite) { await context.read().removePlanFromFavorite(widget.plan.slug, widget.index); } else { await context.read().addPlanToFavorite(widget.plan.slug, widget.index); } }, color: appTheme.whiteA700, isFavorite: widget.plan.isFavorite, borderRadius: BorderRadius.vertical(bottom: Radius.circular(12)), width: 40, height: 44, size: 19, ), ), Positioned( bottom: 16, child: SizedBox( width: MediaQuery.sizeOf(context).width, child: InfoRow( plan: widget.plan, itemsBackgroundColor: appTheme.whiteA700, disableDescriptionOfTypes: true, type: ProductType.plan, ), ), ), ], ), SizedBox(height: 12), Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( widget.plan.name, style: TextStyles.textMSemibold.copyWith(color: appTheme.black), ), ), if (widget.plan.details.isNotEmpty) ...[ SizedBox( height: 12, ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Html( data: widget.plan.details.length > 200 ? widget.plan.details.substring(0, 200) + '...' : widget.plan.details, style: { "*": Style( margin: Margins.zero, color: appTheme.black, fontSize: FontSize(TextStyles.textSMedium.fontSize ?? 14), fontWeight: TextStyles.textSMedium.fontWeight ?? FontWeight.w400, ), }, ), ), ], ], ), SizedBox(height: 16), Padding( padding: const EdgeInsets.only(left: 16.0), child: ListTile( contentPadding: EdgeInsets.zero, leading: Container( width: 46, height: 46, decoration: BoxDecoration( shape: BoxShape.circle, image: DecorationImage( image: NetworkImage(widget.plan.author.authorProfileIcon), fit: BoxFit.cover, ), ), ), subtitle: Row( children: [ InfoBouble( radius: 12, backgroundColor: appTheme.gray50, padding: EdgeInsets.symmetric(vertical: 4, horizontal: 10), children: [ Text( '${widget.plan.author.authorPlaceInRating}-й в рейтинге', style: TextStyles.textXSSemibold.copyWith( color: appTheme.blueA400, ), ), ], ), Spacer(), Text( '${widget.plan.packetsCount == 1 ? widget.plan.packet1Options?.price : '${s.from} ${widget.plan.minPriceOfOptions.toStringAsFixed(0)}'}₽', style: TextStyles.headingXLSemibold.copyWith(color: appTheme.greenA700), ), SizedBox(width: 16), ], ), title: Padding( padding: const EdgeInsets.only(bottom: 4.0), child: Text( widget.plan.author.authorName, style: TextStyles.textSSemibold.copyWith( color: appTheme.black, ), ), ), ), ), SizedBox(height: 16), Padding( padding: const EdgeInsets.only( left: 16, ), child: Row( children: [ FeedIconButton( icon: widget.plan.wasLikedByMe ? Icons.favorite_rounded : Icons.favorite_border_rounded, text: widget.plan.totalLikes.toString(), iconColor: widget.plan.wasLikedByMe ? appTheme.blueA400 : null, backgroundColor: widget.plan.wasLikedByMe ? appTheme.transparentBlue : null, onTap: () async { await context.read().likePlan(widget.plan.slug, widget.index); }, ), SizedBox( width: 12, ), FeedIconButton( icon: Icons.chat_bubble_outline, text: widget.plan.totalComments.toString(), onTap: () => GoRouter.of(context).pushNamed('aboutPlanScreen', extra: {'plan': widget.plan, 'index': widget.index, 'navigateToComments': true}), ), SizedBox( width: 12, ), FeedIconButton( svgIcon: SvgPicture.asset('assets/icons/repost.svg'), onTap: () async { final box = context.findRenderObject() as RenderBox?; final result = await Share.shareUri( Uri.parse( baseUrl + '/ru/diet/' + widget.plan.id.toString(), ), sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, ); switch (result.status) { case ShareResultStatus.success: case ShareResultStatus.dismissed: case ShareResultStatus.unavailable: } }, ), Spacer(), FeedIconButton( svgIcon: SvgPicture.asset('assets/icons/eye2.svg'), text: widget.plan.totalViews.toString(), backgroundColor: Colors.transparent, ), ], ), ), SizedBox(height: 12), ], ), ), ); } }