forked from eatvio/eatvio_app
1405 lines
52 KiB
Dart
1405 lines
52 KiB
Dart
import 'dart:io';
|
||
|
||
import 'package:cached_network_image/cached_network_image.dart';
|
||
import 'package:dismissible_page/dismissible_page.dart';
|
||
import 'package:eatvio_app/core/app_router.dart';
|
||
import 'package:eatvio_app/core/const.dart';
|
||
import 'package:eatvio_app/core/enums/complained_content.dart';
|
||
import 'package:eatvio_app/core/permission_handler/permission_handler.dart';
|
||
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
||
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
||
import 'package:eatvio_app/core/widgets/loader.dart';
|
||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
|
||
import 'package:eatvio_app/features/chat/presentation/pages/photo_view_screen.dart';
|
||
import 'package:eatvio_app/features/complaining/presentation/complaining_bottom_sheet.dart';
|
||
import 'package:eatvio_app/features/feed/models/diets_pagination_model.dart';
|
||
import 'package:eatvio_app/features/feed/presentation/widgets/plan_widget.dart';
|
||
import 'package:eatvio_app/features/menu/presentation/blocked_user_cubit/blocked_users_cubit.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/plans_cubit/plans_cubit.dart';
|
||
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_state.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/bloc/sub_cubit/sub_cubit.dart';
|
||
import 'package:eatvio_app/features/profile/presentation/pages/subs_screen.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/profile_blog_post_widget.dart';
|
||
import 'package:eatvio_app/features/profile/presentation/widgets/weight_chart_widget.dart';
|
||
import 'package:eatvio_app/core/locator_service.dart';
|
||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||
import 'package:eatvio_app/generated/l10n.dart';
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
import 'package:flutter_svg/flutter_svg.dart';
|
||
import 'package:image_picker/image_picker.dart';
|
||
import 'package:intl/intl.dart';
|
||
import 'package:permission_handler/permission_handler.dart';
|
||
import 'package:share_plus/share_plus.dart';
|
||
import 'package:url_launcher/url_launcher.dart';
|
||
|
||
class ProfileScreen extends StatefulWidget {
|
||
final Author? author;
|
||
|
||
const ProfileScreen({
|
||
super.key,
|
||
this.author,
|
||
});
|
||
|
||
@override
|
||
State<ProfileScreen> createState() => _ProfileScreenState();
|
||
}
|
||
|
||
class _ProfileScreenState extends State<ProfileScreen> {
|
||
late final ProfileCubit profileCubit = sl<ProfileCubit>();
|
||
final PlansCubit plansCubit = sl<PlansCubit>();
|
||
final List<String> chipsLabelList = ['Вес', 'Замеры', 'ИМТ'];
|
||
final List<String> chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ'];
|
||
final List<String> chipsIntervalList = ['1', '3', '6', '12', 'all'];
|
||
final TextEditingController controller = TextEditingController();
|
||
|
||
List<WeightModel> weightPoints = [];
|
||
List<CircumferenceModel> circumferencePoints = [];
|
||
int _selectedChipIndex = 0;
|
||
int _selectedIntervalChipIndex = 0;
|
||
late bool canSub;
|
||
bool isFirstFetch = true;
|
||
int _currentBullet = 0;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
widget.author == null || widget.author!.authorIsMe ? profileCubit.getMyProfile() : profileCubit.getProfileBySlug(widget.author!.authorSlug);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
FlutterNativeSplash.remove();
|
||
return BlocProvider<PlansCubit>(
|
||
create: (BuildContext context) => plansCubit,
|
||
child: BlocBuilder<ProfileCubit, ProfileState>(
|
||
bloc: profileCubit,
|
||
builder: (BuildContext context, ProfileState state) {
|
||
if (state is ProfileStateLoaded) {
|
||
if (state.circumferencePoints != null) {
|
||
circumferencePoints = state.circumferencePoints!;
|
||
weightPoints = state.weightPoints!;
|
||
}
|
||
if (isFirstFetch) {
|
||
canSub = !state.profile.isEntitySubscribedByMe;
|
||
if (state.profile.roles.contains('consultant')) {
|
||
plansCubit.getPlans(state.profile.slug);
|
||
}
|
||
isFirstFetch = false;
|
||
}
|
||
return widget.author == null || widget.author!.authorIsMe ? _myProfileScreen(state) : _profileScreen(state);
|
||
} else if (state is ProfileStateError) {
|
||
return Scaffold(
|
||
appBar: AppBar(),
|
||
body: DataErrorWidget(
|
||
onReload: () async {
|
||
widget.author == null || widget.author!.authorIsMe
|
||
? await profileCubit.getMyProfile()
|
||
: await profileCubit.getProfileBySlug(widget.author!.authorSlug);
|
||
},
|
||
),
|
||
);
|
||
} else {
|
||
return Scaffold(
|
||
appBar: AppBar(),
|
||
body: const Loader(),
|
||
);
|
||
}
|
||
},
|
||
),
|
||
);
|
||
}
|
||
|
||
Scaffold _profileScreen(ProfileStateLoaded state) {
|
||
return Scaffold(
|
||
backgroundColor: Colors.grey.shade200,
|
||
appBar: AppBar(),
|
||
body: SingleChildScrollView(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Container(
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.vertical(
|
||
bottom: Radius.circular(16),
|
||
),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
_header(state),
|
||
if (state.profile.roles.contains('consultant'))
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
const SizedBox(width: 16),
|
||
const Text(
|
||
'Консультант',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: Color(
|
||
0xFF323F4B,
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||
decoration: BoxDecoration(
|
||
color: const Color(0xFFF6FAFF),
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Text(
|
||
'${state.consultantInfo!.ratingPlace}-й в рейтинге',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: appTheme.blueA400,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
if (state.consultantInfo!.educationModel.hasMedicalEducation == 1)
|
||
const Row(
|
||
children: [
|
||
SizedBox(width: 16),
|
||
Icon(
|
||
Icons.done_rounded,
|
||
color: Colors.green,
|
||
),
|
||
Text(
|
||
'Медицинское образование',
|
||
style: TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
if (state.profileDetails.additionalInfo.isNotEmpty) _additionalInfo(state),
|
||
const SizedBox(height: 8),
|
||
_messageAndSubscribe(state),
|
||
const SizedBox(height: 16),
|
||
],
|
||
),
|
||
),
|
||
_subscriptionsAndSubscribers(state),
|
||
if (state.profile.badges.isNotEmpty) Padding(padding: const EdgeInsets.only(bottom: 16), child: _badges(state)),
|
||
if (state.profile.roles.contains('consultant')) _socialLinks(state),
|
||
if (state.profile.roles.contains('consultant')) _education(state),
|
||
if (state.profile.roles.contains('consultant')) _diplomasAndCertificates(state),
|
||
if (state.profile.roles.contains('consultant')) _activePlans(state),
|
||
_blogPosts(state),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Scaffold _myProfileScreen(ProfileStateLoaded state) {
|
||
return Scaffold(
|
||
backgroundColor: Colors.grey.shade200,
|
||
appBar: AppBar(toolbarHeight: 0),
|
||
body: SingleChildScrollView(
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Container(
|
||
decoration: const BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.vertical(
|
||
bottom: Radius.circular(16),
|
||
),
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.center,
|
||
children: [
|
||
_header(state),
|
||
if (state.profile.roles.contains('consultant'))
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
const SizedBox(width: 16),
|
||
const Text(
|
||
'Консультант',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: Color(
|
||
0xFF323F4B,
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||
decoration: BoxDecoration(
|
||
color: const Color(0xFFF6FAFF),
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
child: Text(
|
||
'${state.consultantInfo!.ratingPlace}-й в рейтинге',
|
||
style: TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w600,
|
||
color: appTheme.blueA400,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
if (state.consultantInfo!.educationModel.hasMedicalEducation == 1)
|
||
const Row(
|
||
children: [
|
||
SizedBox(width: 16),
|
||
Icon(
|
||
Icons.done_rounded,
|
||
color: Colors.green,
|
||
),
|
||
Text(
|
||
'Медицинское образование',
|
||
style: TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
if (state.profileDetails.additionalInfo.isNotEmpty) _additionalInfo(state),
|
||
],
|
||
),
|
||
),
|
||
_subscriptionsAndSubscribers(state),
|
||
if (state.profile.badges.isNotEmpty) Padding(padding: const EdgeInsets.only(bottom: 16), child: _badges(state)),
|
||
if (state.profile.roles.contains('consultant')) _socialLinks(state),
|
||
if (state.profile.roles.contains('consultant')) _education(state),
|
||
if (state.profile.roles.contains('consultant')) _diplomasAndCertificates(state),
|
||
Padding(padding: const EdgeInsets.only(bottom: 16), child: _charts()),
|
||
if (state.profile.roles.contains('consultant')) _activePlans(state),
|
||
_newBlogPostButton(),
|
||
_blogPosts(state),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Widget _activePlans(ProfileStateLoaded state) {
|
||
if (!state.profile.roles.contains('consultant')) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
return BlocBuilder<PlansCubit, PlansState>(
|
||
bloc: plansCubit,
|
||
builder: (BuildContext context, PlansState state) {
|
||
if (state is PlansStateLoaded) {
|
||
if (state.plansList.isEmpty) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
return Column(
|
||
children: [
|
||
const Padding(
|
||
padding: EdgeInsets.symmetric(horizontal: 16),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
Text(
|
||
'Активные планы',
|
||
style: TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 24,
|
||
height: 1,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
SizedBox(
|
||
height: 781,
|
||
child: PageView.builder(
|
||
itemBuilder: (BuildContext context, int index) {
|
||
return PlanWidget(
|
||
plan: state.plansList[index],
|
||
index: index,
|
||
);
|
||
},
|
||
onPageChanged: (bullet) {
|
||
setState(() {
|
||
_currentBullet = bullet;
|
||
});
|
||
},
|
||
itemCount: state.plansList.length,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
_bullets(_currentBullet, state.plansList.length),
|
||
const SizedBox(height: 8),
|
||
],
|
||
);
|
||
}
|
||
return const Loader();
|
||
},
|
||
);
|
||
}
|
||
|
||
Container _bullets(int currentBullet, int bulletCount) {
|
||
return Container(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(20),
|
||
),
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
for (int i = 0; i < bulletCount; i++) ...[
|
||
_bullet(i == currentBullet),
|
||
i < bulletCount - 1 ? const SizedBox(width: 4) : const SizedBox.shrink(),
|
||
],
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
AnimatedContainer _bullet(bool isActive) {
|
||
return AnimatedContainer(
|
||
width: isActive ? 10 : 8,
|
||
height: isActive ? 10 : 8,
|
||
duration: const Duration(milliseconds: 150),
|
||
decoration: BoxDecoration(
|
||
color: isActive ? appTheme.blueA400 : const Color(0xFFD7D9DC),
|
||
shape: BoxShape.circle,
|
||
),
|
||
);
|
||
}
|
||
|
||
Material _newBlogPostButton() {
|
||
return Material(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||
child: InkWell(
|
||
onTap: () {
|
||
GoRouter.of(context).pushNamed('blogPostCreateScreen');
|
||
},
|
||
borderRadius: BorderRadius.circular(8),
|
||
child: Ink(
|
||
padding: const EdgeInsets.all(12),
|
||
decoration: BoxDecoration(
|
||
color: const Color(0xFFF6FAFF),
|
||
borderRadius: BorderRadius.circular(8),
|
||
),
|
||
child: const Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Icon(
|
||
Icons.add_circle_outline_rounded,
|
||
color: Color(0xFF2F80ED),
|
||
),
|
||
SizedBox(width: 12),
|
||
Text(
|
||
'Новая запись',
|
||
style: TextStyle(
|
||
fontSize: 18,
|
||
fontWeight: FontWeight.w600,
|
||
color: Color(0xFF2F80ED),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
SingleChildRenderObjectWidget _diplomasAndCertificates(ProfileStateLoaded state) {
|
||
if (!state.profile.roles.contains('consultant') || state.consultantInfo!.photos.isEmpty) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
return Padding(
|
||
padding: const EdgeInsets.only(bottom: 16),
|
||
child: Column(
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text(
|
||
'Дипломы\nи сертификаты',
|
||
style: TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 24,
|
||
height: 1,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
GestureDetector(
|
||
onTap: () {
|
||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
|
||
},
|
||
child: Text(
|
||
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '',
|
||
style: const TextStyle(
|
||
color: Color(0xFF2F80ED),
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
Container(
|
||
width: MediaQuery.of(context).size.width - 2,
|
||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||
child: Material(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: SingleChildScrollView(
|
||
physics: const BouncingScrollPhysics(),
|
||
scrollDirection: Axis.horizontal,
|
||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
||
child: Row(
|
||
children: [
|
||
if (state.consultantInfo!.photos.isNotEmpty)
|
||
...List.generate(
|
||
state.consultantInfo!.photos.length * 2 - 1,
|
||
(index) {
|
||
if (index.isEven) {
|
||
final photo = state.consultantInfo!.photos[index ~/ 2];
|
||
return _diplomaImage(photo.url);
|
||
} else {
|
||
return const SizedBox(width: 8);
|
||
}
|
||
},
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
GestureDetector _diplomaImage(String url) {
|
||
return GestureDetector(
|
||
onTap: () {
|
||
context.pushTransparentRoute(
|
||
rootNavigator: true,
|
||
PhotoViewScreen(
|
||
imageUrls: [url],
|
||
index: 0,
|
||
),
|
||
);
|
||
},
|
||
child: Hero(
|
||
tag: url,
|
||
child: ClipRRect(
|
||
borderRadius: BorderRadius.circular(8),
|
||
child: CachedNetworkImage(
|
||
imageUrl: url,
|
||
fit: BoxFit.fitHeight,
|
||
width: MediaQuery.of(context).size.width / 3 - (60 / 3),
|
||
height: 160,
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
SingleChildRenderObjectWidget _education(ProfileStateLoaded state) {
|
||
if (!state.profile.roles.contains('consultant') ||
|
||
state.consultantInfo!.educationModel.completedCourses == null ||
|
||
(state.consultantInfo!.educationModel.completedCourses?.isEmpty ?? false)) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
return Padding(
|
||
padding: const EdgeInsets.only(bottom: 16),
|
||
child: Column(
|
||
children: [
|
||
Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
children: [
|
||
const Text(
|
||
'Образование',
|
||
style: TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 24,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
GestureDetector(
|
||
onTap: () {
|
||
GoRouter.of(context).pushNamed('stepperBecomeConsultantScreen', extra: state.profile.slug);
|
||
},
|
||
child: Text(
|
||
widget.author == null || widget.author!.authorIsMe ? 'Редактировать' : '',
|
||
style: const TextStyle(
|
||
color: Color(0xFF2F80ED),
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||
child: Material(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Column(
|
||
children: [
|
||
ListView.separated(
|
||
shrinkWrap: true,
|
||
physics: const NeverScrollableScrollPhysics(),
|
||
itemBuilder: (context, index) => _educationBlock(state.consultantInfo!.educationModel.completedCourses![index].values.first.title,
|
||
state.consultantInfo!.educationModel.completedCourses![index].values.first.date),
|
||
separatorBuilder: (context, index) => const SizedBox(height: 8),
|
||
itemCount: state.consultantInfo!.educationModel.completedCourses!.length,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
SizedBox _educationBlock(String title, String date) {
|
||
final parsedDate = DateTime.tryParse(date);
|
||
final formattedDate = parsedDate != null ? DateFormat('d MMMM y', 'ru_RU').format(parsedDate) : date;
|
||
|
||
return SizedBox(
|
||
width: double.infinity,
|
||
child: Material(
|
||
color: const Color(0xFFF6FAFF),
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(12),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: const TextStyle(
|
||
height: 1,
|
||
color: Color(0xFF323F4B),
|
||
fontWeight: FontWeight.w500,
|
||
fontSize: 16,
|
||
),
|
||
),
|
||
const SizedBox(height: 4),
|
||
Text(
|
||
formattedDate,
|
||
style: const TextStyle(
|
||
height: 1,
|
||
color: Color(0xFF6D6F71),
|
||
fontWeight: FontWeight.w500,
|
||
fontSize: 14,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
SingleChildRenderObjectWidget _socialLinks(ProfileStateLoaded state) {
|
||
if (!state.profile.roles.contains('consultant')) {
|
||
return const SizedBox.shrink();
|
||
}
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 4) + const EdgeInsets.only(bottom: 16),
|
||
child: Material(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||
child: Row(
|
||
children: [
|
||
_socialLinkButton(
|
||
() {
|
||
launchUrl(
|
||
Uri.parse(
|
||
state.consultantInfo!.educationModel.vkLink ?? '',
|
||
),
|
||
mode: LaunchMode.externalApplication,
|
||
);
|
||
},
|
||
'assets/icons/vk.svg',
|
||
state.consultantInfo!.educationModel.vkLink!.isEmpty ? true : false,
|
||
),
|
||
const SizedBox(width: 12),
|
||
_socialLinkButton(
|
||
() {
|
||
launchUrl(
|
||
Uri.parse(
|
||
state.consultantInfo!.educationModel.tgLink ?? '',
|
||
),
|
||
mode: LaunchMode.externalApplication,
|
||
);
|
||
},
|
||
'assets/icons/telegram.svg',
|
||
state.consultantInfo!.educationModel.tgLink!.isEmpty ? true : false,
|
||
),
|
||
const SizedBox(width: 12),
|
||
_socialLinkButton(
|
||
() {
|
||
launchUrl(
|
||
Uri.parse(
|
||
state.consultantInfo!.educationModel.personalSiteLink ?? '',
|
||
),
|
||
mode: LaunchMode.externalApplication,
|
||
);
|
||
},
|
||
'assets/icons/web.svg',
|
||
state.consultantInfo!.educationModel.personalSiteLink!.isEmpty ? true : false,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
InkWell _socialLinkButton(Function() onTap, String icon, bool disabled) {
|
||
return InkWell(
|
||
onTap: disabled ? null : onTap,
|
||
borderRadius: BorderRadius.circular(20),
|
||
child: Ink(
|
||
width: MediaQuery.of(context).size.width / 3 - (56 / 3),
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(20),
|
||
color: const Color(0xFFF6F6F6),
|
||
),
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 16),
|
||
child: SvgPicture.asset(
|
||
icon,
|
||
width: 24,
|
||
colorFilter: disabled ? const ColorFilter.mode(Colors.black12, BlendMode.srcIn) : const ColorFilter.mode(Colors.black, BlendMode.srcIn),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Padding _badges(ProfileStateLoaded state) {
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||
child: InkWell(
|
||
onTap: () {},
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Ink(
|
||
padding: const EdgeInsets.all(8),
|
||
width: MediaQuery.of(context).size.width,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(12),
|
||
color: Colors.white,
|
||
),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Text(
|
||
'Достижения',
|
||
style: TextStyle(
|
||
color: Color(0xFF6D6F71),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
SingleChildScrollView(
|
||
scrollDirection: Axis.horizontal,
|
||
child: Row(
|
||
children: [
|
||
for (int i = 0; i < state.profile.badges.length; i++) ...[
|
||
state.profile.badges[i].image.contains('svg')
|
||
? Tooltip(
|
||
message: state.profile.badges[i].description,
|
||
triggerMode: TooltipTriggerMode.tap,
|
||
textStyle: const TextStyle(
|
||
color: Colors.black,
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(4),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withAlpha((255 * 0.2).toInt()),
|
||
blurRadius: 32,
|
||
)
|
||
],
|
||
),
|
||
child: SvgPicture.network(
|
||
'$baseUrl/storage/${state.profile.badges[i].image}',
|
||
width: 40,
|
||
height: 40,
|
||
),
|
||
)
|
||
: Tooltip(
|
||
message: state.profile.badges[i].description,
|
||
margin: const EdgeInsets.symmetric(horizontal: 32),
|
||
triggerMode: TooltipTriggerMode.tap,
|
||
textStyle: const TextStyle(
|
||
color: Colors.black,
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
decoration: BoxDecoration(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(4),
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.black.withAlpha((255 * 0.2).toInt()),
|
||
blurRadius: 32,
|
||
)
|
||
],
|
||
),
|
||
child: CachedNetworkImage(
|
||
imageUrl: '$baseUrl/storage/${state.profile.badges[i].image}',
|
||
width: 40,
|
||
height: 40,
|
||
),
|
||
),
|
||
i < state.profile.badges.length - 1 ? const SizedBox(width: 8) : const SizedBox.shrink(),
|
||
],
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Padding _subscriptionsAndSubscribers(ProfileStateLoaded state) {
|
||
return Padding(
|
||
padding: const EdgeInsets.all(4),
|
||
child: Row(
|
||
children: [
|
||
InkWell(
|
||
onTap: () => GoRouter.of(context).pushNamed(
|
||
'subsScreen',
|
||
extra: SubType.subscriptions,
|
||
pathParameters: {
|
||
'slug': state.profile.slug,
|
||
},
|
||
),
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Ink(
|
||
padding: const EdgeInsets.all(8),
|
||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(12),
|
||
color: Colors.white,
|
||
),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
children: [
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Text(
|
||
'Подписки',
|
||
style: TextStyle(
|
||
color: Color(0xFF6D6F71),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
Text(
|
||
'${state.profile.subscriptions.length}',
|
||
style: const TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 22,
|
||
fontWeight: FontWeight.w700,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Padding(
|
||
padding: const EdgeInsets.only(right: 8),
|
||
child: _miniAvatars(state.profile.subscriptions),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 4),
|
||
InkWell(
|
||
onTap: () => GoRouter.of(context).pushNamed(
|
||
'subsScreen',
|
||
extra: SubType.subscribers,
|
||
pathParameters: {
|
||
'slug': state.profile.slug,
|
||
},
|
||
),
|
||
borderRadius: BorderRadius.circular(12),
|
||
child: Ink(
|
||
padding: const EdgeInsets.all(8),
|
||
width: MediaQuery.of(context).size.width / 2 - 6,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(12),
|
||
color: Colors.white,
|
||
),
|
||
child: Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
children: [
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const Text(
|
||
'Подписчики',
|
||
style: TextStyle(
|
||
color: Color(0xFF6D6F71),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
Text(
|
||
'${state.profile.subscribers.length}',
|
||
style: const TextStyle(
|
||
color: Color(0xFF323F4B),
|
||
fontSize: 22,
|
||
fontWeight: FontWeight.w700,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Padding(
|
||
padding: const EdgeInsets.only(right: 8),
|
||
child: _miniAvatars(state.profile.subscribers),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Row _miniAvatars(List<String> urls) {
|
||
int maxLength = urls.length > 2 ? 3 : urls.length;
|
||
return Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
for (int i = 0; i < maxLength; i++)
|
||
Align(
|
||
widthFactor: 0.8,
|
||
child: CircleAvatar(
|
||
radius: 14,
|
||
foregroundImage: NetworkImage(
|
||
urls[i],
|
||
),
|
||
backgroundImage: const AssetImage('assets/images/no_avatar.png'),
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
ListView _blogPosts(ProfileStateLoaded state) {
|
||
return ListView.separated(
|
||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||
shrinkWrap: true,
|
||
physics: const NeverScrollableScrollPhysics(),
|
||
itemBuilder: (context, index) => ProfileBlogPostWidget(
|
||
index: index,
|
||
profileCubit: profileCubit,
|
||
),
|
||
separatorBuilder: (context, index) => const SizedBox(height: 8),
|
||
itemCount: state.blogPosts.length,
|
||
);
|
||
}
|
||
|
||
Container _additionalInfo(ProfileStateLoaded state) {
|
||
String text = state.profileDetails.additionalInfo;
|
||
if (state.profileDetails.additionalInfo.length > 250) {
|
||
text = state.profileDetails.additionalInfo.substring(0, 250);
|
||
}
|
||
return Container(
|
||
alignment: Alignment.centerLeft,
|
||
padding: const EdgeInsets.all(16),
|
||
child: Text(
|
||
text,
|
||
style: TextStyle(
|
||
color: Colors.black.withValues(alpha: 0.4),
|
||
height: 1,
|
||
),
|
||
),
|
||
);
|
||
}
|
||
|
||
Padding _header(ProfileStateLoaded state) {
|
||
return Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Row(
|
||
children: [
|
||
PopupMenuButton(
|
||
onSelected: (value) async {
|
||
if (value == 'view') {
|
||
context.pushTransparentRoute(
|
||
rootNavigator: true,
|
||
PhotoViewScreen(
|
||
imageUrls: [baseUrl + state.profile.profilePhotoUrl],
|
||
index: 0,
|
||
),
|
||
);
|
||
}
|
||
if (value == 'replace') {
|
||
showCupertinoModalPopup<void>(
|
||
context: context,
|
||
builder: (context) {
|
||
final s = S.of(context);
|
||
return CupertinoActionSheet(
|
||
actions: [
|
||
CupertinoActionSheetAction(
|
||
onPressed: () async {
|
||
PermissionHandler.checkPermission(
|
||
permission: Permission.camera,
|
||
title: s.allowAccessToCamera,
|
||
description: s.allowAccessToCameraDescription,
|
||
onGranted: () async {
|
||
AppRouter.navigatorKey.currentContext?.pop();
|
||
final picker = ImagePicker();
|
||
XFile? image = await picker.pickImage(source: ImageSource.camera);
|
||
if (image != null) {
|
||
await profileCubit.uploadPhoto(File(image.path));
|
||
await sl<ProfileAvatarCubit>().getMyProfile();
|
||
}
|
||
},
|
||
context: context,
|
||
);
|
||
},
|
||
child: const Row(
|
||
children: [
|
||
Icon(Icons.photo_camera),
|
||
SizedBox(width: 8),
|
||
Text('Фото'),
|
||
],
|
||
),
|
||
),
|
||
CupertinoActionSheetAction(
|
||
onPressed: () async {
|
||
PermissionHandler.checkPermission(
|
||
permission: Permission.photos,
|
||
title: s.allowAcessToGalery,
|
||
description: s.allowAcessToGaleryDescription,
|
||
onGranted: () async {
|
||
AppRouter.navigatorKey.currentContext?.pop();
|
||
final picker = ImagePicker();
|
||
XFile? image = await picker.pickImage(source: ImageSource.gallery);
|
||
if (image != null) {
|
||
await profileCubit.uploadPhoto(File(image.path));
|
||
await sl<ProfileAvatarCubit>().getMyProfile();
|
||
}
|
||
},
|
||
context: context,
|
||
);
|
||
},
|
||
child: const Row(
|
||
children: [
|
||
Icon(Icons.photo),
|
||
SizedBox(width: 8),
|
||
Text('Галерея'),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
cancelButton: CupertinoActionSheetAction(
|
||
onPressed: () => Navigator.of(context).pop(),
|
||
isDestructiveAction: true,
|
||
child: const Text('Отмена'),
|
||
),
|
||
);
|
||
},
|
||
);
|
||
}
|
||
if (value == 'delete') {
|
||
await profileCubit.deletePhoto();
|
||
await sl<ProfileAvatarCubit>().getMyProfile();
|
||
}
|
||
},
|
||
itemBuilder: (context) => [
|
||
const PopupMenuItem(
|
||
value: 'view',
|
||
child: Text('Посмотреть'),
|
||
),
|
||
if (widget.author == null || widget.author!.authorIsMe)
|
||
const PopupMenuItem(
|
||
value: 'replace',
|
||
child: Text('Заменить'),
|
||
),
|
||
if (widget.author == null || widget.author!.authorIsMe)
|
||
const PopupMenuItem(
|
||
value: 'delete',
|
||
child: Text('Удалить'),
|
||
),
|
||
],
|
||
child: Hero(
|
||
tag: state.profile.profilePhotoUrl,
|
||
child: CircleAvatar(
|
||
radius: 32,
|
||
foregroundImage: NetworkImage(
|
||
state.profile.profilePhotoUrl.contains('https') ? state.profile.profilePhotoUrl : baseUrl + state.profile.profilePhotoUrl,
|
||
),
|
||
backgroundImage: const AssetImage('assets/images/no_avatar.png'),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 12),
|
||
Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Text(
|
||
'${state.profileDetails.firstName} ${state.profileDetails.lastName}',
|
||
style: const TextStyle(
|
||
color: Colors.black,
|
||
fontWeight: FontWeight.w600,
|
||
fontSize: 16,
|
||
height: 1,
|
||
),
|
||
),
|
||
const SizedBox(height: 8),
|
||
GestureDetector(
|
||
onTap: () {
|
||
showModalBottomSheet(
|
||
useRootNavigator: true,
|
||
showDragHandle: true,
|
||
useSafeArea: true,
|
||
context: context,
|
||
builder: (context) => Padding(
|
||
padding: const EdgeInsets.all(16),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
const Text(
|
||
'Подробнее',
|
||
style: TextStyle(
|
||
fontSize: 20,
|
||
fontWeight: FontWeight.w700,
|
||
color: Color(0xFF323F4B),
|
||
),
|
||
),
|
||
const SizedBox(height: 16),
|
||
_additional('Дата рожденя: ', state.profileDetails.birthdate),
|
||
const SizedBox(height: 12),
|
||
_additional('Страна: ', state.profileDetails.country),
|
||
const SizedBox(height: 12),
|
||
_additional('Город: ', state.profileDetails.city),
|
||
const SizedBox(height: 12),
|
||
_additional('Язык общения: ', state.profileDetails.lang),
|
||
const SizedBox(height: 12),
|
||
_additional('В Eatvio с: ', '${state.profile.createdAt?.format('d.MM.yyyy', 'ru')}'),
|
||
const SizedBox(height: 12),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
},
|
||
child: const Row(
|
||
children: [
|
||
Icon(
|
||
Icons.info_outline,
|
||
size: 20,
|
||
color: Color(0xFF6D6F71),
|
||
),
|
||
SizedBox(width: 4),
|
||
Text(
|
||
'Дополнительно',
|
||
style: TextStyle(
|
||
color: Color(0xFF6D6F71),
|
||
fontSize: 14,
|
||
fontWeight: FontWeight.w500,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const Spacer(),
|
||
PopupMenuButton(
|
||
onSelected: (value) {
|
||
if (value == 'share') {
|
||
final box = context.findRenderObject() as RenderBox?;
|
||
SharePlus.instance.share(
|
||
ShareParams(
|
||
uri: Uri.parse('$baseUrl/ru/profile/${state.profile.slug}'),
|
||
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size,
|
||
),
|
||
);
|
||
} else if (value == 'block') {
|
||
sl<BlockedUsersCubit>().blockUser(state.profile.slug);
|
||
} else {
|
||
showModalBottomSheet(
|
||
context: context,
|
||
isScrollControlled: true,
|
||
builder: (context) => ComplainingBottomSheet(
|
||
complainedContentType: ComplainedContent.profile,
|
||
slug: widget.author?.authorSlug,
|
||
),
|
||
);
|
||
}
|
||
},
|
||
itemBuilder: (context) => [
|
||
const PopupMenuItem(
|
||
value: 'share',
|
||
child: Text('Поделиться'),
|
||
),
|
||
if (widget.author != null)
|
||
const PopupMenuItem(
|
||
value: 'complain',
|
||
child: Text('Пожаловаться'),
|
||
),
|
||
if (widget.author != null)
|
||
const PopupMenuItem(
|
||
value: 'block',
|
||
child: Text('Заблокировать'),
|
||
),
|
||
],
|
||
child: const Icon(Icons.more_horiz_rounded),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
Row _additional(String title, String value) {
|
||
return Row(
|
||
children: [
|
||
Text(
|
||
title,
|
||
style: const TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
color: Color(0xFF6D6F71),
|
||
),
|
||
),
|
||
Text(
|
||
value,
|
||
style: const TextStyle(
|
||
fontSize: 16,
|
||
fontWeight: FontWeight.w500,
|
||
color: Color(0xFF323F4B),
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
Row _messageAndSubscribe(ProfileStateLoaded state) {
|
||
return Row(
|
||
children: [
|
||
const SizedBox(width: 16),
|
||
GestureDetector(
|
||
onTap: () async => await profileCubit.getChatRoomIdBySlug(author: widget.author!),
|
||
child: Container(
|
||
alignment: Alignment.center,
|
||
padding: const EdgeInsets.all(8),
|
||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||
decoration: BoxDecoration(
|
||
color: appTheme.blueA400.withValues(alpha: 0.1),
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
child: Text(
|
||
'Сообщение',
|
||
style: TextStyle(
|
||
color: appTheme.blueA400,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 8),
|
||
GestureDetector(
|
||
onTap: () {
|
||
setState(() {
|
||
canSub = !canSub;
|
||
});
|
||
canSub ? sl<SubCubit>().unsubscribe(state.profile.slug) : sl<SubCubit>().subscribe(state.profile.slug);
|
||
},
|
||
child: Container(
|
||
alignment: Alignment.center,
|
||
padding: const EdgeInsets.all(8),
|
||
width: (MediaQuery.of(context).size.width - 40) / 2,
|
||
decoration: BoxDecoration(
|
||
color: !canSub ? Colors.grey.shade200 : appTheme.blueA400,
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
child: Text(
|
||
!canSub ? 'Отписаться' : 'Подписаться',
|
||
style: TextStyle(
|
||
color: !canSub ? Colors.black : Colors.white,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
],
|
||
);
|
||
}
|
||
|
||
Material _charts() {
|
||
return Material(
|
||
color: Colors.white,
|
||
borderRadius: BorderRadius.circular(16),
|
||
child: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
const SizedBox(height: 8),
|
||
SingleChildScrollView(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||
scrollDirection: Axis.horizontal,
|
||
child: Row(
|
||
children: [
|
||
_choiceChipWidget(0),
|
||
const SizedBox(width: 8),
|
||
_choiceChipWidget(1),
|
||
const 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,
|
||
);
|
||
default:
|
||
return const SizedBox.shrink();
|
||
}
|
||
},
|
||
),
|
||
const SizedBox(height: 8),
|
||
Row(
|
||
children: [
|
||
const SizedBox(width: 16),
|
||
_choiceIntervalChipWidget(0),
|
||
const SizedBox(width: 8),
|
||
_choiceIntervalChipWidget(1),
|
||
const SizedBox(width: 8),
|
||
_choiceIntervalChipWidget(2),
|
||
const SizedBox(width: 8),
|
||
_choiceIntervalChipWidget(3),
|
||
const SizedBox(width: 8),
|
||
_choiceIntervalChipWidget(4),
|
||
],
|
||
),
|
||
const SizedBox(height: 8),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
ChoiceChip _choiceIntervalChipWidget(int index) {
|
||
return ChoiceChip(
|
||
selectedColor: Colors.grey.withValues(alpha: 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;
|
||
});
|
||
},
|
||
);
|
||
}
|
||
|
||
ChoiceChip _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;
|
||
});
|
||
},
|
||
);
|
||
}
|
||
}
|