forked from eatvio/eatvio_app
user details created
This commit is contained in:
@@ -41,6 +41,7 @@ import 'package:eatvio_app/features/settings/presentation/pages/physical_activit
|
||||
import 'package:eatvio_app/features/settings/presentation/pages/physical_form_screen.dart';
|
||||
import 'package:eatvio_app/features/settings/presentation/pages/pressure_screen.dart';
|
||||
import 'package:eatvio_app/features/settings/presentation/pages/settings_screen.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/user_details_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
@@ -294,6 +295,13 @@ class AppRouter {
|
||||
name: MyPlansScreen.name,
|
||||
builder: (context, state) => MyPlansScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: UserDetailsScreen.path,
|
||||
name: UserDetailsScreen.name,
|
||||
builder: (context, state) => UserDetailsScreen(
|
||||
slug: state.extra as String,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import 'package:eatvio_app/features/registration/services/registration_service.d
|
||||
import 'package:eatvio_app/features/settings/presentation/bloc/settings_cubit/settings_cubit.dart';
|
||||
import 'package:eatvio_app/features/settings/repositories/service_repository.dart';
|
||||
import 'package:eatvio_app/features/settings/services/settings_service.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_cubit.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:eatvio_app/features/profile/presentation/bloc/plans_cubit/plans_cubit.dart' as profilePlans;
|
||||
|
||||
@@ -98,6 +99,7 @@ Future<void> init() async {
|
||||
sl.registerFactory<CreateRecipeCubit>(() => CreateRecipeCubit());
|
||||
sl.registerFactory<MyDietsCubit>(() => MyDietsCubit(myDietsRepository: sl()));
|
||||
sl.registerFactory<MyPlansCubit>(() => MyPlansCubit(myPlansRepository: sl()));
|
||||
sl.registerFactory<UserDetailsCubit>(() => UserDetailsCubit(profileRepository: sl()));
|
||||
|
||||
// Repository
|
||||
sl.registerLazySingleton<ChatRepository>(() => ChatRepository(chatService: sl()));
|
||||
|
||||
@@ -2,4 +2,13 @@ extension Capitalization on String {
|
||||
String capitalize() {
|
||||
return "${this[0].toUpperCase()}${substring(1).toLowerCase()}";
|
||||
}
|
||||
}
|
||||
|
||||
String parseGender() {
|
||||
if (this == 'male') {
|
||||
return 'Мужской';
|
||||
} else if (this == 'female') {
|
||||
return 'Женский';
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,20 +80,20 @@ class CustomTextFormField extends StatelessWidget {
|
||||
final TextAlignVertical? textAlignVertical;
|
||||
final bool hasError;
|
||||
final bool enabled;
|
||||
|
||||
// final TextAlign
|
||||
final bool readOnly;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Align(
|
||||
alignment: alignment ?? Alignment.center,
|
||||
child: TextFormField(
|
||||
child: TextFormField(
|
||||
enabled: enabled,
|
||||
readOnly: readOnly,
|
||||
textAlignVertical: textAlignVertical,
|
||||
expands: expands,
|
||||
minLines: minLines,
|
||||
maxLength: maxLength,
|
||||
onChanged: onChanged,
|
||||
onChanged: onChanged,
|
||||
controller: controller,
|
||||
focusNode: focusNode ?? null,
|
||||
autofocus: autofocus,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_cubit.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/new_messages_cubit/new_messages_state.dart';
|
||||
@@ -6,6 +7,8 @@ import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/noti
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/notifications_cubit/notifications_state.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_cubit.dart';
|
||||
import 'package:eatvio_app/features/bottom_navigation_bar/presentation/bloc/profile_avatar_cubit/profile_avatar_state.dart';
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/user_details_screen.dart';
|
||||
import 'package:eatvio_app/generated/l10n.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -28,7 +31,7 @@ class BottomNavigationBarWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
void _onItemTapped(int index) {
|
||||
void _onItemTapped(int index) async {
|
||||
if (currentBottomNavBarIndex != index) {
|
||||
setState(() {
|
||||
currentBottomNavBarIndex = index;
|
||||
|
||||
@@ -12,9 +12,12 @@ class ChatSelectCubit extends Cubit<ChatSelectState> {
|
||||
getChatRooms({String? query}) async {
|
||||
emit(ChatSelectState.loading());
|
||||
try {
|
||||
emit(ChatSelectState.loaded(
|
||||
chatRooms: (await chatRepository.getChatRoomPreviews(query: query)),
|
||||
),);
|
||||
final chatRooms = await chatRepository.getChatRoomPreviews(query: query);
|
||||
emit(
|
||||
ChatSelectState.loaded(
|
||||
chatRooms: chatRooms,
|
||||
),
|
||||
);
|
||||
} catch (e) {
|
||||
emit(
|
||||
ChatSelectState.error(errorMessage: e.toString()),
|
||||
|
||||
@@ -190,7 +190,10 @@ class _DietPreviewScreenState extends State<DietPreviewScreen> {
|
||||
actions: [
|
||||
PortalTarget(
|
||||
visible: isMoreOptionsVisible,
|
||||
portalFollower: MoreOptions(disableActions: true, id: widget.diet.id),
|
||||
portalFollower: MoreOptions(
|
||||
disableActions: true,
|
||||
path: 'diet/${widget.diet.id}',
|
||||
),
|
||||
anchor: Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
|
||||
@@ -151,7 +151,7 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
|
||||
BookmarkButton(
|
||||
isFavorite: dietState.diet.isFavorite,
|
||||
onTap: () {
|
||||
if (dietState.diet.isFavorite) {
|
||||
if (dietState.diet.isFavorite) {
|
||||
dietsCubit.removeFromFavorite(widget.diet.id, widget.index);
|
||||
} else {
|
||||
dietsCubit.addToFavorite(widget.diet.id, widget.index);
|
||||
@@ -291,7 +291,9 @@ class _AboutDietScreenState extends State<AboutDietScreen> {
|
||||
actions: [
|
||||
PortalTarget(
|
||||
visible: isMoreOptionsVisible,
|
||||
portalFollower: MoreOptions(id: widget.diet.id),
|
||||
portalFollower: MoreOptions(
|
||||
path: 'diet/${widget.diet.id}',
|
||||
),
|
||||
anchor: Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
|
||||
@@ -12,8 +12,8 @@ import 'package:go_router/go_router.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
class MoreOptions extends StatelessWidget {
|
||||
const MoreOptions({super.key, required this.id, this.disableActions});
|
||||
final int id;
|
||||
const MoreOptions({super.key, this.disableActions, required this.path});
|
||||
final String path;
|
||||
final bool? disableActions;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -26,10 +26,12 @@ class MoreOptions extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap:disableActions == true ? null : () {
|
||||
Clipboard.setData(ClipboardData(text: baseUrl + '/ru/diet/' + id.toString()));
|
||||
showInfoToast(s.link_was_copied);
|
||||
},
|
||||
onTap: disableActions == true
|
||||
? null
|
||||
: () {
|
||||
Clipboard.setData(ClipboardData(text: '$baseUrl/ru/$path'));
|
||||
showInfoToast(s.link_was_copied);
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
@@ -48,11 +50,13 @@ class MoreOptions extends StatelessWidget {
|
||||
child: CustomDivider(),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: disableActions == true ? null : () => Share.shareUri(
|
||||
Uri.parse(
|
||||
baseUrl + '/ru/diet/' + id.toString(),
|
||||
),
|
||||
),
|
||||
onTap: disableActions == true
|
||||
? null
|
||||
: () => Share.shareUri(
|
||||
Uri.parse(
|
||||
'$baseUrl/ru/$path',
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
@@ -71,9 +75,11 @@ class MoreOptions extends StatelessWidget {
|
||||
child: CustomDivider(),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: disableActions == true ? null : () {
|
||||
context.push('complainingScreen');
|
||||
},
|
||||
onTap: disableActions == true
|
||||
? null
|
||||
: () {
|
||||
context.push('complainingScreen');
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
|
||||
@@ -292,7 +292,9 @@ class _AboutPlanScreenState extends State<AboutPlanScreen> {
|
||||
actions: [
|
||||
PortalTarget(
|
||||
visible: isMoreOptionsVisible,
|
||||
portalFollower: MoreOptions(id: widget.plan.id),
|
||||
portalFollower: MoreOptions(
|
||||
path: 'plan/${widget.plan.id}',
|
||||
),
|
||||
anchor: Aligned(
|
||||
shiftToWithinBound: AxisFlag(x: true, y: true),
|
||||
follower: Alignment.topRight,
|
||||
|
||||
@@ -276,7 +276,10 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
height: 378,
|
||||
child: PageView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return PlanWidget(plan: state.plansList[index], index: index,);
|
||||
return PlanWidget(
|
||||
plan: state.plansList[index],
|
||||
index: index,
|
||||
);
|
||||
},
|
||||
onPageChanged: (bullet) {
|
||||
setState(() {
|
||||
@@ -1097,7 +1100,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
_charts() {
|
||||
_charts() {
|
||||
return Material(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
|
||||
@@ -8,12 +8,12 @@ import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
|
||||
class CircumferenceChartWidget extends StatefulWidget {
|
||||
final List<CircumferenceModel> circumferencePoints;
|
||||
final ProfileCubit profileCubit;
|
||||
final ProfileCubit? profileCubit;
|
||||
|
||||
const CircumferenceChartWidget({
|
||||
super.key,
|
||||
required this.circumferencePoints,
|
||||
required this.profileCubit,
|
||||
this.profileCubit,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -171,117 +171,118 @@ class _CircumferenceChartWidgetState extends State<CircumferenceChartWidget> {
|
||||
series: _getSplineSeries(),
|
||||
tooltipBehavior: TooltipBehavior(enable: true),
|
||||
),
|
||||
FloatingActionButton.small(
|
||||
heroTag: 'addCircumference',
|
||||
onPressed: () {
|
||||
if (widget.circumferencePoints.isNotEmpty) {
|
||||
chest = widget.circumferencePoints.last.chestCircumference;
|
||||
waist = widget.circumferencePoints.last.waistCircumference;
|
||||
hip = widget.circumferencePoints.last.hipCircumference;
|
||||
chestController = FixedExtentScrollController(initialItem: chest - 20);
|
||||
waistController = FixedExtentScrollController(initialItem: waist - 20);
|
||||
hipController = FixedExtentScrollController(initialItem: hip - 20);
|
||||
} else {
|
||||
chestController = FixedExtentScrollController();
|
||||
waistController = FixedExtentScrollController();
|
||||
hipController = FixedExtentScrollController();
|
||||
}
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: chestController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
chest = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
if (widget.profileCubit != null)
|
||||
FloatingActionButton.small(
|
||||
heroTag: 'addCircumference',
|
||||
onPressed: () {
|
||||
if (widget.circumferencePoints.isNotEmpty) {
|
||||
chest = widget.circumferencePoints.last.chestCircumference;
|
||||
waist = widget.circumferencePoints.last.waistCircumference;
|
||||
hip = widget.circumferencePoints.last.hipCircumference;
|
||||
chestController = FixedExtentScrollController(initialItem: chest - 20);
|
||||
waistController = FixedExtentScrollController(initialItem: waist - 20);
|
||||
hipController = FixedExtentScrollController(initialItem: hip - 20);
|
||||
} else {
|
||||
chestController = FixedExtentScrollController();
|
||||
waistController = FixedExtentScrollController();
|
||||
hipController = FixedExtentScrollController();
|
||||
}
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: chestController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
chest = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: waistController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
waist = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: waistController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
waist = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: hipController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
hip = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: hipController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
hip = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 200; i++) Text('$i'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
widget.profileCubit.addCircumference(
|
||||
chestCircumference: chest + 20,
|
||||
waistCircumference: waist + 20,
|
||||
hipCircumference: hip + 20,
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
widget.profileCubit?.addCircumference(
|
||||
chestCircumference: chest + 20,
|
||||
waistCircumference: waist + 20,
|
||||
hipCircumference: hip + 20,
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -8,12 +8,12 @@ import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
|
||||
class WeightChartWidget extends StatefulWidget {
|
||||
final List<WeightModel> weightPoints;
|
||||
final ProfileCubit profileCubit;
|
||||
final ProfileCubit? profileCubit;
|
||||
|
||||
const WeightChartWidget({
|
||||
super.key,
|
||||
required this.weightPoints,
|
||||
required this.profileCubit,
|
||||
this.profileCubit,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -111,99 +111,100 @@ class _WeightChartWidgetState extends State<WeightChartWidget> {
|
||||
series: _getSplineSeries(),
|
||||
tooltipBehavior: TooltipBehavior(enable: true),
|
||||
),
|
||||
FloatingActionButton.small(
|
||||
heroTag: 'addWeight',
|
||||
onPressed: () {
|
||||
if (widget.weightPoints.isNotEmpty) {
|
||||
try {
|
||||
weightKilo = int.parse(widget.weightPoints.last.weight.toString().split('.')[0]);
|
||||
weightGrams = int.parse(widget.weightPoints.last.weight.toString().split('.')[1][0]);
|
||||
} catch (e) {
|
||||
weightGrams = 0;
|
||||
if (widget.profileCubit != null)
|
||||
FloatingActionButton.small(
|
||||
heroTag: 'addWeight',
|
||||
onPressed: () {
|
||||
if (widget.weightPoints.isNotEmpty) {
|
||||
try {
|
||||
weightKilo = int.parse(widget.weightPoints.last.weight.toString().split('.')[0]);
|
||||
weightGrams = int.parse(widget.weightPoints.last.weight.toString().split('.')[1][0]);
|
||||
} catch (e) {
|
||||
weightGrams = 0;
|
||||
}
|
||||
weightKiloController = FixedExtentScrollController(initialItem: weightKilo - 20);
|
||||
weightGramsController = FixedExtentScrollController(initialItem: weightGrams);
|
||||
} else {
|
||||
weightKiloController = FixedExtentScrollController();
|
||||
weightGramsController = FixedExtentScrollController();
|
||||
}
|
||||
weightKiloController = FixedExtentScrollController(initialItem: weightKilo - 20);
|
||||
weightGramsController = FixedExtentScrollController(initialItem: weightGrams);
|
||||
} else {
|
||||
weightKiloController = FixedExtentScrollController();
|
||||
weightGramsController = FixedExtentScrollController();
|
||||
}
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: weightKiloController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
weightKilo = value + 20;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 300; i++) Text('$i'),
|
||||
],
|
||||
showModalBottomSheet(
|
||||
useRootNavigator: true,
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: weightKiloController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
weightKilo = value + 20;
|
||||
},
|
||||
children: [
|
||||
for (int i = 20; i < 300; i++) Text('$i'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: weightGramsController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
weightGrams = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 0; i < 10; i++) Text('$i'),
|
||||
],
|
||||
Expanded(
|
||||
child: CupertinoPicker(
|
||||
magnification: 1.22,
|
||||
squeeze: 1.2,
|
||||
useMagnifier: true,
|
||||
scrollController: weightGramsController,
|
||||
itemExtent: 24,
|
||||
onSelectedItemChanged: (int value) {
|
||||
weightGrams = value;
|
||||
},
|
||||
children: [
|
||||
for (int i = 0; i < 10; i++) Text('$i'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
widget.profileCubit.addWeight(weight: double.parse('$weightKilo.$weightGrams'));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
widget.profileCubit?.addWeight(weight: double.parse('$weightKilo.$weightGrams'));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: Ink(
|
||||
width: MediaQuery.of(context).size.width - 32,
|
||||
padding: EdgeInsets.all(16),
|
||||
decoration: BoxDecoration(
|
||||
color: appTheme.blueA400,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
'Сохранить',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
backgroundColor: appTheme.blueA400,
|
||||
shape: CircleBorder(),
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:eatvio_app/features/profile/repositories/profile_repository.dart';
|
||||
import 'package:eatvio_app/features/user_details/presentation/cubit/user_details_state.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class UserDetailsCubit extends Cubit<UserDetailsState> {
|
||||
final ProfileRepository profileRepository;
|
||||
|
||||
UserDetailsCubit({required this.profileRepository}) : super(UserDetailsState());
|
||||
|
||||
void getUserDetails(String slug) async {
|
||||
try {
|
||||
final profileDetails = await profileRepository.getProfileDetailsBySlug(slug);
|
||||
emit(state.copyWith(profileDetails: profileDetails, isLoading: false));
|
||||
getChartData(slug: slug);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
}
|
||||
|
||||
void getChartData({
|
||||
String period = '1',
|
||||
required String slug,
|
||||
}) async {
|
||||
try {
|
||||
final weightPoints = await profileRepository.getWeight(period: period);
|
||||
final circumferencePoints = await profileRepository.getCircumferences(period: period);
|
||||
emit(
|
||||
state.copyWith(
|
||||
weightPoints: weightPoints,
|
||||
circumferencePoints: circumferencePoints,
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
log(e.toString(), stackTrace: stackTrace);
|
||||
emit(state.copyWith(error: e.toString(), isLoading: false));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:eatvio_app/features/profile/models/circumference_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
import 'package:eatvio_app/features/profile/models/weight_model.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'user_details_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class UserDetailsState with _$UserDetailsState {
|
||||
factory UserDetailsState({
|
||||
@Default(false) bool isLoading,
|
||||
String? error,
|
||||
ProfileDetailsModel? profileDetails,
|
||||
List<WeightModel>? weightPoints,
|
||||
List<CircumferenceModel>? circumferencePoints,
|
||||
}) = _UserDetailsState;
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
// coverage:ignore-file
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||
|
||||
part of 'user_details_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
|
||||
final _privateConstructorUsedError = UnsupportedError(
|
||||
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$UserDetailsState {
|
||||
bool get isLoading => throw _privateConstructorUsedError;
|
||||
String? get error => throw _privateConstructorUsedError;
|
||||
ProfileDetailsModel? get profileDetails => throw _privateConstructorUsedError;
|
||||
List<WeightModel>? get weightPoints => throw _privateConstructorUsedError;
|
||||
List<CircumferenceModel>? get circumferencePoints =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
$UserDetailsStateCopyWith<UserDetailsState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $UserDetailsStateCopyWith<$Res> {
|
||||
factory $UserDetailsStateCopyWith(
|
||||
UserDetailsState value, $Res Function(UserDetailsState) then) =
|
||||
_$UserDetailsStateCopyWithImpl<$Res, UserDetailsState>;
|
||||
@useResult
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
String? error,
|
||||
ProfileDetailsModel? profileDetails,
|
||||
List<WeightModel>? weightPoints,
|
||||
List<CircumferenceModel>? circumferencePoints});
|
||||
|
||||
$ProfileDetailsModelCopyWith<$Res>? get profileDetails;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$UserDetailsStateCopyWithImpl<$Res, $Val extends UserDetailsState>
|
||||
implements $UserDetailsStateCopyWith<$Res> {
|
||||
_$UserDetailsStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function($Val) _then;
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? error = freezed,
|
||||
Object? profileDetails = freezed,
|
||||
Object? weightPoints = freezed,
|
||||
Object? circumferencePoints = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error: freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
profileDetails: freezed == profileDetails
|
||||
? _value.profileDetails
|
||||
: profileDetails // ignore: cast_nullable_to_non_nullable
|
||||
as ProfileDetailsModel?,
|
||||
weightPoints: freezed == weightPoints
|
||||
? _value.weightPoints
|
||||
: weightPoints // ignore: cast_nullable_to_non_nullable
|
||||
as List<WeightModel>?,
|
||||
circumferencePoints: freezed == circumferencePoints
|
||||
? _value.circumferencePoints
|
||||
: circumferencePoints // ignore: cast_nullable_to_non_nullable
|
||||
as List<CircumferenceModel>?,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$ProfileDetailsModelCopyWith<$Res>? get profileDetails {
|
||||
if (_value.profileDetails == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $ProfileDetailsModelCopyWith<$Res>(_value.profileDetails!, (value) {
|
||||
return _then(_value.copyWith(profileDetails: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$UserDetailsStateImplCopyWith<$Res>
|
||||
implements $UserDetailsStateCopyWith<$Res> {
|
||||
factory _$$UserDetailsStateImplCopyWith(_$UserDetailsStateImpl value,
|
||||
$Res Function(_$UserDetailsStateImpl) then) =
|
||||
__$$UserDetailsStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call(
|
||||
{bool isLoading,
|
||||
String? error,
|
||||
ProfileDetailsModel? profileDetails,
|
||||
List<WeightModel>? weightPoints,
|
||||
List<CircumferenceModel>? circumferencePoints});
|
||||
|
||||
@override
|
||||
$ProfileDetailsModelCopyWith<$Res>? get profileDetails;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$UserDetailsStateImplCopyWithImpl<$Res>
|
||||
extends _$UserDetailsStateCopyWithImpl<$Res, _$UserDetailsStateImpl>
|
||||
implements _$$UserDetailsStateImplCopyWith<$Res> {
|
||||
__$$UserDetailsStateImplCopyWithImpl(_$UserDetailsStateImpl _value,
|
||||
$Res Function(_$UserDetailsStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? error = freezed,
|
||||
Object? profileDetails = freezed,
|
||||
Object? weightPoints = freezed,
|
||||
Object? circumferencePoints = freezed,
|
||||
}) {
|
||||
return _then(_$UserDetailsStateImpl(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
error: freezed == error
|
||||
? _value.error
|
||||
: error // ignore: cast_nullable_to_non_nullable
|
||||
as String?,
|
||||
profileDetails: freezed == profileDetails
|
||||
? _value.profileDetails
|
||||
: profileDetails // ignore: cast_nullable_to_non_nullable
|
||||
as ProfileDetailsModel?,
|
||||
weightPoints: freezed == weightPoints
|
||||
? _value._weightPoints
|
||||
: weightPoints // ignore: cast_nullable_to_non_nullable
|
||||
as List<WeightModel>?,
|
||||
circumferencePoints: freezed == circumferencePoints
|
||||
? _value._circumferencePoints
|
||||
: circumferencePoints // ignore: cast_nullable_to_non_nullable
|
||||
as List<CircumferenceModel>?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$UserDetailsStateImpl implements _UserDetailsState {
|
||||
_$UserDetailsStateImpl(
|
||||
{this.isLoading = false,
|
||||
this.error,
|
||||
this.profileDetails,
|
||||
final List<WeightModel>? weightPoints,
|
||||
final List<CircumferenceModel>? circumferencePoints})
|
||||
: _weightPoints = weightPoints,
|
||||
_circumferencePoints = circumferencePoints;
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isLoading;
|
||||
@override
|
||||
final String? error;
|
||||
@override
|
||||
final ProfileDetailsModel? profileDetails;
|
||||
final List<WeightModel>? _weightPoints;
|
||||
@override
|
||||
List<WeightModel>? get weightPoints {
|
||||
final value = _weightPoints;
|
||||
if (value == null) return null;
|
||||
if (_weightPoints is EqualUnmodifiableListView) return _weightPoints;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
final List<CircumferenceModel>? _circumferencePoints;
|
||||
@override
|
||||
List<CircumferenceModel>? get circumferencePoints {
|
||||
final value = _circumferencePoints;
|
||||
if (value == null) return null;
|
||||
if (_circumferencePoints is EqualUnmodifiableListView)
|
||||
return _circumferencePoints;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(value);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'UserDetailsState(isLoading: $isLoading, error: $error, profileDetails: $profileDetails, weightPoints: $weightPoints, circumferencePoints: $circumferencePoints)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$UserDetailsStateImpl &&
|
||||
(identical(other.isLoading, isLoading) ||
|
||||
other.isLoading == isLoading) &&
|
||||
(identical(other.error, error) || other.error == error) &&
|
||||
(identical(other.profileDetails, profileDetails) ||
|
||||
other.profileDetails == profileDetails) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._weightPoints, _weightPoints) &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._circumferencePoints, _circumferencePoints));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType,
|
||||
isLoading,
|
||||
error,
|
||||
profileDetails,
|
||||
const DeepCollectionEquality().hash(_weightPoints),
|
||||
const DeepCollectionEquality().hash(_circumferencePoints));
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$UserDetailsStateImplCopyWith<_$UserDetailsStateImpl> get copyWith =>
|
||||
__$$UserDetailsStateImplCopyWithImpl<_$UserDetailsStateImpl>(
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _UserDetailsState implements UserDetailsState {
|
||||
factory _UserDetailsState(
|
||||
{final bool isLoading,
|
||||
final String? error,
|
||||
final ProfileDetailsModel? profileDetails,
|
||||
final List<WeightModel>? weightPoints,
|
||||
final List<CircumferenceModel>? circumferencePoints}) =
|
||||
_$UserDetailsStateImpl;
|
||||
|
||||
@override
|
||||
bool get isLoading;
|
||||
@override
|
||||
String? get error;
|
||||
@override
|
||||
ProfileDetailsModel? get profileDetails;
|
||||
@override
|
||||
List<WeightModel>? get weightPoints;
|
||||
@override
|
||||
List<CircumferenceModel>? get circumferencePoints;
|
||||
|
||||
/// Create a copy of UserDetailsState
|
||||
/// with the given fields replaced by the non-null parameter values.
|
||||
@override
|
||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||
_$$UserDetailsStateImplCopyWith<_$UserDetailsStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
520
lib/features/user_details/presentation/user_details_screen.dart
Normal file
520
lib/features/user_details/presentation/user_details_screen.dart
Normal file
@@ -0,0 +1,520 @@
|
||||
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/loader.dart';
|
||||
import 'package:eatvio_app/features/diets/presentation/widgets/more_options.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/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/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> {
|
||||
final List<String> chipsLabelList = ['Вес', 'Замеры', 'ИМТ'];
|
||||
final List<String> chipsIntervalLabelList = ['1М', '3М', '6М', '1Г', 'ВСЁ ВРЕМЯ'];
|
||||
final List<String> chipsIntervalList = ['1', '3', '6', '12', 'all'];
|
||||
|
||||
List<WeightModel> weightPoints = [];
|
||||
List<CircumferenceModel> circumferencePoints = [];
|
||||
int _selectedChipIndex = 0;
|
||||
int _selectedIntervalChipIndex = 0;
|
||||
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) {
|
||||
weightPoints = state.weightPoints ?? [];
|
||||
circumferencePoints = state.circumferencePoints ?? [];
|
||||
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}',
|
||||
),
|
||||
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()
|
||||
..addListener(() {
|
||||
setState(() {
|
||||
isMoreOptionsVisible = false;
|
||||
});
|
||||
}),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
spacing: 12,
|
||||
children: [
|
||||
SizedBox.shrink(),
|
||||
_charts(),
|
||||
ExpandableBouble(
|
||||
initiallyExpanded: true,
|
||||
title: s.general_info,
|
||||
children: [
|
||||
Text(
|
||||
s.date_of_birth,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: DateTime.parse(profileDetails.birthdate).format('dd.MM.yyyy')),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.sex,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.gender.parseGender()),
|
||||
),
|
||||
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),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.height.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.weight,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.weight.toStringAsFixed(0)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.chest_circumference,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.chestCircumference.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.waist_circumference,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.waistCircumference.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.hip_circumference,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.hipCircumference.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
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),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.bloodPressureUp.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.lower,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.bloodPressureDown.toStringAsFixed(0)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.has_hypo,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.hasHypo.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
s.has_hyper,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.hasHyper.toString()),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
ExpandableBouble(
|
||||
title: s.other_info,
|
||||
children: [
|
||||
Text(
|
||||
s.has_alergy,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.aboutAlergy),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.takes_pills,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.aboutTakingPils),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.sport_hobbies,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.aboutSportHobbies),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.liked_groceries,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.favoriteFoods),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.not_liked_groceries,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
CustomTextFormField(
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: profileDetails.unfavoriteFoods),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
s.additional_information,
|
||||
style: TextStyles.textSMedium.copyWith(color: appTheme.black),
|
||||
),
|
||||
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),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return Scaffold(
|
||||
body: Loader(),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
_charts() {
|
||||
return Material(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
child: 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,
|
||||
);
|
||||
case 1:
|
||||
return CircumferenceChartWidget(
|
||||
circumferencePoints: circumferencePoints,
|
||||
);
|
||||
case 2:
|
||||
return ImtChartWidget(
|
||||
weightPoints: weightPoints,
|
||||
);
|
||||
default:
|
||||
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),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_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) {
|
||||
context.read<UserDetailsCubit>().getChartData(period: chipsIntervalList[index], slug: widget.slug);
|
||||
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;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import 'package:eatvio_app/core/theme/custom_text_style.dart';
|
||||
import 'package:eatvio_app/core/theme/theme_helper.dart';
|
||||
import 'package:eatvio_app/core/widgets/main_background_bouble.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ExpandableBouble extends StatelessWidget {
|
||||
const ExpandableBouble({super.key, required this.title, required this.children, this.initiallyExpanded = false});
|
||||
final String title;
|
||||
final List<Widget> children;
|
||||
final bool initiallyExpanded;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedSize(
|
||||
duration: Duration(seconds: 1),
|
||||
child: MainBackgroundBouble(
|
||||
child: Theme(
|
||||
data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
|
||||
child: ExpansionTile(
|
||||
initiallyExpanded: initiallyExpanded,
|
||||
expandedCrossAxisAlignment: CrossAxisAlignment.start,
|
||||
expandedAlignment: Alignment.bottomLeft,
|
||||
tilePadding: EdgeInsets.symmetric(horizontal: 16),
|
||||
childrenPadding: EdgeInsets.symmetric(horizontal: 16),
|
||||
title: Text(
|
||||
title,
|
||||
style: TextStyles.headingXLSemibold.copyWith(color: appTheme.black),
|
||||
),
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -150,8 +150,16 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"),
|
||||
"from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"),
|
||||
"gallery": MessageLookupByLibrary.simpleMessage("Галерея"),
|
||||
"general_info":
|
||||
MessageLookupByLibrary.simpleMessage("Общая информация"),
|
||||
"gr": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"grams": MessageLookupByLibrary.simpleMessage("гр"),
|
||||
"has_alergy": MessageLookupByLibrary.simpleMessage("Наличие аллергии"),
|
||||
"has_hyper":
|
||||
MessageLookupByLibrary.simpleMessage("Склонность к гипертонии"),
|
||||
"has_hypo":
|
||||
MessageLookupByLibrary.simpleMessage("Склонность к гипотонии"),
|
||||
"height": MessageLookupByLibrary.simpleMessage("Рост"),
|
||||
"height_measurements":
|
||||
MessageLookupByLibrary.simpleMessage("Замер роста"),
|
||||
"hide": MessageLookupByLibrary.simpleMessage("Свернуть"),
|
||||
@@ -173,9 +181,12 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"light_type": MessageLookupByLibrary.simpleMessage("Легкая"),
|
||||
"light_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"С некоторыми видами диет можно употреблять алкоголь в умеренных количествах. Рекомендуется совмещать вместе с низкокалорийными закусками."),
|
||||
"liked_groceries":
|
||||
MessageLookupByLibrary.simpleMessage("Любимые продукты"),
|
||||
"link_was_copied":
|
||||
MessageLookupByLibrary.simpleMessage("Ссылка успешно скопирована"),
|
||||
"loading": MessageLookupByLibrary.simpleMessage("Загрузка..."),
|
||||
"lower": MessageLookupByLibrary.simpleMessage("Нижнее"),
|
||||
"male": MessageLookupByLibrary.simpleMessage("Мужской"),
|
||||
"meal": MessageLookupByLibrary.simpleMessage("Приём пищи"),
|
||||
"meat": MessageLookupByLibrary.simpleMessage("Мясо"),
|
||||
@@ -202,6 +213,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"no": MessageLookupByLibrary.simpleMessage("Нет"),
|
||||
"no_account":
|
||||
MessageLookupByLibrary.simpleMessage("У меня нет аккаунта"),
|
||||
"not_liked_groceries":
|
||||
MessageLookupByLibrary.simpleMessage("Не любимые продукты"),
|
||||
"one_option": MessageLookupByLibrary.simpleMessage("1 опция"),
|
||||
"option": MessageLookupByLibrary.simpleMessage("Опция"),
|
||||
"option_content":
|
||||
@@ -217,6 +230,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Опция подразумевает создание индивидуальной диеты"),
|
||||
"option_title": MessageLookupByLibrary.simpleMessage("Заголовок опции"),
|
||||
"order": MessageLookupByLibrary.simpleMessage("Порядок"),
|
||||
"other_info": MessageLookupByLibrary.simpleMessage("Прочая информация"),
|
||||
"password": MessageLookupByLibrary.simpleMessage("Пароль"),
|
||||
"password_confirmation":
|
||||
MessageLookupByLibrary.simpleMessage("Подтвердите пароль"),
|
||||
@@ -231,6 +245,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"personal_diet_state":
|
||||
MessageLookupByLibrary.simpleMessage("Персональная"),
|
||||
"photo": MessageLookupByLibrary.simpleMessage("Фото"),
|
||||
"physical_fitness":
|
||||
MessageLookupByLibrary.simpleMessage("Физическая форма"),
|
||||
"place_of_living":
|
||||
MessageLookupByLibrary.simpleMessage("Место проживания"),
|
||||
"plan_author": MessageLookupByLibrary.simpleMessage("Автор плана"),
|
||||
@@ -246,6 +262,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"popular": MessageLookupByLibrary.simpleMessage("Популярные"),
|
||||
"preferred_language":
|
||||
MessageLookupByLibrary.simpleMessage("Предпочитаемый язык общения"),
|
||||
"pressure": MessageLookupByLibrary.simpleMessage("Давление"),
|
||||
"pressure_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления обязательны к заполнению"),
|
||||
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -263,14 +280,19 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
|
||||
"services": MessageLookupByLibrary.simpleMessage("Оказание услуг"),
|
||||
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
||||
"sex": MessageLookupByLibrary.simpleMessage("Пол"),
|
||||
"share": MessageLookupByLibrary.simpleMessage("Поделиться"),
|
||||
"skip": MessageLookupByLibrary.simpleMessage("Пропустить"),
|
||||
"slim": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type": MessageLookupByLibrary.simpleMessage("Похудение"),
|
||||
"slim_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"План питания для похудения должен быть разработан с учётом индивидуальных особенностей организма, возраста, пола, уровня физической активности и состояния здоровья. Общие принципы: \n● Снижение калорийности; \n● Сбалансированный рацион; \n● Разнообразие продуктов; \n● Питьевой режим; \n● Ограничение вредных продуктов;"),
|
||||
"sport_hobbies":
|
||||
MessageLookupByLibrary.simpleMessage("Спортивные увлечения"),
|
||||
"standard": MessageLookupByLibrary.simpleMessage("Стандарт"),
|
||||
"startDiet": MessageLookupByLibrary.simpleMessage("Начать диету"),
|
||||
"takes_pills":
|
||||
MessageLookupByLibrary.simpleMessage("Принимает лекарства"),
|
||||
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
|
||||
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
|
||||
"three_options": MessageLookupByLibrary.simpleMessage("3 опции"),
|
||||
@@ -281,8 +303,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"),
|
||||
"up_pressure": MessageLookupByLibrary.simpleMessage(
|
||||
"Верхние показатели давления:"),
|
||||
"upper": MessageLookupByLibrary.simpleMessage("Верхнее"),
|
||||
"user_authorization":
|
||||
MessageLookupByLibrary.simpleMessage("Аутентификация"),
|
||||
"user_data":
|
||||
MessageLookupByLibrary.simpleMessage("Данные пользователя"),
|
||||
"user_registration":
|
||||
MessageLookupByLibrary.simpleMessage("Регистрация пользователя"),
|
||||
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
|
||||
|
||||
@@ -88,7 +88,9 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"date_of_birth": MessageLookupByLibrary.simpleMessage("Дата рождения"),
|
||||
"day": MessageLookupByLibrary.simpleMessage("День"),
|
||||
"days": MessageLookupByLibrary.simpleMessage("дней"),
|
||||
"deleted": MessageLookupByLibrary.simpleMessage("Удалена"),
|
||||
"diary": MessageLookupByLibrary.simpleMessage("Дневник"),
|
||||
"diet": MessageLookupByLibrary.simpleMessage("Диета"),
|
||||
"diet_author": MessageLookupByLibrary.simpleMessage("Автор диеты"),
|
||||
"diet_plan": MessageLookupByLibrary.simpleMessage("План диеты"),
|
||||
"diet_state": MessageLookupByLibrary.simpleMessage("Статус диеты"),
|
||||
@@ -102,6 +104,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"down_pressure":
|
||||
MessageLookupByLibrary.simpleMessage("Нижние показатели давления:"),
|
||||
"draft": MessageLookupByLibrary.simpleMessage("Черновик"),
|
||||
"drafted": MessageLookupByLibrary.simpleMessage("Черновики"),
|
||||
"eating_behavior":
|
||||
MessageLookupByLibrary.simpleMessage("Пищевое поведение"),
|
||||
"eating_behavior_type": MessageLookupByLibrary.simpleMessage(
|
||||
@@ -109,6 +112,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"eating_behavior_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;"),
|
||||
"economy": MessageLookupByLibrary.simpleMessage("Эконом"),
|
||||
"edit": MessageLookupByLibrary.simpleMessage("Редактировать"),
|
||||
"email": MessageLookupByLibrary.simpleMessage("Элетронная почта"),
|
||||
"email_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Необходимо ввести адрес электронной почты"),
|
||||
@@ -142,6 +146,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"fit_type_desc": MessageLookupByLibrary.simpleMessage(
|
||||
"План питания для поддержания формы сбалансированный и разнообразный, чтобы обеспечить организм всеми необходимыми питательными веществами. Общие принципы: \n● Дробное питание; \n● Разнообразие продуктов; \n● Контроль порций; \n● Питьевой режим; \n● Ограничение вредных продуктов;"),
|
||||
"fitness": MessageLookupByLibrary.simpleMessage("Поддержка формы"),
|
||||
"from": MessageLookupByLibrary.simpleMessage("от"),
|
||||
"from_a_to_z": MessageLookupByLibrary.simpleMessage("Название: А-Я"),
|
||||
"from_z_to_a": MessageLookupByLibrary.simpleMessage("Название: Я-А"),
|
||||
"gallery": MessageLookupByLibrary.simpleMessage("Галерея"),
|
||||
@@ -187,6 +192,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"msg_something_went_wrong":
|
||||
MessageLookupByLibrary.simpleMessage("Что то пошло не так!"),
|
||||
"my_blog": MessageLookupByLibrary.simpleMessage("Мой блог"),
|
||||
"my_diets": MessageLookupByLibrary.simpleMessage("Мои диеты"),
|
||||
"my_plans": MessageLookupByLibrary.simpleMessage("Мои планы"),
|
||||
"my_settings": MessageLookupByLibrary.simpleMessage("Мои настройки"),
|
||||
"name_empty": MessageLookupByLibrary.simpleMessage(
|
||||
"Имя пользователя обязательно для заполнения"),
|
||||
@@ -220,6 +227,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"password_short": MessageLookupByLibrary.simpleMessage(
|
||||
"В пароле должно быть минимум 6 символов"),
|
||||
"pcs": MessageLookupByLibrary.simpleMessage("шт"),
|
||||
"personal": MessageLookupByLibrary.simpleMessage("Персональные"),
|
||||
"personal_diet_state":
|
||||
MessageLookupByLibrary.simpleMessage("Персональная"),
|
||||
"photo": MessageLookupByLibrary.simpleMessage("Фото"),
|
||||
@@ -242,11 +250,15 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"pressure_is_not_a_number": MessageLookupByLibrary.simpleMessage(
|
||||
"Все показатели давления должны быть числами"),
|
||||
"preview": MessageLookupByLibrary.simpleMessage("Превью"),
|
||||
"price": MessageLookupByLibrary.simpleMessage("Цена"),
|
||||
"price_explanation": MessageLookupByLibrary.simpleMessage(
|
||||
"Разница в ценах, это комиссия Итвио"),
|
||||
"profile": MessageLookupByLibrary.simpleMessage("Профиль"),
|
||||
"proteins": MessageLookupByLibrary.simpleMessage("Белки"),
|
||||
"publish": MessageLookupByLibrary.simpleMessage("Опубликовать"),
|
||||
"published": MessageLookupByLibrary.simpleMessage("Опубликованные"),
|
||||
"removeFromActive":
|
||||
MessageLookupByLibrary.simpleMessage("Снять с публикации"),
|
||||
"save": MessageLookupByLibrary.simpleMessage("Сохранить"),
|
||||
"services": MessageLookupByLibrary.simpleMessage("Оказание услуг"),
|
||||
"settings": MessageLookupByLibrary.simpleMessage("Настройки"),
|
||||
@@ -261,6 +273,7 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"tell_your_schedule": MessageLookupByLibrary.simpleMessage(
|
||||
"Расскажите в свободной форме о том как просыпаетесь, когда едите, когда ложитесь спать:"),
|
||||
"three_options": MessageLookupByLibrary.simpleMessage("3 опции"),
|
||||
"toOffer": MessageLookupByLibrary.simpleMessage("Предложить"),
|
||||
"to_draft": MessageLookupByLibrary.simpleMessage("В черновик"),
|
||||
"unfavorite_foods":
|
||||
MessageLookupByLibrary.simpleMessage("Нелюбимые продукты"),
|
||||
@@ -268,6 +281,8 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
"Верхние показатели давления:"),
|
||||
"user_authorization":
|
||||
MessageLookupByLibrary.simpleMessage("Аутентификация"),
|
||||
"user_data":
|
||||
MessageLookupByLibrary.simpleMessage("Данные пользователя"),
|
||||
"user_registration":
|
||||
MessageLookupByLibrary.simpleMessage("Регистрация пользователя"),
|
||||
"username": MessageLookupByLibrary.simpleMessage("Имя пользователя"),
|
||||
|
||||
@@ -2169,6 +2169,166 @@ class S {
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Данные пользователя`
|
||||
String get user_data {
|
||||
return Intl.message(
|
||||
'Данные пользователя',
|
||||
name: 'user_data',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Общая информация`
|
||||
String get general_info {
|
||||
return Intl.message(
|
||||
'Общая информация',
|
||||
name: 'general_info',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Пол`
|
||||
String get sex {
|
||||
return Intl.message(
|
||||
'Пол',
|
||||
name: 'sex',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Физическая форма`
|
||||
String get physical_fitness {
|
||||
return Intl.message(
|
||||
'Физическая форма',
|
||||
name: 'physical_fitness',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Рост`
|
||||
String get height {
|
||||
return Intl.message(
|
||||
'Рост',
|
||||
name: 'height',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Давление`
|
||||
String get pressure {
|
||||
return Intl.message(
|
||||
'Давление',
|
||||
name: 'pressure',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Верхнее`
|
||||
String get upper {
|
||||
return Intl.message(
|
||||
'Верхнее',
|
||||
name: 'upper',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Нижнее`
|
||||
String get lower {
|
||||
return Intl.message(
|
||||
'Нижнее',
|
||||
name: 'lower',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Склонность к гипотонии`
|
||||
String get has_hypo {
|
||||
return Intl.message(
|
||||
'Склонность к гипотонии',
|
||||
name: 'has_hypo',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Склонность к гипертонии`
|
||||
String get has_hyper {
|
||||
return Intl.message(
|
||||
'Склонность к гипертонии',
|
||||
name: 'has_hyper',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Прочая информация`
|
||||
String get other_info {
|
||||
return Intl.message(
|
||||
'Прочая информация',
|
||||
name: 'other_info',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Наличие аллергии`
|
||||
String get has_alergy {
|
||||
return Intl.message(
|
||||
'Наличие аллергии',
|
||||
name: 'has_alergy',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Принимает лекарства`
|
||||
String get takes_pills {
|
||||
return Intl.message(
|
||||
'Принимает лекарства',
|
||||
name: 'takes_pills',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Спортивные увлечения`
|
||||
String get sport_hobbies {
|
||||
return Intl.message(
|
||||
'Спортивные увлечения',
|
||||
name: 'sport_hobbies',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Любимые продукты`
|
||||
String get liked_groceries {
|
||||
return Intl.message(
|
||||
'Любимые продукты',
|
||||
name: 'liked_groceries',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Не любимые продукты`
|
||||
String get not_liked_groceries {
|
||||
return Intl.message(
|
||||
'Не любимые продукты',
|
||||
name: 'not_liked_groceries',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||
|
||||
@@ -210,5 +210,21 @@
|
||||
"diet": "Диета",
|
||||
"deleted": "Удалена",
|
||||
"my_plans": "Мои планы",
|
||||
"from": "от"
|
||||
"from": "от",
|
||||
"user_data": "Данные пользователя",
|
||||
"general_info": "Общая информация",
|
||||
"sex": "Пол",
|
||||
"physical_fitness": "Физическая форма",
|
||||
"height": "Рост",
|
||||
"pressure": "Давление",
|
||||
"upper": "Верхнее",
|
||||
"lower": "Нижнее",
|
||||
"has_hypo": "Склонность к гипотонии",
|
||||
"has_hyper": "Склонность к гипертонии",
|
||||
"other_info": "Прочая информация",
|
||||
"has_alergy": "Наличие аллергии",
|
||||
"takes_pills": "Принимает лекарства",
|
||||
"sport_hobbies": "Спортивные увлечения",
|
||||
"liked_groceries": "Любимые продукты",
|
||||
"not_liked_groceries": "Не любимые продукты"
|
||||
}
|
||||
|
||||
@@ -197,5 +197,18 @@
|
||||
"wellness_type": "Улучшение самочувствия",
|
||||
"wellness_type_desc": "Если вы любите мучные продукты, но хотите придерживаться диеты, вам подходит диета с добавленим мучных блюд на основе цельнозерновых вариантов. В них больше сложных углеводов и клетчатки, что способствует длительному чувству сытости и поддерживает здоровье пищеварительной системы.",
|
||||
"eating_behavior_type": "Формирование пищевого поведения",
|
||||
"eating_behavior_type_desc": "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;"
|
||||
"eating_behavior_type_desc": "Формирование здорового пищевого поведения — это процесс, который включает в себя изменение привычек и отношения к еде. Он направлен на то, чтобы помочь людям научиться правильно питаться и поддерживать здоровый образ жизни.Основные принципы формирования здорового пищевого поведения: \n● Разнообразие продуктов; \n● Сбалансированный рацион; \n● Питьевой режим; \n● Ограничение вредных продуктов; \n● Регулярные приёмы пищи; \n● Умеренность;Осознанное питание; \n● Физическая активность;",
|
||||
"price": "Цена",
|
||||
"my_diets": "Мои диеты",
|
||||
"published": "Опубликованные",
|
||||
"drafted": "Черновики",
|
||||
"personal": "Персональные",
|
||||
"edit": "Редактировать",
|
||||
"toOffer": "Предложить",
|
||||
"removeFromActive": "Снять с публикации",
|
||||
"diet": "Диета",
|
||||
"deleted": "Удалена",
|
||||
"my_plans": "Мои планы",
|
||||
"from": "от",
|
||||
"user_data": "Данные пользователя"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user