import 'package:eatvio_app/core/const.dart'; import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart'; import 'package:eatvio_app/features/feed/presentation/widgets/blog_post_widget.dart'; import 'package:eatvio_app/features/profile/models/circumference_model.dart'; import 'package:eatvio_app/features/profile/models/weight_model.dart'; import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_cubit.dart'; import 'package:eatvio_app/features/profile/presentation/bloc/profile_cubit/profile_state.dart'; import 'package:eatvio_app/features/profile/presentation/widgets/circumference_chart_widget.dart'; import 'package:eatvio_app/features/profile/presentation/widgets/imt_chart_widget.dart'; import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart'; import 'package:eatvio_app/locator_service.dart'; import 'package:eatvio_app/theme/theme_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; import 'package:rive/rive.dart'; import 'package:share_plus/share_plus.dart'; class ProfileScreen extends StatefulWidget { final Author? author; const ProfileScreen({super.key, this.author}); @override State createState() => _ProfileScreenState(); } class _ProfileScreenState extends State { List circumferencePoints = []; List weightPoints = []; final List chipsLabelList = ['Вес', 'Замеры', 'ИМТ']; final List chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ']; final List chipsIntervalList = ['1', '3', '6', '12', 'all']; int _selectedChipIndex = 0; int _selectedIntervalChipIndex = 0; final ProfileCubit profileCubit = sl(); @override void initState() { super.initState(); widget.author == null ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.author!.authorSlug); } @override Widget build(BuildContext context) { return BlocBuilder( bloc: profileCubit, builder: (BuildContext context, ProfileState state) { if (state is ProfileStateLoaded) { if (state.circumferencePoints != null) { circumferencePoints = state.circumferencePoints!; weightPoints = state.weightPoints!; } return Scaffold( backgroundColor: Colors.grey.shade200, appBar: widget.author == null ? AppBar(toolbarHeight: 0) : AppBar(), body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.vertical( bottom: Radius.circular(16), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: const EdgeInsets.all(16), child: Row( children: [ CircleAvatar( radius: 32, backgroundImage: NetworkImage(state.profile.profilePhotoUrl), ), const SizedBox(width: 12), Text( state.profile.name, style: TextStyle( color: Colors.black, fontWeight: FontWeight.w500, height: 1, ), ), const Spacer(), Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( child: SvgPicture.asset( height: 28, width: 28, 'assets/icons/subscribers.svg', colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn), ), ), SizedBox(width: 8), Column( children: [ Text( '123', style: TextStyle( height: 1, fontSize: 18, fontWeight: FontWeight.w500, color: Colors.black87, ), ), Text( 'Подписчика', style: TextStyle( height: 1, fontSize: 12, fontWeight: FontWeight.w400, color: Colors.black38, ), ), ], ), ], ), GestureDetector( onTap: () => Share.shareUri( Uri.parse( baseUrl + '/ru/profile/' + state.profile.slug, ), ), child: Container( padding: EdgeInsets.only(left: 16), child: SvgPicture.asset( height: 24, width: 24, 'assets/icons/share.svg', colorFilter: ColorFilter.mode(appTheme.blueA400, BlendMode.srcIn), ), ), ), ], ), ), if (state.profileDetails.additionalInfo.isNotEmpty) Container( alignment: Alignment.centerLeft, padding: const EdgeInsets.all(16), child: Text( state.profileDetails.additionalInfo, style: TextStyle( color: Colors.black.withOpacity(0.4), height: 1, ), ), ), if (widget.author != null) const SizedBox(height: 8), if (widget.author != null) Row( children: [ SizedBox(width: 16), GestureDetector( onTap: () => GoRouter.of(context).pushNamed( 'chatScreen', ), child: Container( alignment: Alignment.center, padding: EdgeInsets.all(8), width: (MediaQuery.of(context).size.width - 40) / 2, decoration: BoxDecoration( color: appTheme.blueA400.withOpacity(0.1), borderRadius: BorderRadius.circular(16), ), child: Text( 'Сообщение', style: TextStyle( color: appTheme.blueA400, ), ), ), ), SizedBox(width: 8), Container( alignment: Alignment.center, padding: EdgeInsets.all(8), width: (MediaQuery.of(context).size.width - 40) / 2, decoration: BoxDecoration( color: appTheme.blueA400, borderRadius: BorderRadius.circular(16), ), child: Text( 'Подписаться', style: TextStyle( color: Colors.white, ), ), ), SizedBox(width: 16), ], ), if (widget.author != null) SizedBox(height: 16), if (widget.author == null) _divider(context), if (widget.author == null) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 8), SingleChildScrollView( padding: EdgeInsets.symmetric(horizontal: 16), scrollDirection: Axis.horizontal, child: Row( children: [ _choiceChipWidget(0), SizedBox(width: 8), _choiceChipWidget(1), SizedBox(width: 8), _choiceChipWidget(2), ], ), ), Builder( builder: (context) { switch (_selectedChipIndex) { case 0: return WeightChartWidget( weightPoints: weightPoints, profileCubit: profileCubit, ); case 1: return CircumferenceChartWidget( circumferencePoints: circumferencePoints, profileCubit: profileCubit, ); case 2: return ImtChartWidget( weightPoints: weightPoints, ); } return SizedBox.shrink(); }, ), SizedBox(height: 8), Row( children: [ SizedBox(width: 16), _choiceIntervalChipWidget(0), SizedBox(width: 8), _choiceIntervalChipWidget(1), SizedBox(width: 8), _choiceIntervalChipWidget(2), SizedBox(width: 8), _choiceIntervalChipWidget(3), SizedBox(width: 8), _choiceIntervalChipWidget(4), ], ), SizedBox(height: 8), ], ), ], ), ), SizedBox(height: 16), ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) => BlogPostWidget(feedBlogPostModel: state.blogPosts[index]), separatorBuilder: (context, index) => SizedBox(height: 8), itemCount: state.blogPosts.length, ), SizedBox(height: 16), ], ), ), ); } else if (state is ProfileStateError) { return Scaffold( appBar: AppBar(), body: Center( child: Padding( padding: const EdgeInsets.all(16), child: Text(state.errorMessage), ), ), ); } else { return Scaffold( appBar: AppBar(), body: Center( child: SizedBox( height: 32, width: 32, child: RiveAnimation.asset( 'assets/rive_animations/loading.riv', ), ), ), ); } }, ); } _divider(BuildContext context) { return Container( height: 0.4, width: MediaQuery.of(context).size.width - 32, decoration: BoxDecoration( color: Colors.black26, borderRadius: BorderRadius.circular(16), ), ); } _choiceIntervalChipWidget(int index) { return ChoiceChip( selectedColor: Colors.grey.withOpacity(0.1), pressElevation: 0, showCheckmark: false, side: BorderSide.none, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), label: Text(chipsIntervalLabelList[index]), labelStyle: TextStyle( color: appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12, ), selected: _selectedIntervalChipIndex == index, onSelected: (bool selected) { profileCubit.getMyProfile(period: chipsIntervalList[index]); setState(() { _selectedIntervalChipIndex = index; }); }, ); } _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: 8, vertical: 4), label: Text(chipsLabelList[index]), labelStyle: TextStyle( color: index == _selectedChipIndex ? Colors.white : appTheme.gray600, fontWeight: FontWeight.w500, fontSize: 12, ), selected: _selectedChipIndex == index, backgroundColor: appTheme.gray100, onSelected: (bool selected) { setState(() { _selectedChipIndex = index; }); }, ); } }