forked from eatvio/eatvio_app
300 lines
15 KiB
Dart
300 lines
15 KiB
Dart
import 'package:eatvio_app/core/enums/complained_content.dart';
|
|
import 'package:eatvio_app/core/locator_service.dart';
|
|
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
|
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
|
import 'package:eatvio_app/core/utils/date_time_utils.dart';
|
|
import 'package:eatvio_app/core/utils/string_extentions.dart';
|
|
import 'package:eatvio_app/core/widgets/custom_text_form_field.dart';
|
|
import 'package:eatvio_app/core/widgets/data_error_widget.dart';
|
|
import 'package:eatvio_app/core/widgets/loader.dart';
|
|
import 'package:eatvio_app/features/diets/presentation/widgets/more_options.dart';
|
|
import 'package:eatvio_app/features/insights/presentation/widgets/insights_card.dart';
|
|
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_cubit.dart';
|
|
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_state.dart';
|
|
import 'package:eatvio_app/features/user_details/presentation/widgets/expandable_bouble.dart';
|
|
import 'package:eatvio_app/generated/l10n.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
import 'package:flutter_portal/flutter_portal.dart';
|
|
import 'package:flutter_svg/svg.dart';
|
|
|
|
class UserDetailsScreen extends StatelessWidget {
|
|
final String slug;
|
|
const UserDetailsScreen({super.key, required this.slug});
|
|
static const name = 'userDetailsScreen';
|
|
static const path = '/user-details-screen';
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return BlocProvider(
|
|
create: (context) => sl<UserDetailsCubit>()..getUserDetails(slug),
|
|
child: UserDetailsContent(slug: slug),
|
|
);
|
|
}
|
|
}
|
|
|
|
class UserDetailsContent extends StatefulWidget {
|
|
const UserDetailsContent({super.key, required this.slug});
|
|
final String slug;
|
|
@override
|
|
State<UserDetailsContent> createState() => _UserDetailsContentState();
|
|
}
|
|
|
|
class _UserDetailsContentState extends State<UserDetailsContent> {
|
|
bool isMoreOptionsVisible = false;
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final s = S.of(context);
|
|
return BlocBuilder<UserDetailsCubit, UserDetailsState>(
|
|
builder: (context, state) {
|
|
final profileDetails = state.profileDetails;
|
|
if (profileDetails != null && state.isLoading == false) {
|
|
return Scaffold(
|
|
backgroundColor: appTheme.gray100,
|
|
appBar: AppBar(
|
|
centerTitle: true,
|
|
title: Text(
|
|
'${s.user_data} ${profileDetails.firstName} ${profileDetails.lastName}',
|
|
maxLines: 2,
|
|
textAlign: TextAlign.center,
|
|
overflow: TextOverflow.ellipsis,
|
|
softWrap: true,
|
|
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
|
),
|
|
actions: [
|
|
PortalTarget(
|
|
visible: isMoreOptionsVisible,
|
|
portalFollower: MoreOptions(path: 'profile/${widget.slug}', complainedContentType: ComplainedContent.profile, slug: widget.slug),
|
|
anchor: const 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: SafeArea(
|
|
child: SingleChildScrollView(
|
|
controller: ScrollController()
|
|
..addListener(() {
|
|
if (isMoreOptionsVisible) {
|
|
setState(() {
|
|
isMoreOptionsVisible = false;
|
|
});
|
|
}
|
|
}),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
spacing: 12,
|
|
children: [
|
|
const SizedBox.shrink(),
|
|
InsightsCard(slug: widget.slug),
|
|
ExpandableBouble(
|
|
initiallyExpanded: true,
|
|
title: s.general_info,
|
|
children: [
|
|
Text(s.date_of_birth, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(
|
|
readOnly: true,
|
|
controller: TextEditingController(text: DateTime.parse(profileDetails.birthdate).format('dd.MM.yyyy')),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(s.sex, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.gender.parseGender())),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
ExpandableBouble(
|
|
title: s.physical_fitness,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.height, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.height.toString())),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.weight, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.weight.toStringAsFixed(0))),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.chest_circumference, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.chestCircumference.toString())),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.waist_circumference, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.waistCircumference.toString())),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.hip_circumference, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.hipCircumference.toString())),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
ExpandableBouble(
|
|
title: s.pressure,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.upper, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.bloodPressureUp.toString())),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.lower, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(
|
|
readOnly: true,
|
|
controller: TextEditingController(text: profileDetails.bloodPressureDown.toStringAsFixed(0)),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.has_hypo, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.hasHypo ? 'да' : 'нет')),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(s.has_hyper, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.hasHyper ? 'да' : 'нет')),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
ExpandableBouble(
|
|
title: s.other_info,
|
|
children: [
|
|
Text(s.has_alergy, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.aboutAlergy)),
|
|
const SizedBox(height: 16),
|
|
Text(s.takes_pills, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.aboutTakingPils)),
|
|
const SizedBox(height: 16),
|
|
Text(s.sport_hobbies, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.aboutSportHobbies)),
|
|
const SizedBox(height: 16),
|
|
Text(s.liked_groceries, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.favoriteFoods)),
|
|
const SizedBox(height: 16),
|
|
Text(s.not_liked_groceries, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
CustomTextFormField(readOnly: true, controller: TextEditingController(text: profileDetails.unfavoriteFoods)),
|
|
const SizedBox(height: 16),
|
|
Text(s.additional_information, style: TextStyles.textSMedium.copyWith(color: appTheme.black)),
|
|
const SizedBox(height: 4),
|
|
SizedBox(
|
|
height: 112,
|
|
child: CustomTextFormField(
|
|
readOnly: true,
|
|
maxLength: 1000,
|
|
maxLines: null,
|
|
minLines: null,
|
|
expands: true,
|
|
textAlignVertical: TextAlignVertical.top,
|
|
controller: TextEditingController(text: profileDetails.additionalInfo),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
} else if (state.error != null) {
|
|
return Scaffold(
|
|
appBar: AppBar(),
|
|
body: DataErrorWidget(
|
|
onReload: () async {
|
|
context.read<UserDetailsCubit>().getUserDetails(widget.slug);
|
|
},
|
|
),
|
|
);
|
|
}
|
|
return Scaffold(appBar: AppBar(), body: const Loader());
|
|
},
|
|
);
|
|
}
|
|
}
|