diff --git a/assets/images/img_logo_eatvio.svg b/assets/images/img_logo_eatvio.svg index bc575bc9..6fcfd149 100644 --- a/assets/images/img_logo_eatvio.svg +++ b/assets/images/img_logo_eatvio.svg @@ -1,12 +1,56 @@ - - - - - - - - - - - + + + + + + + + + + + + + diff --git a/assets/images/img_nav_bell.svg b/assets/images/img_nav_bell.svg new file mode 100644 index 00000000..3304f0cd --- /dev/null +++ b/assets/images/img_nav_bell.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_nav_blue_gray_400_24x25.svg b/assets/images/img_nav_chat.svg similarity index 100% rename from assets/images/img_nav_blue_gray_400_24x25.svg rename to assets/images/img_nav_chat.svg diff --git a/assets/images/img_nav.svg b/assets/images/img_nav_diary.svg similarity index 100% rename from assets/images/img_nav.svg rename to assets/images/img_nav_diary.svg diff --git a/assets/images/img_nav_diets.svg b/assets/images/img_nav_diets.svg new file mode 100644 index 00000000..6300006a --- /dev/null +++ b/assets/images/img_nav_diets.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_nav_exit.svg b/assets/images/img_nav_exit.svg new file mode 100644 index 00000000..5559649e --- /dev/null +++ b/assets/images/img_nav_exit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/img_nav_feed.svg b/assets/images/img_nav_feed.svg new file mode 100644 index 00000000..55794777 --- /dev/null +++ b/assets/images/img_nav_feed.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/images/img_nav_finance.svg b/assets/images/img_nav_finance.svg new file mode 100644 index 00000000..79c9d63a --- /dev/null +++ b/assets/images/img_nav_finance.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/img_nav_logo.svg b/assets/images/img_nav_logo.svg new file mode 100644 index 00000000..b4b27e75 --- /dev/null +++ b/assets/images/img_nav_logo.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/images/img_nav_plans.svg b/assets/images/img_nav_plans.svg new file mode 100644 index 00000000..62e0c17a --- /dev/null +++ b/assets/images/img_nav_plans.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_nav_recipes.svg b/assets/images/img_nav_recipes.svg new file mode 100644 index 00000000..505da803 --- /dev/null +++ b/assets/images/img_nav_recipes.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_nav_settings.svg b/assets/images/img_nav_settings.svg new file mode 100644 index 00000000..619bd4e7 --- /dev/null +++ b/assets/images/img_nav_settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/img_nav_support.svg b/assets/images/img_nav_support.svg new file mode 100644 index 00000000..84859d74 --- /dev/null +++ b/assets/images/img_nav_support.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/lib/core/utils/image_constant.dart b/lib/core/utils/image_constant.dart index 37113a30..e7dd2b2a 100644 --- a/lib/core/utils/image_constant.dart +++ b/lib/core/utils/image_constant.dart @@ -79,7 +79,33 @@ class ImageConstant { static String imgEllipse3 = '$imagePath/img_ellipse_3.png'; - static String imgNav = '$imagePath/img_nav.svg'; + //------------------NAVIGATION--------------------------------- + + static String imgDiary = '$imagePath/img_nav_diary.svg'; + + static String imgFeed = '$imagePath/img_nav_feed.svg'; + + static String imgChat = '$imagePath/img_nav_chat.svg'; + + static String imgLogo = '$imagePath/img_nav_logo.svg'; + + static String imgBell = '$imagePath/img_nav_bell.svg'; + + static String imgSettings = '$imagePath/img_nav_settings.svg'; + + static String imgRecipes = '$imagePath/img_nav_recipes.svg'; + + static String imgDiets = '$imagePath/img_nav_diets.svg'; + + static String imgPlans = '$imagePath/img_nav_plans.svg'; + + static String imgFinance = '$imagePath/img_nav_finance.svg'; + + static String imgSupport = '$imagePath/img_nav_support.svg'; + + static String imgExit = '$imagePath/img_nav_exit.svg'; + + //------------------------------------------------------------- static String imgNavBlueGray400 = '$imagePath/img_nav_blue_gray_400.svg'; diff --git a/lib/data/models/userRegistrationModel/user_registration_model.dart b/lib/data/models/userRegistrationModel/user_registration_model.dart index 0001f9ec..baeb3a16 100644 --- a/lib/data/models/userRegistrationModel/user_registration_model.dart +++ b/lib/data/models/userRegistrationModel/user_registration_model.dart @@ -86,6 +86,7 @@ class UserRegistrationSheet { 'favorite_foods': favoriteFoods, 'unfavorite_foods': unfavoriteFoods, 'additional_info': additionalInfo, + 'activity_coefficient': '1.2', }; } } diff --git a/lib/presentation/auth/auth_screen/auth_screen.dart b/lib/presentation/auth/auth_screen/auth_screen.dart index 1ac19724..b85786d6 100644 --- a/lib/presentation/auth/auth_screen/auth_screen.dart +++ b/lib/presentation/auth/auth_screen/auth_screen.dart @@ -34,7 +34,7 @@ class AuthScreen extends StatelessWidget { width: double.maxFinite, padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), child: Column(children: [ - SizedBox(height: 39.v), + SizedBox(height: 36.v), Text("user_authorization".tr, style: theme.textTheme.headlineSmall), SizedBox(height: 60.v), @@ -58,32 +58,32 @@ class AuthScreen extends StatelessWidget { controller: passwordController, ); }), - Spacer(), + SizedBox(height: 50.v), NextStepButton( text: "no_account".tr.toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: onTapNoAccount(context)), - NextStepButton( + /*NextStepButton( text: "Тест дневника".toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, onPressed: onTapDiaryTest(context)), NextStepButton( - text: "Тест профиля".toUpperCase(), + text: "Тест чата".toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapProfileTest(context)), + onPressed: onTapProfileTest(context)),*/ BlocBuilder(builder: (context, state) { return NextStepButton( text: "authentificate".tr.toUpperCase(), margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: () => onTapAuth(state, context)); + onPressed: onTapAuth(state, context)); }), ]))); } @@ -102,6 +102,7 @@ class AuthScreen extends StatelessWidget { headers: {'Content-Type': 'application/json'}, body: json.encode(credentials), encoding: utf8); + print(response.statusCode); if (response.statusCode == 200) { var res = await jsonDecode(response.body); final box = await Hive.openBox('token'); diff --git a/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart b/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart new file mode 100644 index 00000000..47ed9dec --- /dev/null +++ b/lib/presentation/chat/chat_screen/bloc/chat_bloc.dart @@ -0,0 +1,20 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/chat/chat_screen/models/chat_model.dart'; +part 'chat_event.dart'; +part 'chat_state.dart'; + +/// A bloc that manages the state of a Chat according to the event that is dispatched to it. +class ChatBloc extends Bloc { + ChatBloc(ChatState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + ChatInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith(chatModelObj: state.chatModelObj?.copyWith())); + } +} diff --git a/lib/presentation/chat/chat_screen/bloc/chat_event.dart b/lib/presentation/chat/chat_screen/bloc/chat_event.dart new file mode 100644 index 00000000..a3778f98 --- /dev/null +++ b/lib/presentation/chat/chat_screen/bloc/chat_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'chat_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///Chat widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class ChatEvent extends Equatable {} + +/// Event that is dispatched when the Chat widget is first created. +class ChatInitialEvent extends ChatEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends ChatEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/chat/chat_screen/bloc/chat_state.dart b/lib/presentation/chat/chat_screen/bloc/chat_state.dart new file mode 100644 index 00000000..20be159f --- /dev/null +++ b/lib/presentation/chat/chat_screen/bloc/chat_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'chat_bloc.dart'; + +/// Represents the state of Chat in the application. +class ChatState extends Equatable { + ChatState({ + this.selectedDropDownValue, + this.chatModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + ChatModel? chatModelObj; + + @override + List get props => [ + selectedDropDownValue, + chatModelObj, + ]; + ChatState copyWith({ + SelectionPopupModel? selectedDropDownValue, + ChatModel? chatModelObj, + }) { + return ChatState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + chatModelObj: chatModelObj ?? this.chatModelObj, + ); + } +} diff --git a/lib/presentation/chat/chat_screen/chat_screen.dart b/lib/presentation/chat/chat_screen/chat_screen.dart new file mode 100644 index 00000000..e78a8f38 --- /dev/null +++ b/lib/presentation/chat/chat_screen/chat_screen.dart @@ -0,0 +1,20 @@ +import 'bloc/chat_bloc.dart'; +import 'models/chat_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class ChatScreen extends StatelessWidget { + const ChatScreen({Key? key}) : super(key: key); + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => ChatBloc(ChatState(chatModelObj: ChatModel())) + ..add(ChatInitialEvent()), + child: ChatScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return Container(); + } +} diff --git a/lib/presentation/chat/chat_screen/models/chat_model.dart b/lib/presentation/chat/chat_screen/models/chat_model.dart new file mode 100644 index 00000000..0e74b3ee --- /dev/null +++ b/lib/presentation/chat/chat_screen/models/chat_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [chat_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class ChatModel extends Equatable { + ChatModel(); + + ChatModel copyWith() { + return ChatModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart new file mode 100644 index 00000000..1fbde95f --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_bloc.dart @@ -0,0 +1,21 @@ +import 'package:equatable/equatable.dart'; +import 'package:flutter/material.dart'; +import '/core/app_export.dart'; +import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_select_model.dart'; +part 'chat_select_event.dart'; +part 'chat_select_state.dart'; + +/// A bloc that manages the state of a ChatSelect according to the event that is dispatched to it. +class ChatSelectBloc extends Bloc { + ChatSelectBloc(ChatSelectState initialState) : super(initialState) { + on(_onInitialize); + } + + _onInitialize( + ChatSelectInitialEvent event, + Emitter emit, + ) async { + emit(state.copyWith( + chatSelectModelObj: state.chatSelectModelObj?.copyWith())); + } +} diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_event.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_event.dart new file mode 100644 index 00000000..681736b1 --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_event.dart @@ -0,0 +1,28 @@ +// ignore_for_file: must_be_immutable + +part of 'chat_select_bloc.dart'; + +/// Abstract class for all events that can be dispatched from the +///ChatSelect widget. +/// +/// Events must be immutable and implement the [Equatable] interface. +@immutable +abstract class ChatSelectEvent extends Equatable {} + +/// Event that is dispatched when the ChatSelect widget is first created. +class ChatSelectInitialEvent extends ChatSelectEvent { + @override + List get props => []; +} + +///event for dropdown selection +class ChangeDropDownEvent extends ChatSelectEvent { + ChangeDropDownEvent({required this.value}); + + SelectionPopupModel value; + + @override + List get props => [ + value, + ]; +} diff --git a/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart b/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart new file mode 100644 index 00000000..7f56519e --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/bloc/chat_select_state.dart @@ -0,0 +1,31 @@ +// ignore_for_file: must_be_immutable + +part of 'chat_select_bloc.dart'; + +/// Represents the state of ChatSelect in the application. +class ChatSelectState extends Equatable { + ChatSelectState({ + this.selectedDropDownValue, + this.chatSelectModelObj, + }); + + SelectionPopupModel? selectedDropDownValue; + + ChatSelectModel? chatSelectModelObj; + + @override + List get props => [ + selectedDropDownValue, + chatSelectModelObj, + ]; + ChatSelectState copyWith({ + SelectionPopupModel? selectedDropDownValue, + ChatSelectModel? chatSelectModelObj, + }) { + return ChatSelectState( + selectedDropDownValue: + selectedDropDownValue ?? this.selectedDropDownValue, + chatSelectModelObj: chatSelectModelObj ?? this.chatSelectModelObj, + ); + } +} diff --git a/lib/presentation/chat/chat_select_screen/chat_select_screen.dart b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart new file mode 100644 index 00000000..1959b70c --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/chat_select_screen.dart @@ -0,0 +1,21 @@ +import 'bloc/chat_select_bloc.dart'; +import 'models/chat_select_model.dart'; +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; + +class ChatSelectScreen extends StatelessWidget { + const ChatSelectScreen({Key? key}) : super(key: key); + static Widget builder(BuildContext context) { + return BlocProvider( + create: (context) => ChatSelectBloc( + ChatSelectState(chatSelectModelObj: ChatSelectModel())) + ..add(ChatSelectInitialEvent()), + child: ChatSelectScreen()); + } + + @override + Widget build(BuildContext context) { + mediaQueryData = MediaQuery.of(context); + return Container(); + } +} diff --git a/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart new file mode 100644 index 00000000..e77aa4fe --- /dev/null +++ b/lib/presentation/chat/chat_select_screen/models/chat_select_model.dart @@ -0,0 +1,16 @@ +// ignore_for_file: must_be_immutable + +import 'package:equatable/equatable.dart'; + +/// This class defines the variables used in the [chat_select_screen], +/// and is typically used to hold data that is passed between different parts of the application. +class ChatSelectModel extends Equatable { + ChatSelectModel(); + + ChatSelectModel copyWith() { + return ChatSelectModel(); + } + + @override + List get props => []; +} diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart index d3d9d29c..1bf38360 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_bloc.dart @@ -7,6 +7,7 @@ import 'package:image_picker/image_picker.dart'; import 'package:eatvio_app/presentation/diary/diary_edit_screen/models/diary_edit_model.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; +import 'package:hive/hive.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; part 'diary_edit_event.dart'; @@ -44,142 +45,91 @@ class DiaryEditBloc extends Bloc { Emitter emit, ) async { try { - final token = - "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; - final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $token', - }, - ); - if (response.statusCode == 200) { - final data = jsonDecode(response.body); - if (data is Map && data.containsKey('id')) { - final int diaryId = data['id']; - try { - final response = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $token', - }, - ); - final diary = jsonDecode(response.body)['diary']; - print("Screen load success"); - if (diary is Map) { - final String diaryDate = - diary['date'] ?? DateTime.now().toString(); - final responseChart = await http.get( - Uri.parse(dotenv.env['SERVER_ROOT']! + - '/diary/$diaryId/dailyNutritionData/'), - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $token', - }, - ); - if (responseChart.statusCode == 200) { - final recommendedChartValues = jsonDecode( - responseChart.body)['dailyNutritionRecommendation']; - final consumedChartValues = - jsonDecode(responseChart.body)['dailyNutritionIntake']; - - if (state is DiaryEditLoadedState) { - // Если текущее состояние уже загружено, обновляем его - var currentState = state as DiaryEditLoadedState; - emit((currentState).copyWith( - currentMeal: currentState.currentMeal, - wakeupExpanded: currentState.wakeupExpanded, - moodExpanded: currentState.moodExpanded, - moderationExpanded: currentState.moderationExpanded, - token: currentState.token, - meals: currentState.meals, - portions: currentState.portions, - photos: currentState.photos, - wakeupController: currentState.wakeupController, - retireController: currentState.retireController, - commentController: currentState.commentController, - mealTimeController: currentState.mealTimeController, - productNameController: currentState.productNameController, - caloriesController: currentState.caloriesController, - proteinsController: currentState.proteinsController, - fatsController: currentState.fatsController, - carbsController: currentState.carbsController, - selectedSatiety: currentState.selectedSatiety, - selectedMood: currentState.selectedMood, - diaryDate: currentState.diaryDate, - diaryId: currentState.diaryId, - productQuantityController: - currentState.productQuantityController, - recommendedChartValues: - currentState.recommendedChartValues, - consumedChartValues: currentState.consumedChartValues, - autocompleteList: currentState.autocompleteList, - diaryEditModelObj: currentState.diaryEditModelObj)); - } else { - // Если текущее состояние - начальное, создаем новое загруженное состояние - emit(DiaryEditLoadedState( - currentMeal: SelectionPopupModel( - id: 1, title: "Прием пищи 1", isSelected: true), - portionController: SelectionPopupModel( - id: 0, title: "порций", isSelected: true), - wakeupExpanded: true, - moodExpanded: true, - moderationExpanded: false, - token: token, - recommendedChartValues: recommendedChartValues.values - .map((value) => value as int) - .toList(), - consumedChartValues: consumedChartValues.values - .map((value) => value as int) - .toList() ?? - [0, 0, 0, 0], - meals: diary['meals'], - portions: diary['meals'][0]['portions'], - photos: diary['meals'][0]['photos'], - wakeupController: toTime(diary['wakeup'] ?? "09:00"), - retireController: toTime(diary['retire'] ?? "23:00"), - mealTimeController: - toTime(diary['meals'][0]['time'] ?? "10:00"), - selectedSatiety: diary['meals'][0]['satiety'], - selectedMood: diary['meals'][0]['mood'], - commentController: - TextEditingController(text: diary['comment']), - productNameController: TextEditingController(), - productQuantityController: TextEditingController(), - caloriesController: TextEditingController(), - proteinsController: TextEditingController(), - fatsController: TextEditingController(), - carbsController: TextEditingController(), - diaryId: diaryId, - diaryDate: diaryDate, - autocompleteList: [], - diaryEditModelObj: state.diaryEditModelObj?.copyWith( - mealList: fillMealList(), - portionList: fillPortions()))); - } - } else { - emit(DiaryEditErrorState( - 'Ошибка при декодировании данных КБЖУ')); - } - } else { - // Ошибка при декодировании JSON - emit(DiaryEditErrorState( - 'Ошибка при декодировании данных дневника')); - } - } catch (e) { - // Ошибка при получении данных дневника - emit(DiaryEditErrorState( - 'Ошибка при получении данных дневника: $e')); + // final token = + // "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; + final box = await Hive.openBox('token'); + final token = box.get('token'); + //print(await fetchDiaryId(token)); + final int diaryId = await fetchDiaryId(token, emit); + try { + print("Diary ID fetched"); + final diary = await fetchDiaryData(token, diaryId); + print("Screen load success"); + if (diary is Map) { + final String diaryDate = diary['date'] ?? DateTime.now().toString(); + final chartValues = await fetchChartValues(token, diaryId, emit); + if (state is DiaryEditLoadedState) { + // Если текущее состояние уже загружено, обновляем его + var currentState = state as DiaryEditLoadedState; + emit((currentState).copyWith( + currentMeal: currentState.currentMeal, + wakeupExpanded: currentState.wakeupExpanded, + moodExpanded: currentState.moodExpanded, + moderationExpanded: currentState.moderationExpanded, + token: currentState.token, + meals: currentState.meals, + portions: currentState.portions, + photos: currentState.photos, + wakeupController: currentState.wakeupController, + retireController: currentState.retireController, + commentController: currentState.commentController, + mealTimeController: currentState.mealTimeController, + productNameController: currentState.productNameController, + caloriesController: currentState.caloriesController, + proteinsController: currentState.proteinsController, + fatsController: currentState.fatsController, + carbsController: currentState.carbsController, + selectedSatiety: currentState.selectedSatiety, + selectedMood: currentState.selectedMood, + diaryDate: currentState.diaryDate, + diaryId: currentState.diaryId, + productQuantityController: + currentState.productQuantityController, + recommendedChartValues: currentState.recommendedChartValues, + consumedChartValues: currentState.consumedChartValues, + autocompleteList: currentState.autocompleteList, + diaryEditModelObj: currentState.diaryEditModelObj)); + } else { + // Если текущее состояние - начальное, создаем новое загруженное состояние + final List meals = + fillMealList(diary['meals']); + emit(DiaryEditLoadedState( + currentMeal: meals[0], + portionController: SelectionPopupModel( + id: 0, title: "порций", isSelected: true), + wakeupExpanded: true, + moodExpanded: true, + moderationExpanded: false, + token: token, + recommendedChartValues: chartValues[0], + consumedChartValues: chartValues[1], + meals: diary['meals'], + portions: diary['meals'][0]['portions'], + photos: diary['meals'][0]['photos'], + wakeupController: toTime(diary['wakeup'] ?? "09:00"), + retireController: toTime(diary['retire'] ?? "23:00"), + mealTimeController: + toTime(diary['meals'][0]['time'] ?? "10:00"), + selectedSatiety: diary['meals'][0]['satiety'], + selectedMood: diary['meals'][0]['mood'], + commentController: + TextEditingController(text: diary['comment']), + productNameController: TextEditingController(), + productQuantityController: TextEditingController(), + caloriesController: TextEditingController(), + proteinsController: TextEditingController(), + fatsController: TextEditingController(), + carbsController: TextEditingController(), + diaryId: diaryId, + diaryDate: diaryDate, + autocompleteList: [], + diaryEditModelObj: state.diaryEditModelObj + ?.copyWith(mealList: meals, portionList: fillPortions()))); } - } else { - // Один или несколько ключевых полей отсутствуют, обрабатываем ошибку - emit( - DiaryEditErrorState('Некоторые необходимые данные отсутствуют.')); } - } else { - // Статус ответа не равен 200, обрабатываем ошибку - emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}')); + } catch (e) { + // Ошибка при получении данных дневника + emit(DiaryEditErrorState('Ошибка при получении данных дневника: $e')); } } catch (e) { // Ошибка при получении данных дневника @@ -187,12 +137,91 @@ class DiaryEditBloc extends Bloc { } } - reloadScreen(DiaryEditEvent event, Emitter emit) async { + fetchDiaryId(String token, Emitter emit) async { + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + if (response.statusCode == 200) { + final data = jsonDecode(response.body); + if (data is Map && data.containsKey('id')) { + final int diaryId = data['id']; + return diaryId; + } else { + emit(DiaryEditErrorState('Некоторые необходимые данные отсутствуют.')); + print('fail'); + return -1; + } + } else { + emit(DiaryEditErrorState('Ошибка сервера: ${response.statusCode}')); + print('fail'); + return -1; + } + } + + fetchDiaryData(String token, int diaryId) async { + final response = await http.get( + Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/$diaryId/show/'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + final diary = jsonDecode(response.body)['diary']; + + return diary; + } + + fetchChartValues( + String token, int diaryID, Emitter emit) async { + final responseChart = await http.get( + Uri.parse( + dotenv.env['SERVER_ROOT']! + '/diary/$diaryID/dailyNutritionData/'), + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + if (responseChart.statusCode == 200) { + final recommendedChartValues = + jsonDecode(responseChart.body)['dailyNutritionRecommendation'] + .values + .map((value) => value as int) + .toList(); + final consumedChartValues = + jsonDecode(responseChart.body)['dailyNutritionIntake'] + .values + .map((value) => value as int) + .toList(); + return [recommendedChartValues, consumedChartValues]; + } else { + emit(DiaryEditErrorState('Ошибка при декодировании данных КБЖУ')); + print('fail'); + return -1; + } + } + + refreshScreen( + int mealID, + DiaryEditEvent event, + Emitter emit, + ) async { + await reloadScreen(event, emit); + } + + reloadScreen( + DiaryEditEvent event, + Emitter emit, + ) async { print("Reloading..."); try { - final token = - "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; - + //final token = + // "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; final box = await Hive.openBox('token'); + final box = await Hive.openBox('token'); + final token = box.get('token'); final response = await http.get( Uri.parse(dotenv.env['SERVER_ROOT']! + '/diary/index'), headers: { @@ -231,45 +260,46 @@ class DiaryEditBloc extends Bloc { responseChart.body)['dailyNutritionRecommendation']; final consumedChartValues = jsonDecode(responseChart.body)['dailyNutritionIntake']; + final List meals = + fillMealList(diary['meals']); try { await Future(() => emit(DiaryEditLoadedState( - currentMeal: SelectionPopupModel( - id: 1, title: "Прием пищи 1", isSelected: true), - portionController: SelectionPopupModel( - id: 0, title: "порций", isSelected: true), - wakeupExpanded: true, - moodExpanded: true, - moderationExpanded: false, - token: token, - recommendedChartValues: recommendedChartValues.values - .map((value) => value as int) - .toList(), - consumedChartValues: consumedChartValues.values - .map((value) => value as int) - .toList(), - meals: diary['meals'], - portions: diary['meals'][0]['portions'], - photos: diary['meals'][0]['photos'], - wakeupController: toTime(diary['wakeup'] ?? "09:00"), - retireController: toTime(diary['retire'] ?? "23:00"), - mealTimeController: - toTime(diary['meals'][0]['time'] ?? "10:00"), - selectedSatiety: diary['meals'][0]['satiety'], - selectedMood: diary['meals'][0]['mood'], - commentController: - TextEditingController(text: diary['comment']), - productNameController: TextEditingController(), - productQuantityController: TextEditingController(), - caloriesController: TextEditingController(), - proteinsController: TextEditingController(), - fatsController: TextEditingController(), - carbsController: TextEditingController(), - diaryId: diaryId, - diaryDate: diaryDate, - autocompleteList: [], - diaryEditModelObj: state.diaryEditModelObj?.copyWith( - mealList: fillMealList(), - portionList: fillPortions())))); + diaryEditModelObj: state.diaryEditModelObj?.copyWith( + mealList: meals, portionList: fillPortions()), + currentMeal: meals[0], + portionController: SelectionPopupModel( + id: 0, title: "порций", isSelected: true), + wakeupExpanded: true, + moodExpanded: true, + moderationExpanded: false, + token: token, + recommendedChartValues: recommendedChartValues.values + .map((value) => value as int) + .toList(), + consumedChartValues: consumedChartValues.values + .map((value) => value as int) + .toList(), + meals: diary['meals'], + portions: diary['meals'][0]['portions'], + photos: diary['meals'][0]['photos'], + wakeupController: toTime(diary['wakeup'] ?? "09:00"), + retireController: toTime(diary['retire'] ?? "23:00"), + mealTimeController: + toTime(diary['meals'][0]['time'] ?? "10:00"), + selectedSatiety: diary['meals'][0]['satiety'], + selectedMood: diary['meals'][0]['mood'], + commentController: + TextEditingController(text: diary['comment']), + productNameController: TextEditingController(), + productQuantityController: TextEditingController(), + caloriesController: TextEditingController(), + proteinsController: TextEditingController(), + fatsController: TextEditingController(), + carbsController: TextEditingController(), + diaryId: diaryId, + diaryDate: diaryDate, + autocompleteList: [], + ))); print("Updated"); } catch (e) { @@ -351,6 +381,8 @@ class DiaryEditBloc extends Bloc { currentState.diaryId); if (response.statusCode == 200) { + print( + 'Mood change success! meal_id: ${currentState.currentMeal?.id}, mood: ${event.selectedElement}'); updatedState.selectedMood = event.selectedElement; emit(updatedState); // Передаем обновленное состояние в emit } @@ -387,6 +419,7 @@ class DiaryEditBloc extends Bloc { var response = await sendWakeupData( currentState.token, event.selectedTime, currentState.diaryId); if (response.statusCode == 200) { + await reloadScreen(event, emit); var updatedState = currentState.copyWith(wakeupController: event.selectedTime); print("Wakeup time changed to ${event.selectedTime}"); @@ -403,6 +436,7 @@ class DiaryEditBloc extends Bloc { var response = await sendRetireData( currentState.token, event.selectedTime, currentState.diaryId); if (response.statusCode == 200) { + await reloadScreen(event, emit); var updatedState = currentState.copyWith(retireController: event.selectedTime); print("Retire time changed to ${event.selectedTime}"); @@ -496,11 +530,10 @@ class DiaryEditBloc extends Bloc { if (state is DiaryEditLoadedState) { var currentState = state as DiaryEditLoadedState; final meal = currentState.meals?.firstWhere( - (meal) => meal['type'] == event.value.id, + (meal) => meal['id'] == event.value.id, orElse: () => null); - - print(meal); int? id = event.value.id; + print(meal['photos']); DiaryEditLoadedState updatedState = currentState.copyWith( currentMeal: event.value, portions: meal['portions'], @@ -508,6 +541,7 @@ class DiaryEditBloc extends Bloc { mealTimeController: toTime(meal['time'] ?? "1$id:00"), selectedMood: meal['mood'], selectedSatiety: meal['satiety']); + print(updatedState.photos); emit(updatedState); } } @@ -727,7 +761,7 @@ class DiaryEditBloc extends Bloc { ); if (response.statusCode == 200) { - print("finished"); + await reloadScreen(event, emit); } } } @@ -901,15 +935,16 @@ class DiaryEditBloc extends Bloc { return timeOfDay; } - List fillMealList() { - return [ - SelectionPopupModel(id: 1, title: "Прием пищи 1", isSelected: true), - SelectionPopupModel(id: 2, title: "Прием пищи 2"), - SelectionPopupModel(id: 3, title: "Прием пищи 3"), - SelectionPopupModel(id: 4, title: "Прием пищи 4"), - SelectionPopupModel(id: 5, title: "Прием пищи 5"), - SelectionPopupModel(id: 6, title: "Прием пищи 6"), - ]; + List fillMealList(List meals) { + meals.sort(compareTypes); + return meals.map((meal) { + String title = "Прием пищи ${meal['type']}"; + return SelectionPopupModel(id: meal['id'], title: title); + }).toList(); + } + + int compareTypes(a, b) { + return a['type'].compareTo(b['type']); } List fillPortions() { diff --git a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart index 58c6fd25..ebed94bd 100644 --- a/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart +++ b/lib/presentation/diary/diary_edit_screen/bloc/diary_edit_state.dart @@ -139,6 +139,7 @@ class DiaryEditLoadedState extends DiaryEditState { diaryDate: diaryDate ?? this.diaryDate, token: token ?? this.token, meals: meals ?? this.meals, + photos: photos ?? this.photos, autocompleteList: autocompleteList ?? this.autocompleteList, portions: portions ?? this.portions, recommendedChartValues: diff --git a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart index e2bdbeee..6f37061c 100644 --- a/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart +++ b/lib/presentation/diary/diary_edit_screen/diary_edit_screen.dart @@ -13,6 +13,8 @@ import 'package:eatvio_app/widgets/custom_edit_text_form_field.dart'; import 'package:eatvio_app/widgets/custom_edit_drop_down.dart'; import 'package:eatvio_app/widgets/custom_outlined_button.dart'; import 'package:eatvio_app/widgets/custom_scale_element.dart'; +//import 'package:eatvio_app/widgets/custom_bottom_bar.dart'; +import 'package:carousel_slider/carousel_slider.dart'; // ignore: must_be_immutable class DiaryEditScreen extends StatelessWidget { @@ -229,7 +231,6 @@ class DiaryEditScreen extends StatelessWidget { state.autocompleteList!.map((dynamic item) => item as String).toList(); //print(_options); FocusNode focusNodeName = FocusNode(); - FocusNode focusNodeQuantity = FocusNode(); return Container( margin: EdgeInsets.symmetric(horizontal: 16.h), padding: EdgeInsets.symmetric( @@ -318,10 +319,7 @@ class DiaryEditScreen extends StatelessWidget { hintText: "Введите название продукта", controller: productEditingController, focusNode: focusNodeName, - onChanged: getAutocomplete(context, focusNodeQuantity), - /*onFieldSubmitted: (String value) { - onFieldSubmitted(); - },*/ + onChanged: getAutocomplete(context, focusNodeName), ); }, optionsViewBuilder: ( @@ -341,7 +339,7 @@ class DiaryEditScreen extends StatelessWidget { itemBuilder: (BuildContext context, int index) { final String option = options.elementAt(index); return GestureDetector( - onTap: selectProduct(onSelected, option), + onTap: selectProduct(onSelected, option, state), child: ListTile( title: Text(option), ), @@ -374,7 +372,7 @@ class DiaryEditScreen extends StatelessWidget { width: 150.h, hintText: "Кол-во", textInputAction: TextInputAction.done, - focusNode: focusNodeQuantity, + // focusNode: focusNodeQuantity, controller: state.productQuantityController, keyboardType: TextInputType.number, inputFormatters: [digitsOnly], @@ -404,11 +402,14 @@ class DiaryEditScreen extends StatelessWidget { .map((portion) => _buildProduct(context, portion)) .toList(), SizedBox(height: 30.v), - ...state.photos != null - ? state.photos! - .map((photo) => _buildPhoto(context, photo)) - .toList() - : [], + /*...state.photos != null + ? state.photos!.isEmpty + ? [Text('Фото пока нет')] + : state.photos! + .map((photo) => _buildPhoto(context, photo)) + .toList() + : [Text('Фото нет')],*/ + _buildCarousel(context, state), SizedBox(height: 20.v), _buildAddPhoto(context), SizedBox(height: 30.v), @@ -561,7 +562,9 @@ class DiaryEditScreen extends StatelessWidget { }; } - selectProduct(AutocompleteOnSelected onSelected, String option) { + selectProduct(AutocompleteOnSelected onSelected, String option, + DiaryEditLoadedState state) { + state.productNameController?.text = option; return () { onSelected(option); }; @@ -600,6 +603,20 @@ class DiaryEditScreen extends StatelessWidget { }; } + _buildCarousel(BuildContext context, DiaryEditLoadedState state) { + if (state.photos!.isEmpty) { + return Text("Фото нет"); + } else { + return CarouselSlider( + options: CarouselOptions(height: 340.0), + items: state.photos!.map((photo) { + return _buildPhoto( + context, photo); // Assuming photos are stored as strings + }).toList(), + ); + } + } + _buildProduct(BuildContext context, Map portion) { return Container( margin: EdgeInsets.symmetric(horizontal: 10.h), @@ -764,25 +781,37 @@ class DiaryEditScreen extends StatelessWidget { BarChartGroupData(x: 0, barRods: [ BarChartRodData( toY: consumedValues[0] / recommendedValues[0] * 100, - color: Colors.blue, + color: checkConsumedValues( + [recommendedValues[0]], [consumedValues[1]]) + ? Colors.red + : Colors.blue, ) ]), BarChartGroupData(x: 1, barRods: [ BarChartRodData( toY: consumedValues[1] / recommendedValues[1] * 100, - color: Colors.red, + color: checkConsumedValues( + [recommendedValues[1]], [consumedValues[1]]) + ? Colors.red + : Colors.blue, ) ]), BarChartGroupData(x: 2, barRods: [ BarChartRodData( toY: consumedValues[2] / recommendedValues[2] * 100, - color: Colors.green, + color: checkConsumedValues( + [recommendedValues[2]], [consumedValues[2]]) + ? Colors.red + : Colors.blue, ) ]), BarChartGroupData(x: 3, barRods: [ BarChartRodData( toY: consumedValues[3] / recommendedValues[3] * 100, - color: Colors.orange, + color: checkConsumedValues( + [recommendedValues[3]], [consumedValues[3]]) + ? Colors.red + : Colors.blue, ) ]), ], @@ -889,7 +918,7 @@ class DiaryEditScreen extends StatelessWidget { SizedBox(height: 19.v), if (checkConsumedValues(recommendedValues, consumedValues)) Text( - "*Превышенная суточная норма углеводов", + "*Превышенная суточная норма", style: theme.textTheme.labelLarge, ) ], @@ -1042,7 +1071,6 @@ class DiaryEditScreen extends StatelessWidget { Function() onFinishDayPressed(BuildContext context) { return () { - print("sad"); showDialog( context: context, builder: (BuildContext dialogContext) { diff --git a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart index 69207e24..29c6c673 100644 --- a/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart +++ b/lib/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart @@ -1,10 +1,11 @@ +//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart'; import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import '/core/app_export.dart'; import 'package:eatvio_app/presentation/profile/my_profile_screen/models/my_profile_model.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; -//import 'package:hive/hive.dart'; +import 'package:hive/hive.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; part 'my_profile_event.dart'; @@ -21,28 +22,29 @@ class MyProfileBloc extends Bloc { Emitter emit, ) async { try { - /*final box = await Hive.openBox('token'); - final token = box.get('token');*/ - final token = - "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; + final box = await Hive.openBox('token'); + final token = box.get('token'); + if (token == null) { + NavigatorService.popAndPushNamed( + AppRoutes.authScreen, + ); // Если токен есть, запускаем приложение + } + //final token = + // "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1neAggmpR2TidVGDPN34fa201a"; final response = await http.get( Uri.parse(dotenv.env['SERVER_ROOT']! + '/profile/index'), headers: { 'Authorization': 'Bearer $token', }, ); - if (response.statusCode == 200) { final data = jsonDecode(response.body); - // Проверка наличия ключевых полей в JSON if (data is Map && data.containsKey('user') && data.containsKey('userDetails') && data.containsKey('chartPoints') && data.containsKey('circumferences')) { - // Все ключевые поля присутствуют, продолжаем обработку if (state is MyProfileLoadedState) { - // Если текущее состояние уже загружено, обновляем его var currentState = state as MyProfileLoadedState; var plans = [] ..addAll(data["finishedPlans"]) @@ -51,9 +53,6 @@ class MyProfileBloc extends Bloc { ..addAll(data["paidPlan"]) ..addAll(data["requestedPlan"]) ..addAll(data["initedPlan"]); - - // Обновляем значения контроллеров только если они уже были созданы - emit((currentState).copyWith( chartPoints: currentState.chartPoints, chartDates: currentState.chartDates, @@ -123,18 +122,6 @@ class MyProfileBloc extends Bloc { }) : data["chartPoints"]; - /*List weights = [0.0, 0.0, 0.0, 0.0]; - List dates = [ - "0000-00-00 00:00:00", - "0000-00-00 00:00:00", - "0000-00-00 00:00:00", - "0000-00-00 00:00:00" - ]; - for (int i = 0; i < data["chartPoints"].length; i++) { - weights[i] = data["chartPoints"][i]["weight"].toDouble(); - dates[i] = data["chartPoints"][i]["created_at"].toString(); - } - print(data);*/ List dates = [ "0000-00-00 00:00:00", "0000-00-00 00:00:00", @@ -169,14 +156,7 @@ class MyProfileBloc extends Bloc { }; } } - print(data['userDetails']); - /*print(chartPoints); - print(circumferences);*/ - /*print(weights); - print(weights.runtimeType); - print(circumferences); - print(circumferences.runtimeType);*/ - // Если текущее состояние - начальное, создаем новое загруженное состояние + emit(MyProfileLoadedState( chartPoints: chartPoints, chartDates: dates, @@ -231,7 +211,7 @@ class MyProfileBloc extends Bloc { selectedCity: data['userDetails']['city'], selectedCountry: data['userDetails']['country'], selectedActivity: determineActivityLevel( - double.parse(data['userDetails']['activity_coefficient'])), + data['userDetails']['activity_coefficient']), )); } } else { diff --git a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart index 77929fd5..0a387801 100644 --- a/lib/presentation/profile/my_profile_screen/my_profile_screen.dart +++ b/lib/presentation/profile/my_profile_screen/my_profile_screen.dart @@ -182,7 +182,7 @@ class MyProfileScreen extends StatelessWidget { switch (chartType) { case 1: // График веса return GestureDetector( - onTap: _editWeight(context, state), + onTap: () => _editWeight(context, state), child: Column(children: [ Text( "weight_chart".tr, @@ -225,7 +225,7 @@ class MyProfileScreen extends StatelessWidget { ]); case 3: //График обхватов return GestureDetector( - onTap: _editCircumference(context, state), + onTap: () => _editCircumference(context, state), child: Column(children: [ Text( "circumferences_chart".tr, @@ -279,10 +279,8 @@ class MyProfileScreen extends StatelessWidget { ); } - /// Section Widget _buildChart( BuildContext context, List chartPoints, List? dates) { -// Определение осей графика List spots = []; for (int i = 0; i < 4; i++) { spots.add( @@ -428,7 +426,7 @@ class MyProfileScreen extends StatelessWidget { }; } - mapSpots() { + List Function(List) mapSpots() { return (touchedSpots) { return touchedSpots.map((LineBarSpot touchedSpot) { final textStyle = TextStyle( @@ -635,7 +633,7 @@ class MyProfileScreen extends StatelessWidget { ); } - mapTouchedSpots() { + List Function(List) mapTouchedSpots() { return (touchedSpots) { return touchedSpots.map((LineBarSpot touchedSpot) { final textStyle = TextStyle( diff --git a/lib/presentation/registration/additional_information_screen/additional_information_screen.dart b/lib/presentation/registration/additional_information_screen/additional_information_screen.dart index 08ad6dd6..c1d7037b 100644 --- a/lib/presentation/registration/additional_information_screen/additional_information_screen.dart +++ b/lib/presentation/registration/additional_information_screen/additional_information_screen.dart @@ -76,16 +76,18 @@ class AdditionalInformationScreen extends StatelessWidget { UserRegistrationSheet sheet = state.additionalInformationModelObj!.userRegistrationSheet; sheet.additionalInfo = state.editTextController!.text; - //print(json.encode(sheet.toJson())); + final response = await http.post( - Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'), - headers: {'Content-Type': 'application/json'}, - body: jsonEncode(sheet.toJson()), - ); - print(response.statusCode); - print(response.body); + Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + body: jsonEncode(sheet.toJson()), + encoding: utf8); + + var res = await jsonDecode(response.body); if (response.statusCode == 200) { - var res = await jsonDecode(response.body); final box = await Hive.openBox('token'); final token = res['token']; box.put('token', token); @@ -93,6 +95,8 @@ class AdditionalInformationScreen extends StatelessWidget { context, AppRoutes.myProfile, ); + } else { + showErrorMessage(context, res['message']); } }; } @@ -118,7 +122,7 @@ class AdditionalInformationScreen extends StatelessWidget { /// Section Widget _buildTextFormField(BuildContext context) { return SizedBox( - height: 257.v, + height: 315.v, width: 343.h, child: Stack(alignment: Alignment.center, children: [ Align( @@ -139,7 +143,10 @@ class AdditionalInformationScreen extends StatelessWidget { builder: (context, editTextController) { return CustomTextFormField( controller: editTextController, - textInputAction: TextInputAction.done); + hintText: + "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни", + textInputAction: TextInputAction.done, + maxLines: 8); }) ])) ])); @@ -152,12 +159,12 @@ class AdditionalInformationScreen extends StatelessWidget { /// Displays an alert dialog when the action is triggered. /// The dialog box contains a title and a message with the `Теперь вы можете пользоваться полным функционалом приложения` - showSuccessMessage(BuildContext context, String text) { + showErrorMessage(BuildContext context, String text) { showDialog( context: context, builder: (_) => AlertDialog( - title: const Text('Регистрация завершена!'), - content: const Text('1'), + title: const Text('Ошибка'), + content: Text(text), actions: [ TextButton(onPressed: onTapOk(context), child: const Text('Ok')) ], diff --git a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_bloc.dart b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_bloc.dart index 0a4fa9fa..ce4073f3 100644 --- a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_bloc.dart +++ b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_bloc.dart @@ -10,7 +10,6 @@ class CityOfLivingBloc extends Bloc { CityOfLivingBloc(CityOfLivingState initialState) : super(initialState) { on(_onInitialize); on(_changeDropDown); - on(_changeDropDown1); } _onInitialize( @@ -19,8 +18,8 @@ class CityOfLivingBloc extends Bloc { ) async { emit(state.copyWith( cityOfLivingModelObj: state.cityOfLivingModelObj?.copyWith( - dropdownItemList: fillDropdownItemList(), - dropdownItemList1: fillDropdownItemList1()))); + dropdownItemList: fillDropdownItemList(), + ))); } _changeDropDown( @@ -32,50 +31,7 @@ class CityOfLivingBloc extends Bloc { event.value.title; } - _changeDropDown1( - ChangeDropDown1Event event, - Emitter emit, - ) { - emit(state.copyWith(selectedDropDownValue1: event.value)); - state.cityOfLivingModelObj?.userRegistrationSheet.city = event.value.title; - } - List fillDropdownItemList() { return [SelectionPopupModel(id: 1, title: "Россия", isSelected: true)]; } - - List fillDropdownItemList1() { - return [ - SelectionPopupModel(id: 1, title: "Москва", isSelected: true), - SelectionPopupModel(id: 2, title: "Санкт-Петербург"), - SelectionPopupModel(id: 3, title: "Новосибирск"), - SelectionPopupModel(id: 4, title: "Екатеринбург"), - SelectionPopupModel(id: 5, title: "Нижний Новгород"), - SelectionPopupModel(id: 6, title: "Казань"), - SelectionPopupModel(id: 7, title: "Самара"), - SelectionPopupModel(id: 8, title: "Омск"), - SelectionPopupModel(id: 9, title: "Челябинск"), - SelectionPopupModel(id: 10, title: "Ростов-на-Дону"), - SelectionPopupModel(id: 11, title: "Уфа"), - SelectionPopupModel(id: 12, title: "Волгоград"), - SelectionPopupModel(id: 13, title: "Пермь"), - SelectionPopupModel(id: 14, title: "Красноярск"), - SelectionPopupModel(id: 15, title: "Воронеж"), - SelectionPopupModel(id: 16, title: "Саратов"), - SelectionPopupModel(id: 17, title: "Краснодар"), - SelectionPopupModel(id: 18, title: "Тольятти"), - SelectionPopupModel(id: 19, title: "Барнаул"), - SelectionPopupModel(id: 20, title: "Ижевск"), - SelectionPopupModel(id: 21, title: "Ульяновск"), - SelectionPopupModel(id: 22, title: "Тюмень"), - SelectionPopupModel(id: 23, title: "Иркутск"), - SelectionPopupModel(id: 24, title: "Хабаровск"), - SelectionPopupModel(id: 25, title: "Ярославль"), - SelectionPopupModel(id: 26, title: "Кемерово"), - SelectionPopupModel(id: 27, title: "Магнитогорск"), - SelectionPopupModel(id: 28, title: "Новокузнецк"), - SelectionPopupModel(id: 29, title: "Томск"), - SelectionPopupModel(id: 30, title: "Астрахань") - ]; - } } diff --git a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_event.dart b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_event.dart index c12d13e3..d8418128 100644 --- a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_event.dart +++ b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_event.dart @@ -26,15 +26,3 @@ class ChangeDropDownEvent extends CityOfLivingEvent { value, ]; } - -///event for dropdown selection -class ChangeDropDown1Event extends CityOfLivingEvent { - ChangeDropDown1Event({required this.value}); - - SelectionPopupModel value; - - @override - List get props => [ - value, - ]; -} diff --git a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_state.dart b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_state.dart index b7967ccf..5179b21e 100644 --- a/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_state.dart +++ b/lib/presentation/registration/city_of_living_screen/bloc/city_of_living_state.dart @@ -6,20 +6,20 @@ part of 'city_of_living_bloc.dart'; class CityOfLivingState extends Equatable { CityOfLivingState({ this.selectedDropDownValue, - this.selectedDropDownValue1, + this.cityController, this.cityOfLivingModelObj, }); SelectionPopupModel? selectedDropDownValue; - SelectionPopupModel? selectedDropDownValue1; + TextEditingController? cityController; CityOfLivingModel? cityOfLivingModelObj; @override List get props => [ selectedDropDownValue, - selectedDropDownValue1, + cityController, cityOfLivingModelObj, ]; CityOfLivingState copyWith({ @@ -30,8 +30,7 @@ class CityOfLivingState extends Equatable { return CityOfLivingState( selectedDropDownValue: selectedDropDownValue ?? this.selectedDropDownValue, - selectedDropDownValue1: - selectedDropDownValue1 ?? this.selectedDropDownValue1, + cityController: cityController ?? this.cityController, cityOfLivingModelObj: cityOfLivingModelObj ?? this.cityOfLivingModelObj, ); } diff --git a/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart b/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart index eac52021..20ab28e8 100644 --- a/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart +++ b/lib/presentation/registration/city_of_living_screen/city_of_living_screen.dart @@ -6,6 +6,7 @@ import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; import 'package:eatvio_app/widgets/custom_drop_down.dart'; import 'package:eatvio_app/widgets/next_step_button.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; @@ -25,6 +26,1125 @@ class CityOfLivingScreen extends StatelessWidget { @override Widget build(BuildContext context) { + List _options = [ + "Абаза", + "Абакан", + "Абдулино", + "Абинск", + "Агидель", + "Агрыз", + "Адыгейск", + "Азнакаево", + "Азов", + "Ак-Довурак", + "Аксай", + "Алагир", + "Алапаевск", + "Алатырь", + "Алдан", + "Алейск", + "Александров", + "Александровск", + "Александровск-Сахалинский", + "Алексеевка", + "Алексин", + "Алзамай", + "АлупкаОспаривается", + "АлуштаОспаривается", + "Альметьевск", + "Амурск", + "Анадырь", + "Анапа", + "Ангарск", + "Андреаполь", + "Анжеро-Судженск", + "Анива", + "Апатиты", + "Апрелевка", + "Апшеронск", + "Арамиль", + "Аргун", + "Ардатов", + "Ардон", + "Арзамас", + "Аркадак", + "Армавир", + "АрмянскОспаривается", + "Арсеньев", + "Арск", + "Артём", + "Артёмовск", + "Артёмовский", + "Архангельск", + "Асбест", + "Асино", + "Астрахань", + "Аткарск", + "Ахтубинск", + "Ачинск", + "Аша", + "Бабаево", + "Бабушкин", + "Бавлы", + "Багратионовск", + "Байкальск", + "Баймак", + "Бакал", + "Баксан", + "Балабаново", + "Балаково", + "Балахна", + "Балашиха", + "Балашов", + "Балей", + "Балтийск", + "Барабинск", + "Барнаул", + "Барыш", + "Батайск", + "БахчисарайОспаривается", + "Бежецк", + "Белая Калитва", + "Белая Холуница", + "Белгород", + "Белебей", + "Белёв", + "Белинский", + "Белово", + "Белогорск", + "БелогорскОспаривается", + "Белозерск", + "Белокуриха", + "Беломорск", + "Белоозёрский", + "Белорецк", + "Белореченск", + "Белоусово", + "Белоярский", + "Белый", + "Бердск", + "Березники", + "Берёзовский", + "Берёзовский", + "Беслан", + "Бийск", + "Бикин", + "Билибино", + "Биробиджан", + "Бирск", + "Бирюсинск", + "Бирюч", + "Благовещенск", + "Благовещенск", + "Благодарный", + "Бобров", + "Богданович", + "Богородицк", + "Богородск", + "Боготол", + "Богучар", + "Бодайбо", + "Бокситогорск", + "Болгар", + "Бологое", + "Болотное", + "Болохово", + "Болхов", + "Большой Камень", + "Бор", + "Борзя", + "Борисоглебск", + "Боровичи", + "Боровск", + "Бородино", + "Братск", + "Бронницы", + "Брянск", + "Бугульма", + "Бугуруслан", + "Будённовск", + "Бузулук", + "Буинск", + "Буй", + "Буйнакск", + "Бутурлиновка", + "Валдай", + "Валуйки", + "Велиж", + "Великие Луки", + "Великий Новгород", + "Великий Устюг", + "Вельск", + "Венёв", + "Верещагино", + "Верея", + "Верхнеуральск", + "Верхний Тагил", + "Верхний Уфалей", + "Верхняя Пышма", + "Верхняя Салда", + "Верхняя Тура", + "Верхотурье", + "Верхоянск", + "Весьегонск", + "Ветлуга", + "Видное", + "Вилюйск", + "Вилючинск", + "Вихоревка", + "Вичуга", + "Владивосток", + "Владикавказ", + "Владимир", + "Волгоград", + "Волгодонск", + "Волгореченск", + "Волжск", + "Волжский", + "Вологда", + "Володарск", + "Волоколамск", + "Волосово", + "Волхов", + "Волчанск", + "Вольск", + "Воркута", + "Воронеж", + "Ворсма", + "Воскресенск", + "Воткинск", + "Всеволожск", + "Вуктыл", + "Выборг", + "Выкса", + "Высоковск", + "Высоцк", + "Вытегра", + "Вышний Волочёк", + "Вяземский", + "Вязники", + "Вязьма", + "Вятские Поляны", + "Гаврилов Посад", + "Гаврилов-Ям", + "Гагарин", + "Гаджиево", + "Гай", + "Галич", + "Гатчина", + "Гвардейск", + "Гдов", + "Геленджик", + "Георгиевск", + "Глазов", + "Голицыно", + "Горбатов", + "Горно-Алтайск", + "Горнозаводск", + "Горняк", + "Городец", + "Городище", + "Городовиковск", + "Гороховец", + "Горячий Ключ", + "Грайворон", + "Гремячинск", + "Грозный", + "Грязи", + "Грязовец", + "Губаха", + "Губкин", + "Губкинский", + "Гудермес", + "Гуково", + "Гулькевичи", + "Гурьевск", + "Гурьевск", + "Гусев", + "Гусиноозёрск", + "Гусь-Хрустальный", + "Давлеканово", + "Дагестанские Огни", + "Далматово", + "Дальнегорск", + "Дальнереченск", + "Данилов", + "Данков", + "Дегтярск", + "Дедовск", + "Демидов", + "Дербент", + "Десногорск", + "ДжанкойОспаривается", + "Дзержинск", + "Дзержинский", + "Дивногорск", + "Дигора", + "Димитровград", + "Дмитриев", + "Дмитров", + "Дмитровск", + "Дно", + "Добрянка", + "Долгопрудный", + "Долинск", + "Домодедово", + "Донецк", + "Донской", + "Дорогобуж", + "Дрезна", + "Дубна", + "Дубовка", + "Дудинка", + "Духовщина", + "Дюртюли", + "Дятьково", + "ЕвпаторияОспаривается", + "Егорьевск", + "Ейск", + "Екатеринбург", + "Елабуга", + "Елец", + "Елизово", + "Ельня", + "Еманжелинск", + "Емва", + "Енисейск", + "Ермолино", + "Ершов", + "Ессентуки", + "Ефремов", + "Железноводск", + "Железногорск", + "Железногорск", + "Железногорск-Илимский", + "Жердевка", + "Жигулёвск", + "Жиздра", + "Жирновск", + "Жуков", + "Жуковка", + "Жуковский", + "Завитинск", + "Заводоуковск", + "Заволжск", + "Заволжье", + "Задонск", + "Заинск", + "Закаменск", + "Заозёрный", + "Заозёрск", + "Западная Двина", + "Заполярный", + "Зарайск", + "Заречный", + "Заречный", + "Заринск", + "Звенигово", + "Звенигород", + "Зверево", + "Зеленогорск", + "Зеленоградск", + "Зеленодольск", + "Зеленокумск", + "Зерноград", + "Зея", + "Зима", + "Златоуст", + "Злынка", + "Змеиногорск", + "Знаменск", + "Зубцов", + "Зуевка", + "Ивангород", + "Иваново", + "Ивантеевка", + "Ивдель", + "Игарка", + "Ижевск", + "Избербаш", + "Изобильный", + "Иланский", + "Инза", + "Иннополис", + "Инсар", + "Инта", + "Ипатово", + "Ирбит", + "Иркутск", + "Исилькуль", + "Искитим", + "Истра", + "Ишим", + "Ишимбай", + "Йошкар-Ола", + "Кадников", + "Казань", + "Калач", + "Калач-на-Дону", + "Калачинск", + "Калининград", + "Калининск", + "Калтан", + "Калуга", + "Калязин", + "Камбарка", + "Каменка", + "Каменногорск", + "Каменск-Уральский", + "Каменск-Шахтинский", + "Камень-на-Оби", + "Камешково", + "Камызяк", + "Камышин", + "Камышлов", + "Канаш", + "Кандалакша", + "Канск", + "Карабаново", + "Карабаш", + "Карабулак", + "Карасук", + "Карачаевск", + "Карачев", + "Каргат", + "Каргополь", + "Карпинск", + "Карталы", + "Касимов", + "Касли", + "Каспийск", + "Катав-Ивановск", + "Катайск", + "Качканар", + "Кашин", + "Кашира", + "Кедровый", + "Кемерово", + "Кемь", + "КерчьОспаривается", + "Кизел", + "Кизилюрт", + "Кизляр", + "Кимовск", + "Кимры", + "Кингисепп", + "Кинель", + "Кинешма", + "Киреевск", + "Киренск", + "Киржач", + "Кириллов", + "Кириши", + "Киров", + "Киров", + "Кировград", + "Кирово-Чепецк", + "Кировск", + "Кировск", + "Кирс", + "Кирсанов", + "Киселёвск", + "Кисловодск", + "Клин", + "Клинцы", + "Княгинино", + "Ковдор", + "Ковров", + "Ковылкино", + "Когалым", + "Кодинск", + "Козельск", + "Козловка", + "Козьмодемьянск", + "Кола", + "Кологрив", + "Коломна", + "Колпашево", + "Кольчугино", + "Коммунар", + "Комсомольск", + "Комсомольск-на-Амуре", + "Конаково", + "Кондопога", + "Кондрово", + "Константиновск", + "Копейск", + "Кораблино", + "Кореновск", + "Коркино", + "Королёв", + "Короча", + "Корсаков", + "Коряжма", + "Костерёво", + "Костомукша", + "Кострома", + "Котельники", + "Котельниково", + "Котельнич", + "Котлас", + "Котово", + "Котовск", + "Кохма", + "Красавино", + "Красноармейск", + "Красноармейск", + "Красновишерск", + "Красногорск", + "Краснодар", + "Краснозаводск", + "Краснознаменск", + "Краснознаменск", + "Краснокаменск", + "Краснокамск", + "КрасноперекопскОспаривается", + "Краснослободск", + "Краснослободск", + "Краснотурьинск", + "Красноуральск", + "Красноуфимск", + "Красноярск", + "Красный Кут", + "Красный Сулин", + "Красный Холм", + "Кремёнки", + "Кропоткин", + "Крымск", + "Кстово", + "Кубинка", + "Кувандык", + "Кувшиново", + "Кудрово", + "Кудымкар", + "Кузнецк", + "Куйбышев", + "Кукмор", + "Кулебаки", + "Кумертау", + "Кунгур", + "Купино", + "Курган", + "Курганинск", + "Курильск", + "Курлово", + "Куровское", + "Курск", + "Куртамыш", + "Курчалой", + "Курчатов", + "Куса", + "Кушва", + "Кызыл", + "Кыштым", + "Кяхта", + "Лабинск", + "Лабытнанги", + "Лагань", + "Ладушкин", + "Лаишево", + "Лакинск", + "Лангепас", + "Лахденпохья", + "Лебедянь", + "Лениногорск", + "Ленинск", + "Ленинск-Кузнецкий", + "Ленск", + "Лермонтов", + "Лесной", + "Лесозаводск", + "Лесосибирск", + "Ливны", + "Ликино-Дулёво", + "Липецк", + "Липки", + "Лиски", + "Лихославль", + "Лобня", + "Лодейное Поле", + "Лосино-Петровский", + "Луга", + "Луза", + "Лукоянов", + "Луховицы", + "Лысково", + "Лысьва", + "Лыткарино", + "Льгов", + "Любань", + "Люберцы", + "Любим", + "Людиново", + "Лянтор", + "Магадан", + "Магас", + "Магнитогорск", + "Майкоп", + "Майский", + "Макаров", + "Макарьев", + "Макушино", + "Малая Вишера", + "Малгобек", + "Малмыж", + "Малоархангельск", + "Малоярославец", + "Мамадыш", + "Мамоново", + "Мантурово", + "Мариинск", + "Мариинский Посад", + "Маркс", + "Махачкала", + "Мглин", + "Мегион", + "Медвежьегорск", + "Медногорск", + "Медынь", + "Межгорье", + "Междуреченск", + "Мезень", + "Меленки", + "Мелеуз", + "Менделеевск", + "Мензелинск", + "Мещовск", + "Миасс", + "Микунь", + "Миллерово", + "Минеральные Воды", + "Минусинск", + "Миньяр", + "Мирный", + "Мирный", + "Михайлов", + "Михайловка", + "Михайловск", + "Михайловск", + "Мичуринск", + "Могоча", + "Можайск", + "Можга", + "Моздок", + "Мончегорск", + "Морозовск", + "Моршанск", + "Мосальск", + "Москва", + "Муравленко", + "Мураши", + "Мурино", + "Мурманск", + "Муром", + "Мценск", + "Мыски", + "Мытищи", + "Мышкин", + "Набережные Челны", + "Навашино", + "Наволоки", + "Надым", + "Назарово", + "Назрань", + "Называевск", + "Нальчик", + "Нариманов", + "Наро-Фоминск", + "Нарткала", + "Нарьян-Мар", + "Находка", + "Невель", + "Невельск", + "Невинномысск", + "Невьянск", + "Нелидово", + "Неман", + "Нерехта", + "Нерчинск", + "Нерюнгри", + "Нестеров", + "Нефтегорск", + "Нефтекамск", + "Нефтекумск", + "Нефтеюганск", + "Нея", + "Нижневартовск", + "Нижнекамск", + "Нижнеудинск", + "Нижние Серги", + "Нижний Ломов", + "Нижний Новгород", + "Нижний Тагил", + "Нижняя Салда", + "Нижняя Тура", + "Николаевск", + "Николаевск-на-Амуре", + "Никольск", + "Никольск", + "Никольское", + "Новая Ладога", + "Новая Ляля", + "Новоалександровск", + "Новоалтайск", + "Новоаннинский", + "Нововоронеж", + "Новодвинск", + "Новозыбков", + "Новокубанск", + "Новокузнецк", + "Новокуйбышевск", + "Новомичуринск", + "Новомосковск", + "Новопавловск", + "Новоржев", + "Новороссийск", + "Новосибирск", + "Новосиль", + "Новосокольники", + "Новотроицк", + "Новоузенск", + "Новоульяновск", + "Новоуральск", + "Новохопёрск", + "Новочебоксарск", + "Новочеркасск", + "Новошахтинск", + "Новый Оскол", + "Новый Уренгой", + "Ногинск", + "Нолинск", + "Норильск", + "Ноябрьск", + "Нурлат", + "Нытва", + "Нюрба", + "Нягань", + "Нязепетровск", + "Няндома", + "Облучье", + "Обнинск", + "Обоянь", + "Обь", + "Одинцово", + "Озёрск", + "Озёрск", + "Озёры", + "Октябрьск", + "Октябрьский", + "Окуловка", + "Олёкминск", + "Оленегорск", + "Олонец", + "Омск", + "Омутнинск", + "Онега", + "Опочка", + "Орёл", + "Оренбург", + "Орехово-Зуево", + "Орлов", + "Орск", + "Оса", + "Осинники", + "Осташков", + "Остров", + "Островной", + "Острогожск", + "Отрадное", + "Отрадный", + "Оха", + "Оханск", + "Очёр", + "Павлово", + "Павловск", + "Павловский Посад", + "Палласовка", + "Партизанск", + "Певек", + "Пенза", + "Первомайск", + "Первоуральск", + "Перевоз", + "Пересвет", + "Переславль-Залесский", + "Пермь", + "Пестово", + "Петров Вал", + "Петровск", + "Петровск-Забайкальский", + "Петрозаводск", + "Петропавловск-Камчатский", + "Петухово", + "Петушки", + "Печора", + "Печоры", + "Пикалёво", + "Пионерский", + "Питкяранта", + "Плавск", + "Пласт", + "Плёс", + "Поворино", + "Подольск", + "Подпорожье", + "Покачи", + "Покров", + "Покровск", + "Полевской", + "Полесск", + "Полысаево", + "Полярные Зори", + "Полярный", + "Поронайск", + "Порхов", + "Похвистнево", + "Почеп", + "Починок", + "Пошехонье", + "Правдинск", + "Приволжск", + "Приморск", + "Приморск", + "Приморско-Ахтарск", + "Приозерск", + "Прокопьевск", + "Пролетарск", + "Протвино", + "Прохладный", + "Псков", + "Пугачёв", + "Пудож", + "Пустошка", + "Пучеж", + "Пушкино", + "Пущино", + "Пыталово", + "Пыть-Ях", + "Пятигорск", + "Радужный", + "Радужный", + "Райчихинск", + "Раменское", + "Рассказово", + "Ревда", + "Реж", + "Реутов", + "Ржев", + "Родники", + "Рославль", + "Россошь", + "Ростов-на-Дону", + "Ростов", + "Рошаль", + "Ртищево", + "Рубцовск", + "Рудня", + "Руза", + "Рузаевка", + "Рыбинск", + "Рыбное", + "Рыльск", + "Ряжск", + "Рязань", + "СакиОспаривается", + "Салават", + "Салаир", + "Салехард", + "Сальск", + "Самара", + "Санкт-Петербург", + "Саранск", + "Сарапул", + "Саратов", + "Саров", + "Сасово", + "Сатка", + "Сафоново", + "Саяногорск", + "Саянск", + "Светлогорск", + "Светлоград", + "Светлый", + "Светогорск", + "Свирск", + "Свободный", + "Себеж", + "СевастопольОспаривается", + "Северо-Курильск", + "Северобайкальск", + "Северодвинск", + "Североморск", + "Североуральск", + "Северск", + "Севск", + "Сегежа", + "Сельцо", + "Семёнов", + "Семикаракорск", + "Семилуки", + "Сенгилей", + "Серафимович", + "Сергач", + "Сергиев Посад", + "Сердобск", + "Серов", + "Серпухов", + "Сертолово", + "Сибай", + "Сим", + "СимферопольОспаривается", + "Сковородино", + "Скопин", + "Славгород", + "Славск", + "Славянск-на-Кубани", + "Сланцы", + "Слободской", + "Слюдянка", + "Смоленск", + "Снежинск", + "Снежногорск", + "Собинка", + "Советск", + "Советск", + "Советск", + "Советская Гавань", + "Советский", + "Сокол", + "Солигалич", + "Соликамск", + "Солнечногорск", + "Соль-Илецк", + "Сольвычегодск", + "Сольцы", + "Сорочинск", + "Сорск", + "Сортавала", + "Сосенский", + "Сосновка", + "Сосновоборск", + "Сосновый Бор", + "Сосногорск", + "Сочи", + "Спас-Деменск", + "Спас-Клепики", + "Спасск", + "Спасск-Дальний", + "Спасск-Рязанский", + "Среднеколымск", + "Среднеуральск", + "Сретенск", + "Ставрополь", + "Старая Купавна", + "Старая Русса", + "Старица", + "Стародуб", + "Старый КрымОспаривается", + "Старый Оскол", + "Стерлитамак", + "Стрежевой", + "Строитель", + "Струнино", + "Ступино", + "Суворов", + "СудакОспаривается", + "Суджа", + "Судогда", + "Суздаль", + "Сунжа", + "Суоярви", + "Сураж", + "Сургут", + "Суровикино", + "Сурск", + "Сусуман", + "Сухиничи", + "Сухой Лог", + "Сызрань", + "Сыктывкар", + "Сысерть", + "Сычёвка", + "Сясьстрой", + "Тавда", + "Таганрог", + "Тайга", + "Тайшет", + "Талдом", + "Талица", + "Тамбов", + "Тара", + "Тарко-Сале", + "Таруса", + "Татарск", + "Таштагол", + "Тверь", + "Теберда", + "Тейково", + "Темников", + "Темрюк", + "Терек", + "Тетюши", + "Тимашёвск", + "Тихвин", + "Тихорецк", + "Тобольск", + "Тогучин", + "Тольятти", + "Томари", + "Томмот", + "Томск", + "Топки", + "Торжок", + "Торопец", + "Тосно", + "Тотьма", + "Трёхгорный", + "Троицк", + "Трубчевск", + "Туапсе", + "Туймазы", + "Тула", + "Тулун", + "Туран", + "Туринск", + "Тутаев", + "Тында", + "Тырныауз", + "Тюкалинск", + "Тюмень", + "Уварово", + "Углегорск", + "Углич", + "Удачный", + "Удомля", + "Ужур", + "Узловая", + "Улан-Удэ", + "Ульяновск", + "Унеча", + "Урай", + "Урень", + "Уржум", + "Урус-Мартан", + "Урюпинск", + "Усинск", + "Усмань", + "Усолье-Сибирское", + "Усолье", + "Уссурийск", + "Усть-Джегута", + "Усть-Илимск", + "Усть-Катав", + "Усть-Кут", + "Усть-Лабинск", + "Устюжна", + "Уфа", + "Ухта", + "Учалы", + "Уяр", + "Фатеж", + "ФеодосияОспаривается", + "Фокино", + "Фокино", + "Фролово", + "Фрязино", + "Фурманов", + "Хабаровск", + "Хадыженск", + "Ханты-Мансийск", + "Харабали", + "Харовск", + "Хасавюрт", + "Хвалынск", + "Хилок", + "Химки", + "Холм", + "Холмск", + "Хотьково", + "Цивильск", + "Цимлянск", + "Циолковский", + "Чадан", + "Чайковский", + "Чапаевск", + "Чаплыгин", + "Чебаркуль", + "Чебоксары", + "Чегем", + "Чекалин", + "Челябинск", + "Чердынь", + "Черемхово", + "Черепаново", + "Череповец", + "Черкесск", + "Чёрмоз", + "Черноголовка", + "Черногорск", + "Чернушка", + "Черняховск", + "Чехов", + "Чистополь", + "Чита", + "Чкаловск", + "Чудово", + "Чулым", + "Чусовой", + "Чухлома", + "Шагонар", + "Шадринск", + "Шали", + "Шарыпово", + "Шарья", + "Шатура", + "Шахты", + "Шахунья", + "Шацк", + "Шебекино", + "Шелехов", + "Шенкурск", + "Шилка", + "Шимановск", + "Шиханы", + "Шлиссельбург", + "Шумерля", + "Шумиха", + "Шуя", + "Щёкино", + "ЩёлкиноОспаривается", + "Щёлково", + "Щигры", + "Щучье", + "Электрогорск", + "Электросталь", + "Электроугли", + "Элиста", + "Энгельс", + "Эртиль", + "Югорск", + "Южа", + "Южно-Сахалинск", + "Южно-Сухокумск", + "Южноуральск", + "Юрга", + "Юрьев-Польский", + "Юрьевец", + "Юрюзань", + "Юхнов", + "Ядрин", + "Якутск", + "ЯлтаОспаривается", + "Ялуторовск", + "Янаул", + "Яранск", + "Яровое", + "Ярославль", + "Ярцево", + "Ясногорск", + "Ясный", + "Яхрома" + ]; mediaQueryData = MediaQuery.of(context); return SafeArea( child: Scaffold( @@ -74,27 +1194,61 @@ class CityOfLivingScreen extends StatelessWidget { onChanged: onDropDownChange(context)); }), SizedBox(height: 22.v), - Text("city".tr, style: theme.textTheme.bodyLarge), + Text("Населенный пункт", style: theme.textTheme.bodyLarge), SizedBox(height: 2.v), - BlocSelector( - selector: (state) => state.cityOfLivingModelObj, - builder: (context, cityOfLivingModelObj) { - return CustomDropDown( - icon: Container( - margin: - EdgeInsets.fromLTRB(30.h, 11.v, 17.h, 11.v), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(1.h)), - child: CustomImageView( - imagePath: ImageConstant.imgFavorite, - height: 12.adaptSize, - width: 12.adaptSize)), - hintText: "Не выбрано".tr, - items: - cityOfLivingModelObj?.dropdownItemList1 ?? [], - onChanged: onDropDownChangeCity(context)); + BlocBuilder( + builder: (context, state) { + return RawAutocomplete( + optionsBuilder: (TextEditingValue textEditingValue) => + _options.where((String option) { + return option + .toLowerCase() + .startsWith(textEditingValue.text.toLowerCase()); }), + fieldViewBuilder: ( + BuildContext context, + TextEditingController textEditingController, + FocusNode focusNode, + VoidCallback onFieldSubmitted, + ) { + return CustomTextFormField( + controller: textEditingController, + focusNode: focusNode, + onFieldSubmitted: (String value) => + onFieldSubmitted(), + ); + }, + optionsViewBuilder: ( + BuildContext context, + AutocompleteOnSelected onSelected, + Iterable options, + ) { + return Align( + alignment: Alignment.topLeft, + child: Material( + elevation: 4.0, + child: SizedBox( + height: 200.0, + child: ListView.builder( + padding: const EdgeInsets.all(8.0), + itemCount: options.length, + itemBuilder: (BuildContext context, int index) { + final String option = + options.elementAt(index); + return GestureDetector( + onTap: () => onSelected(option), + child: ListTile( + title: Text(option), + ), + ); + }, + ), + ), + ), + ); + }, + ); + }), Spacer(flex: 65), BlocBuilder( builder: (context, state) { @@ -120,12 +1274,6 @@ class CityOfLivingScreen extends StatelessWidget { }; } - onDropDownChangeCity(BuildContext context) { - return (value) { - context.read().add(ChangeDropDown1Event(value: value)); - }; - } - onDropDownChange(BuildContext context) { return (value) { context.read().add(ChangeDropDownEvent(value: value)); @@ -155,3 +1303,19 @@ class CityOfLivingScreen extends StatelessWidget { NavigatorService.goBack(); } } + +selectProduct(AutocompleteOnSelected onSelected, String option, + CityOfLivingState state) { + state.cityController?.text = option; + return () { + onSelected(option); + }; +} + +buildOptions(List _options) { + return (TextEditingValue textEditingValue) { + return _options.where((String option) { + return true; + }); + }; +} diff --git a/lib/presentation/registration/city_of_living_screen/models/city_of_living_model.dart b/lib/presentation/registration/city_of_living_screen/models/city_of_living_model.dart index 048621df..10366f3d 100644 --- a/lib/presentation/registration/city_of_living_screen/models/city_of_living_model.dart +++ b/lib/presentation/registration/city_of_living_screen/models/city_of_living_model.dart @@ -11,12 +11,1130 @@ class CityOfLivingModel extends Equatable { CityOfLivingModel({ required this.userRegistrationSheet, this.dropdownItemList = const [], - this.dropdownItemList1 = const [], + this.cityList = const [ + "Абаза", + "Абакан", + "Абдулино", + "Абинск", + "Агидель", + "Агрыз", + "Адыгейск", + "Азнакаево", + "Азов", + "Ак-Довурак", + "Аксай", + "Алагир", + "Алапаевск", + "Алатырь", + "Алдан", + "Алейск", + "Александров", + "Александровск", + "Александровск-Сахалинский", + "Алексеевка", + "Алексин", + "Алзамай", + "АлупкаОспаривается", + "АлуштаОспаривается", + "Альметьевск", + "Амурск", + "Анадырь", + "Анапа", + "Ангарск", + "Андреаполь", + "Анжеро-Судженск", + "Анива", + "Апатиты", + "Апрелевка", + "Апшеронск", + "Арамиль", + "Аргун", + "Ардатов", + "Ардон", + "Арзамас", + "Аркадак", + "Армавир", + "АрмянскОспаривается", + "Арсеньев", + "Арск", + "Артём", + "Артёмовск", + "Артёмовский", + "Архангельск", + "Асбест", + "Асино", + "Астрахань", + "Аткарск", + "Ахтубинск", + "Ачинск", + "Аша", + "Бабаево", + "Бабушкин", + "Бавлы", + "Багратионовск", + "Байкальск", + "Баймак", + "Бакал", + "Баксан", + "Балабаново", + "Балаково", + "Балахна", + "Балашиха", + "Балашов", + "Балей", + "Балтийск", + "Барабинск", + "Барнаул", + "Барыш", + "Батайск", + "БахчисарайОспаривается", + "Бежецк", + "Белая Калитва", + "Белая Холуница", + "Белгород", + "Белебей", + "Белёв", + "Белинский", + "Белово", + "Белогорск", + "БелогорскОспаривается", + "Белозерск", + "Белокуриха", + "Беломорск", + "Белоозёрский", + "Белорецк", + "Белореченск", + "Белоусово", + "Белоярский", + "Белый", + "Бердск", + "Березники", + "Берёзовский", + "Берёзовский", + "Беслан", + "Бийск", + "Бикин", + "Билибино", + "Биробиджан", + "Бирск", + "Бирюсинск", + "Бирюч", + "Благовещенск", + "Благовещенск", + "Благодарный", + "Бобров", + "Богданович", + "Богородицк", + "Богородск", + "Боготол", + "Богучар", + "Бодайбо", + "Бокситогорск", + "Болгар", + "Бологое", + "Болотное", + "Болохово", + "Болхов", + "Большой Камень", + "Бор", + "Борзя", + "Борисоглебск", + "Боровичи", + "Боровск", + "Бородино", + "Братск", + "Бронницы", + "Брянск", + "Бугульма", + "Бугуруслан", + "Будённовск", + "Бузулук", + "Буинск", + "Буй", + "Буйнакск", + "Бутурлиновка", + "Валдай", + "Валуйки", + "Велиж", + "Великие Луки", + "Великий Новгород", + "Великий Устюг", + "Вельск", + "Венёв", + "Верещагино", + "Верея", + "Верхнеуральск", + "Верхний Тагил", + "Верхний Уфалей", + "Верхняя Пышма", + "Верхняя Салда", + "Верхняя Тура", + "Верхотурье", + "Верхоянск", + "Весьегонск", + "Ветлуга", + "Видное", + "Вилюйск", + "Вилючинск", + "Вихоревка", + "Вичуга", + "Владивосток", + "Владикавказ", + "Владимир", + "Волгоград", + "Волгодонск", + "Волгореченск", + "Волжск", + "Волжский", + "Вологда", + "Володарск", + "Волоколамск", + "Волосово", + "Волхов", + "Волчанск", + "Вольск", + "Воркута", + "Воронеж", + "Ворсма", + "Воскресенск", + "Воткинск", + "Всеволожск", + "Вуктыл", + "Выборг", + "Выкса", + "Высоковск", + "Высоцк", + "Вытегра", + "Вышний Волочёк", + "Вяземский", + "Вязники", + "Вязьма", + "Вятские Поляны", + "Гаврилов Посад", + "Гаврилов-Ям", + "Гагарин", + "Гаджиево", + "Гай", + "Галич", + "Гатчина", + "Гвардейск", + "Гдов", + "Геленджик", + "Георгиевск", + "Глазов", + "Голицыно", + "Горбатов", + "Горно-Алтайск", + "Горнозаводск", + "Горняк", + "Городец", + "Городище", + "Городовиковск", + "Гороховец", + "Горячий Ключ", + "Грайворон", + "Гремячинск", + "Грозный", + "Грязи", + "Грязовец", + "Губаха", + "Губкин", + "Губкинский", + "Гудермес", + "Гуково", + "Гулькевичи", + "Гурьевск", + "Гурьевск", + "Гусев", + "Гусиноозёрск", + "Гусь-Хрустальный", + "Давлеканово", + "Дагестанские Огни", + "Далматово", + "Дальнегорск", + "Дальнереченск", + "Данилов", + "Данков", + "Дегтярск", + "Дедовск", + "Демидов", + "Дербент", + "Десногорск", + "ДжанкойОспаривается", + "Дзержинск", + "Дзержинский", + "Дивногорск", + "Дигора", + "Димитровград", + "Дмитриев", + "Дмитров", + "Дмитровск", + "Дно", + "Добрянка", + "Долгопрудный", + "Долинск", + "Домодедово", + "Донецк", + "Донской", + "Дорогобуж", + "Дрезна", + "Дубна", + "Дубовка", + "Дудинка", + "Духовщина", + "Дюртюли", + "Дятьково", + "ЕвпаторияОспаривается", + "Егорьевск", + "Ейск", + "Екатеринбург", + "Елабуга", + "Елец", + "Елизово", + "Ельня", + "Еманжелинск", + "Емва", + "Енисейск", + "Ермолино", + "Ершов", + "Ессентуки", + "Ефремов", + "Железноводск", + "Железногорск", + "Железногорск", + "Железногорск-Илимский", + "Жердевка", + "Жигулёвск", + "Жиздра", + "Жирновск", + "Жуков", + "Жуковка", + "Жуковский", + "Завитинск", + "Заводоуковск", + "Заволжск", + "Заволжье", + "Задонск", + "Заинск", + "Закаменск", + "Заозёрный", + "Заозёрск", + "Западная Двина", + "Заполярный", + "Зарайск", + "Заречный", + "Заречный", + "Заринск", + "Звенигово", + "Звенигород", + "Зверево", + "Зеленогорск", + "Зеленоградск", + "Зеленодольск", + "Зеленокумск", + "Зерноград", + "Зея", + "Зима", + "Златоуст", + "Злынка", + "Змеиногорск", + "Знаменск", + "Зубцов", + "Зуевка", + "Ивангород", + "Иваново", + "Ивантеевка", + "Ивдель", + "Игарка", + "Ижевск", + "Избербаш", + "Изобильный", + "Иланский", + "Инза", + "Иннополис", + "Инсар", + "Инта", + "Ипатово", + "Ирбит", + "Иркутск", + "Исилькуль", + "Искитим", + "Истра", + "Ишим", + "Ишимбай", + "Йошкар-Ола", + "Кадников", + "Казань", + "Калач", + "Калач-на-Дону", + "Калачинск", + "Калининград", + "Калининск", + "Калтан", + "Калуга", + "Калязин", + "Камбарка", + "Каменка", + "Каменногорск", + "Каменск-Уральский", + "Каменск-Шахтинский", + "Камень-на-Оби", + "Камешково", + "Камызяк", + "Камышин", + "Камышлов", + "Канаш", + "Кандалакша", + "Канск", + "Карабаново", + "Карабаш", + "Карабулак", + "Карасук", + "Карачаевск", + "Карачев", + "Каргат", + "Каргополь", + "Карпинск", + "Карталы", + "Касимов", + "Касли", + "Каспийск", + "Катав-Ивановск", + "Катайск", + "Качканар", + "Кашин", + "Кашира", + "Кедровый", + "Кемерово", + "Кемь", + "КерчьОспаривается", + "Кизел", + "Кизилюрт", + "Кизляр", + "Кимовск", + "Кимры", + "Кингисепп", + "Кинель", + "Кинешма", + "Киреевск", + "Киренск", + "Киржач", + "Кириллов", + "Кириши", + "Киров", + "Киров", + "Кировград", + "Кирово-Чепецк", + "Кировск", + "Кировск", + "Кирс", + "Кирсанов", + "Киселёвск", + "Кисловодск", + "Клин", + "Клинцы", + "Княгинино", + "Ковдор", + "Ковров", + "Ковылкино", + "Когалым", + "Кодинск", + "Козельск", + "Козловка", + "Козьмодемьянск", + "Кола", + "Кологрив", + "Коломна", + "Колпашево", + "Кольчугино", + "Коммунар", + "Комсомольск", + "Комсомольск-на-Амуре", + "Конаково", + "Кондопога", + "Кондрово", + "Константиновск", + "Копейск", + "Кораблино", + "Кореновск", + "Коркино", + "Королёв", + "Короча", + "Корсаков", + "Коряжма", + "Костерёво", + "Костомукша", + "Кострома", + "Котельники", + "Котельниково", + "Котельнич", + "Котлас", + "Котово", + "Котовск", + "Кохма", + "Красавино", + "Красноармейск", + "Красноармейск", + "Красновишерск", + "Красногорск", + "Краснодар", + "Краснозаводск", + "Краснознаменск", + "Краснознаменск", + "Краснокаменск", + "Краснокамск", + "КрасноперекопскОспаривается", + "Краснослободск", + "Краснослободск", + "Краснотурьинск", + "Красноуральск", + "Красноуфимск", + "Красноярск", + "Красный Кут", + "Красный Сулин", + "Красный Холм", + "Кремёнки", + "Кропоткин", + "Крымск", + "Кстово", + "Кубинка", + "Кувандык", + "Кувшиново", + "Кудрово", + "Кудымкар", + "Кузнецк", + "Куйбышев", + "Кукмор", + "Кулебаки", + "Кумертау", + "Кунгур", + "Купино", + "Курган", + "Курганинск", + "Курильск", + "Курлово", + "Куровское", + "Курск", + "Куртамыш", + "Курчалой", + "Курчатов", + "Куса", + "Кушва", + "Кызыл", + "Кыштым", + "Кяхта", + "Лабинск", + "Лабытнанги", + "Лагань", + "Ладушкин", + "Лаишево", + "Лакинск", + "Лангепас", + "Лахденпохья", + "Лебедянь", + "Лениногорск", + "Ленинск", + "Ленинск-Кузнецкий", + "Ленск", + "Лермонтов", + "Лесной", + "Лесозаводск", + "Лесосибирск", + "Ливны", + "Ликино-Дулёво", + "Липецк", + "Липки", + "Лиски", + "Лихославль", + "Лобня", + "Лодейное Поле", + "Лосино-Петровский", + "Луга", + "Луза", + "Лукоянов", + "Луховицы", + "Лысково", + "Лысьва", + "Лыткарино", + "Льгов", + "Любань", + "Люберцы", + "Любим", + "Людиново", + "Лянтор", + "Магадан", + "Магас", + "Магнитогорск", + "Майкоп", + "Майский", + "Макаров", + "Макарьев", + "Макушино", + "Малая Вишера", + "Малгобек", + "Малмыж", + "Малоархангельск", + "Малоярославец", + "Мамадыш", + "Мамоново", + "Мантурово", + "Мариинск", + "Мариинский Посад", + "Маркс", + "Махачкала", + "Мглин", + "Мегион", + "Медвежьегорск", + "Медногорск", + "Медынь", + "Межгорье", + "Междуреченск", + "Мезень", + "Меленки", + "Мелеуз", + "Менделеевск", + "Мензелинск", + "Мещовск", + "Миасс", + "Микунь", + "Миллерово", + "Минеральные Воды", + "Минусинск", + "Миньяр", + "Мирный", + "Мирный", + "Михайлов", + "Михайловка", + "Михайловск", + "Михайловск", + "Мичуринск", + "Могоча", + "Можайск", + "Можга", + "Моздок", + "Мончегорск", + "Морозовск", + "Моршанск", + "Мосальск", + "Москва", + "Муравленко", + "Мураши", + "Мурино", + "Мурманск", + "Муром", + "Мценск", + "Мыски", + "Мытищи", + "Мышкин", + "Набережные Челны", + "Навашино", + "Наволоки", + "Надым", + "Назарово", + "Назрань", + "Называевск", + "Нальчик", + "Нариманов", + "Наро-Фоминск", + "Нарткала", + "Нарьян-Мар", + "Находка", + "Невель", + "Невельск", + "Невинномысск", + "Невьянск", + "Нелидово", + "Неман", + "Нерехта", + "Нерчинск", + "Нерюнгри", + "Нестеров", + "Нефтегорск", + "Нефтекамск", + "Нефтекумск", + "Нефтеюганск", + "Нея", + "Нижневартовск", + "Нижнекамск", + "Нижнеудинск", + "Нижние Серги", + "Нижний Ломов", + "Нижний Новгород", + "Нижний Тагил", + "Нижняя Салда", + "Нижняя Тура", + "Николаевск", + "Николаевск-на-Амуре", + "Никольск", + "Никольск", + "Никольское", + "Новая Ладога", + "Новая Ляля", + "Новоалександровск", + "Новоалтайск", + "Новоаннинский", + "Нововоронеж", + "Новодвинск", + "Новозыбков", + "Новокубанск", + "Новокузнецк", + "Новокуйбышевск", + "Новомичуринск", + "Новомосковск", + "Новопавловск", + "Новоржев", + "Новороссийск", + "Новосибирск", + "Новосиль", + "Новосокольники", + "Новотроицк", + "Новоузенск", + "Новоульяновск", + "Новоуральск", + "Новохопёрск", + "Новочебоксарск", + "Новочеркасск", + "Новошахтинск", + "Новый Оскол", + "Новый Уренгой", + "Ногинск", + "Нолинск", + "Норильск", + "Ноябрьск", + "Нурлат", + "Нытва", + "Нюрба", + "Нягань", + "Нязепетровск", + "Няндома", + "Облучье", + "Обнинск", + "Обоянь", + "Обь", + "Одинцово", + "Озёрск", + "Озёрск", + "Озёры", + "Октябрьск", + "Октябрьский", + "Окуловка", + "Олёкминск", + "Оленегорск", + "Олонец", + "Омск", + "Омутнинск", + "Онега", + "Опочка", + "Орёл", + "Оренбург", + "Орехово-Зуево", + "Орлов", + "Орск", + "Оса", + "Осинники", + "Осташков", + "Остров", + "Островной", + "Острогожск", + "Отрадное", + "Отрадный", + "Оха", + "Оханск", + "Очёр", + "Павлово", + "Павловск", + "Павловский Посад", + "Палласовка", + "Партизанск", + "Певек", + "Пенза", + "Первомайск", + "Первоуральск", + "Перевоз", + "Пересвет", + "Переславль-Залесский", + "Пермь", + "Пестово", + "Петров Вал", + "Петровск", + "Петровск-Забайкальский", + "Петрозаводск", + "Петропавловск-Камчатский", + "Петухово", + "Петушки", + "Печора", + "Печоры", + "Пикалёво", + "Пионерский", + "Питкяранта", + "Плавск", + "Пласт", + "Плёс", + "Поворино", + "Подольск", + "Подпорожье", + "Покачи", + "Покров", + "Покровск", + "Полевской", + "Полесск", + "Полысаево", + "Полярные Зори", + "Полярный", + "Поронайск", + "Порхов", + "Похвистнево", + "Почеп", + "Починок", + "Пошехонье", + "Правдинск", + "Приволжск", + "Приморск", + "Приморск", + "Приморско-Ахтарск", + "Приозерск", + "Прокопьевск", + "Пролетарск", + "Протвино", + "Прохладный", + "Псков", + "Пугачёв", + "Пудож", + "Пустошка", + "Пучеж", + "Пушкино", + "Пущино", + "Пыталово", + "Пыть-Ях", + "Пятигорск", + "Радужный", + "Радужный", + "Райчихинск", + "Раменское", + "Рассказово", + "Ревда", + "Реж", + "Реутов", + "Ржев", + "Родники", + "Рославль", + "Россошь", + "Ростов-на-Дону", + "Ростов", + "Рошаль", + "Ртищево", + "Рубцовск", + "Рудня", + "Руза", + "Рузаевка", + "Рыбинск", + "Рыбное", + "Рыльск", + "Ряжск", + "Рязань", + "СакиОспаривается", + "Салават", + "Салаир", + "Салехард", + "Сальск", + "Самара", + "Санкт-Петербург", + "Саранск", + "Сарапул", + "Саратов", + "Саров", + "Сасово", + "Сатка", + "Сафоново", + "Саяногорск", + "Саянск", + "Светлогорск", + "Светлоград", + "Светлый", + "Светогорск", + "Свирск", + "Свободный", + "Себеж", + "СевастопольОспаривается", + "Северо-Курильск", + "Северобайкальск", + "Северодвинск", + "Североморск", + "Североуральск", + "Северск", + "Севск", + "Сегежа", + "Сельцо", + "Семёнов", + "Семикаракорск", + "Семилуки", + "Сенгилей", + "Серафимович", + "Сергач", + "Сергиев Посад", + "Сердобск", + "Серов", + "Серпухов", + "Сертолово", + "Сибай", + "Сим", + "СимферопольОспаривается", + "Сковородино", + "Скопин", + "Славгород", + "Славск", + "Славянск-на-Кубани", + "Сланцы", + "Слободской", + "Слюдянка", + "Смоленск", + "Снежинск", + "Снежногорск", + "Собинка", + "Советск", + "Советск", + "Советск", + "Советская Гавань", + "Советский", + "Сокол", + "Солигалич", + "Соликамск", + "Солнечногорск", + "Соль-Илецк", + "Сольвычегодск", + "Сольцы", + "Сорочинск", + "Сорск", + "Сортавала", + "Сосенский", + "Сосновка", + "Сосновоборск", + "Сосновый Бор", + "Сосногорск", + "Сочи", + "Спас-Деменск", + "Спас-Клепики", + "Спасск", + "Спасск-Дальний", + "Спасск-Рязанский", + "Среднеколымск", + "Среднеуральск", + "Сретенск", + "Ставрополь", + "Старая Купавна", + "Старая Русса", + "Старица", + "Стародуб", + "Старый КрымОспаривается", + "Старый Оскол", + "Стерлитамак", + "Стрежевой", + "Строитель", + "Струнино", + "Ступино", + "Суворов", + "СудакОспаривается", + "Суджа", + "Судогда", + "Суздаль", + "Сунжа", + "Суоярви", + "Сураж", + "Сургут", + "Суровикино", + "Сурск", + "Сусуман", + "Сухиничи", + "Сухой Лог", + "Сызрань", + "Сыктывкар", + "Сысерть", + "Сычёвка", + "Сясьстрой", + "Тавда", + "Таганрог", + "Тайга", + "Тайшет", + "Талдом", + "Талица", + "Тамбов", + "Тара", + "Тарко-Сале", + "Таруса", + "Татарск", + "Таштагол", + "Тверь", + "Теберда", + "Тейково", + "Темников", + "Темрюк", + "Терек", + "Тетюши", + "Тимашёвск", + "Тихвин", + "Тихорецк", + "Тобольск", + "Тогучин", + "Тольятти", + "Томари", + "Томмот", + "Томск", + "Топки", + "Торжок", + "Торопец", + "Тосно", + "Тотьма", + "Трёхгорный", + "Троицк", + "Трубчевск", + "Туапсе", + "Туймазы", + "Тула", + "Тулун", + "Туран", + "Туринск", + "Тутаев", + "Тында", + "Тырныауз", + "Тюкалинск", + "Тюмень", + "Уварово", + "Углегорск", + "Углич", + "Удачный", + "Удомля", + "Ужур", + "Узловая", + "Улан-Удэ", + "Ульяновск", + "Унеча", + "Урай", + "Урень", + "Уржум", + "Урус-Мартан", + "Урюпинск", + "Усинск", + "Усмань", + "Усолье-Сибирское", + "Усолье", + "Уссурийск", + "Усть-Джегута", + "Усть-Илимск", + "Усть-Катав", + "Усть-Кут", + "Усть-Лабинск", + "Устюжна", + "Уфа", + "Ухта", + "Учалы", + "Уяр", + "Фатеж", + "ФеодосияОспаривается", + "Фокино", + "Фокино", + "Фролово", + "Фрязино", + "Фурманов", + "Хабаровск", + "Хадыженск", + "Ханты-Мансийск", + "Харабали", + "Харовск", + "Хасавюрт", + "Хвалынск", + "Хилок", + "Химки", + "Холм", + "Холмск", + "Хотьково", + "Цивильск", + "Цимлянск", + "Циолковский", + "Чадан", + "Чайковский", + "Чапаевск", + "Чаплыгин", + "Чебаркуль", + "Чебоксары", + "Чегем", + "Чекалин", + "Челябинск", + "Чердынь", + "Черемхово", + "Черепаново", + "Череповец", + "Черкесск", + "Чёрмоз", + "Черноголовка", + "Черногорск", + "Чернушка", + "Черняховск", + "Чехов", + "Чистополь", + "Чита", + "Чкаловск", + "Чудово", + "Чулым", + "Чусовой", + "Чухлома", + "Шагонар", + "Шадринск", + "Шали", + "Шарыпово", + "Шарья", + "Шатура", + "Шахты", + "Шахунья", + "Шацк", + "Шебекино", + "Шелехов", + "Шенкурск", + "Шилка", + "Шимановск", + "Шиханы", + "Шлиссельбург", + "Шумерля", + "Шумиха", + "Шуя", + "Щёкино", + "ЩёлкиноОспаривается", + "Щёлково", + "Щигры", + "Щучье", + "Электрогорск", + "Электросталь", + "Электроугли", + "Элиста", + "Энгельс", + "Эртиль", + "Югорск", + "Южа", + "Южно-Сахалинск", + "Южно-Сухокумск", + "Южноуральск", + "Юрга", + "Юрьев-Польский", + "Юрьевец", + "Юрюзань", + "Юхнов", + "Ядрин", + "Якутск", + "ЯлтаОспаривается", + "Ялуторовск", + "Янаул", + "Яранск", + "Яровое", + "Ярославль", + "Ярцево", + "Ясногорск", + "Ясный", + "Яхрома" + ], }); List dropdownItemList; - List dropdownItemList1; + List cityList; CityOfLivingModel copyWith({ List? dropdownItemList, @@ -25,11 +1143,11 @@ class CityOfLivingModel extends Equatable { return CityOfLivingModel( userRegistrationSheet: userRegistrationSheet, dropdownItemList: dropdownItemList ?? this.dropdownItemList, - dropdownItemList1: dropdownItemList1 ?? this.dropdownItemList1, + cityList: cityList, ); } @override List get props => - [dropdownItemList, dropdownItemList1, userRegistrationSheet]; + [dropdownItemList, cityList, userRegistrationSheet]; } diff --git a/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart b/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart index cb23b28f..e4c6f1cf 100644 --- a/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart +++ b/lib/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart @@ -138,7 +138,8 @@ class _FavoriteSportsScreenState extends State { builder: (context, enterinformationController) { return CustomTextFormField( controller: enterinformationController, - hintText: "enter_information".tr, + hintText: + "Я занимаюсь плаванием , почти каждый вечер прогулки на свежем воздухе, пару раз в месяц играю в волейбол. Стараюсь не сидеть на месте!", textInputAction: TextInputAction.done, maxLines: 8); }) diff --git a/lib/presentation/registration/height_screen/bloc/height_bloc.dart b/lib/presentation/registration/height_screen/bloc/height_bloc.dart index f9330fd6..70b8ba60 100644 --- a/lib/presentation/registration/height_screen/bloc/height_bloc.dart +++ b/lib/presentation/registration/height_screen/bloc/height_bloc.dart @@ -9,7 +9,6 @@ part 'height_state.dart'; class HeightBloc extends Bloc { HeightBloc(HeightState initialState) : super(initialState) { on(_onInitialize); - on(_changeDropDown); } _onInitialize( @@ -17,25 +16,7 @@ class HeightBloc extends Bloc { Emitter emit, ) async { emit(state.copyWith( - heightModelObj: state.heightModelObj - ?.copyWith(dropdownItemList: fillDropdownItemList()))); - } - - _changeDropDown( - ChangeDropDownEvent event, - Emitter emit, - ) { - emit(state.copyWith(selectedDropDownValue: event.value)); - state.heightModelObj?.userRegistrationSheet.height = event.value.title; - } - - List fillDropdownItemList() { - List selectionPopupModels = []; - - for (int i = 140; i <= 220; i++) { - selectionPopupModels - .add(SelectionPopupModel(id: i - 34, title: i.toString())); - } - return selectionPopupModels; + heightModelObj: state.heightModelObj?.copyWith(), + heightController: state.heightController)); } } diff --git a/lib/presentation/registration/height_screen/bloc/height_event.dart b/lib/presentation/registration/height_screen/bloc/height_event.dart index 80d209c4..1d65dd82 100644 --- a/lib/presentation/registration/height_screen/bloc/height_event.dart +++ b/lib/presentation/registration/height_screen/bloc/height_event.dart @@ -14,15 +14,3 @@ class HeightInitialEvent extends HeightEvent { @override List get props => []; } - -///event for dropdown selection -class ChangeDropDownEvent extends HeightEvent { - ChangeDropDownEvent({required this.value}); - - SelectionPopupModel value; - - @override - List get props => [ - value, - ]; -} diff --git a/lib/presentation/registration/height_screen/bloc/height_state.dart b/lib/presentation/registration/height_screen/bloc/height_state.dart index d0e3f45d..aa10592f 100644 --- a/lib/presentation/registration/height_screen/bloc/height_state.dart +++ b/lib/presentation/registration/height_screen/bloc/height_state.dart @@ -5,26 +5,25 @@ part of 'height_bloc.dart'; /// Represents the state of Height in the application. class HeightState extends Equatable { HeightState({ - this.selectedDropDownValue, + this.heightController, this.heightModelObj, }); - SelectionPopupModel? selectedDropDownValue; + TextEditingController? heightController; HeightModel? heightModelObj; @override List get props => [ - selectedDropDownValue, + heightController, heightModelObj, ]; HeightState copyWith({ - SelectionPopupModel? selectedDropDownValue, + TextEditingController? heightController, HeightModel? heightModelObj, }) { return HeightState( - selectedDropDownValue: - selectedDropDownValue ?? this.selectedDropDownValue, + heightController: heightController ?? this.heightController, heightModelObj: heightModelObj ?? this.heightModelObj, ); } diff --git a/lib/presentation/registration/height_screen/height_screen.dart b/lib/presentation/registration/height_screen/height_screen.dart index 9cb66c29..f5bafcb6 100644 --- a/lib/presentation/registration/height_screen/height_screen.dart +++ b/lib/presentation/registration/height_screen/height_screen.dart @@ -4,12 +4,13 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/services.dart'; import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class HeightScreen extends StatefulWidget { +class HeightScreen extends StatelessWidget { const HeightScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { @@ -22,82 +23,91 @@ class HeightScreen extends StatefulWidget { child: HeightScreen()); } - @override - State createState() => _HeightScreenState(); -} - -class _HeightScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); return SafeArea( - child: Scaffold( - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all( - color: theme.colorScheme.primary, width: 1.h)), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.55, - backgroundColor: theme.colorScheme.onPrimary, - valueColor: AlwaysStoppedAnimation( - appTheme.blueA400)))), - SizedBox(height: 39.v), - Column(children: [ - Text("height_measurements".tr, - style: theme.textTheme.headlineSmall), - SizedBox(height: 174.v), - Column(children: [ - Text("your_height".tr, style: theme.textTheme.bodyLarge), + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.55, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400, + ), + ), + ), + ), + SizedBox(height: 39.v), + Column( + children: [ + Text( + "height_measurements".tr, + style: theme.textTheme.headlineSmall, + ), + SizedBox(height: 174.v), + Column( + children: [ + Text( + "your_height".tr, + style: theme.textTheme.bodyLarge, + ), SizedBox(height: 4.v), - BlocSelector( - selector: (state) => state.heightModelObj, - builder: (context, heightModelObj) { - return CustomDropDown( - icon: Container( - margin: EdgeInsets.fromLTRB( - 30.h, 11.v, 17.h, 11.v), - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(1.h)), - child: CustomImageView( - imagePath: ImageConstant.imgFavorite, - height: 12.adaptSize, - width: 12.adaptSize)), - hintText: "170", - items: heightModelObj?.dropdownItemList ?? [], - onChanged: newMethod(context)); - }) - ]) - ]), - Spacer(), - BlocBuilder( - builder: (context, state) { - return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only( - left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapNext(state, context)); - }), - ])))); - } - - newMethod(BuildContext context) { - return (value) { - context.read().add(ChangeDropDownEvent(value: value)); - }; + BlocBuilder( + builder: (context, state) { + return CustomTextFormField( + width: 150.h, + textInputAction: TextInputAction.done, + controller: state.heightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ); + }) + ], + ), + ], + ), + Spacer(), + BlocBuilder( + builder: (context, state) { + return NextStepButton( + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only( + left: 16.h, + right: 16.h, + bottom: 50.v, + ), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapNext(state, context), + ); + }, + ), + ], + ), + ), + ), + ); } onTapNext(HeightState state, BuildContext context) { diff --git a/lib/presentation/registration/splash_screen/bloc/splash_bloc.dart b/lib/presentation/registration/splash_screen/bloc/splash_bloc.dart index a767f763..9491b451 100644 --- a/lib/presentation/registration/splash_screen/bloc/splash_bloc.dart +++ b/lib/presentation/registration/splash_screen/bloc/splash_bloc.dart @@ -17,7 +17,7 @@ class SplashBloc extends Bloc { ) async { Future.delayed(const Duration(milliseconds: 3000), () { NavigatorService.popAndPushNamed( - AppRoutes.authScreen, + AppRoutes.myProfile, ); }); } diff --git a/lib/presentation/registration/weight_screen/bloc/weight_bloc.dart b/lib/presentation/registration/weight_screen/bloc/weight_bloc.dart index bf2cc1f9..69161cce 100644 --- a/lib/presentation/registration/weight_screen/bloc/weight_bloc.dart +++ b/lib/presentation/registration/weight_screen/bloc/weight_bloc.dart @@ -9,7 +9,6 @@ part 'weight_state.dart'; class WeightBloc extends Bloc { WeightBloc(WeightState initialState) : super(initialState) { on(_onInitialize); - on(_changeDropDown); } _onInitialize( @@ -17,25 +16,7 @@ class WeightBloc extends Bloc { Emitter emit, ) async { emit(state.copyWith( - weightModelObj: state.weightModelObj - ?.copyWith(dropdownItemList: fillDropdownItemList()))); - } - - _changeDropDown( - ChangeDropDownEvent event, - Emitter emit, - ) { - emit(state.copyWith(selectedDropDownValue: event.value)); - state.weightModelObj?.userRegistrationSheet.weight = event.value.title; - } - - List fillDropdownItemList() { - List selectionPopupModels = []; - - for (int i = 35; i <= 200; i++) { - selectionPopupModels - .add(SelectionPopupModel(id: i - 34, title: i.toString())); - } - return selectionPopupModels; + weightModelObj: state.weightModelObj?.copyWith(), + weightController: state.weightController)); } } diff --git a/lib/presentation/registration/weight_screen/bloc/weight_event.dart b/lib/presentation/registration/weight_screen/bloc/weight_event.dart index 93b69d22..1b554c5e 100644 --- a/lib/presentation/registration/weight_screen/bloc/weight_event.dart +++ b/lib/presentation/registration/weight_screen/bloc/weight_event.dart @@ -14,15 +14,3 @@ class WeightInitialEvent extends WeightEvent { @override List get props => []; } - -///event for dropdown selection -class ChangeDropDownEvent extends WeightEvent { - ChangeDropDownEvent({required this.value}); - - SelectionPopupModel value; - - @override - List get props => [ - value, - ]; -} diff --git a/lib/presentation/registration/weight_screen/bloc/weight_state.dart b/lib/presentation/registration/weight_screen/bloc/weight_state.dart index 06b9c2cf..5d782dfd 100644 --- a/lib/presentation/registration/weight_screen/bloc/weight_state.dart +++ b/lib/presentation/registration/weight_screen/bloc/weight_state.dart @@ -5,26 +5,25 @@ part of 'weight_bloc.dart'; /// Represents the state of Weight in the application. class WeightState extends Equatable { WeightState({ - this.selectedDropDownValue, + this.weightController, this.weightModelObj, }); - SelectionPopupModel? selectedDropDownValue; + TextEditingController? weightController; WeightModel? weightModelObj; @override List get props => [ - selectedDropDownValue, + weightController, weightModelObj, ]; WeightState copyWith({ - SelectionPopupModel? selectedDropDownValue, + TextEditingController? weightController, WeightModel? weightModelObj, }) { return WeightState( - selectedDropDownValue: - selectedDropDownValue ?? this.selectedDropDownValue, + weightController: weightController ?? this.weightController, weightModelObj: weightModelObj ?? this.weightModelObj, ); } diff --git a/lib/presentation/registration/weight_screen/weight_screen.dart b/lib/presentation/registration/weight_screen/weight_screen.dart index f26fe3de..c68ccb83 100644 --- a/lib/presentation/registration/weight_screen/weight_screen.dart +++ b/lib/presentation/registration/weight_screen/weight_screen.dart @@ -4,12 +4,13 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart'; import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart'; import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart'; -import 'package:eatvio_app/widgets/custom_drop_down.dart'; +import 'package:eatvio_app/widgets/custom_text_form_field.dart'; +import 'package:flutter/services.dart'; import 'package:eatvio_app/widgets/next_step_button.dart'; import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart'; import 'package:flutter/material.dart'; -class WeightScreen extends StatefulWidget { +class WeightScreen extends StatelessWidget { const WeightScreen({Key? key}) : super(key: key); static Widget builder(BuildContext context) { @@ -22,96 +23,94 @@ class WeightScreen extends StatefulWidget { child: WeightScreen()); } - @override - State createState() => _WeightScreenState(); -} - -class _WeightScreenState extends State { @override Widget build(BuildContext context) { mediaQueryData = MediaQuery.of(context); return SafeArea( - child: Scaffold( - appBar: _buildAppBar(context), - body: Container( - width: double.maxFinite, - padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), - child: Column(children: [ - SizedBox(height: 7.v), - Container( - height: 16.v, - width: 343.h, - decoration: BoxDecoration( - color: theme.colorScheme.onPrimary, - borderRadius: BorderRadius.circular(8.h), - border: Border.all( - color: theme.colorScheme.primary, width: 1.h)), - child: ClipRRect( - borderRadius: BorderRadius.circular(8.h), - child: LinearProgressIndicator( - value: 0.48, - backgroundColor: theme.colorScheme.onPrimary, - valueColor: AlwaysStoppedAnimation( - appTheme.blueA400)))), - SizedBox(height: 39.v), - Column(children: [ - Text("weight_measurements".tr, - style: theme.textTheme.headlineSmall), - SizedBox(height: 174.v), - Column(children: [ - Text("your_weight".tr, style: theme.textTheme.bodyLarge), + child: Scaffold( + appBar: _buildAppBar(context), + body: Container( + width: double.maxFinite, + padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v), + child: Column( + children: [ + SizedBox(height: 7.v), + Container( + height: 16.v, + width: 343.h, + decoration: BoxDecoration( + color: theme.colorScheme.onPrimary, + borderRadius: BorderRadius.circular(8.h), + border: Border.all( + color: theme.colorScheme.primary, + width: 1.h, + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8.h), + child: LinearProgressIndicator( + value: 0.55, + backgroundColor: theme.colorScheme.onPrimary, + valueColor: AlwaysStoppedAnimation( + appTheme.blueA400, + ), + ), + ), + ), + SizedBox(height: 39.v), + Column( + children: [ + Text( + "weight_measurements".tr, + style: theme.textTheme.headlineSmall, + ), + SizedBox(height: 174.v), + Column( + children: [ + Text( + "your_weight".tr, + style: theme.textTheme.bodyLarge, + ), SizedBox(height: 4.v), - BlocSelector( - selector: (state) => state.weightModelObj, - builder: (context, weightModelObj) { - return CustomDropDown( - icon: Container( - margin: EdgeInsets.fromLTRB( - 30.h, 11.v, 17.h, 11.v), - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(1.h)), - child: CustomImageView( - imagePath: ImageConstant.imgFavorite, - height: 12.adaptSize, - width: 12.adaptSize)), - hintText: "Не выбрано", - items: weightModelObj?.dropdownItemList ?? [], - onChanged: _onDropDownChanged); - }) - ]) - ]), - Spacer(), - BlocBuilder( - builder: (context, state) { - return NextStepButton( - text: "continue".tr.toUpperCase(), - margin: EdgeInsets.only( - left: 16.h, right: 16.h, bottom: 50.v), - buttonStyle: CustomButtonStyles.outlinePrimaryTL15, - onPressed: onTapNext(context, state)); - }), - ])))); + BlocBuilder( + builder: (context, state) { + return CustomTextFormField( + width: 150.h, + textInputAction: TextInputAction.done, + controller: state.weightController, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + ); + }) + ], + ), + ], + ), + Spacer(), + BlocBuilder( + builder: (context, state) { + return NextStepButton( + text: "continue".tr.toUpperCase(), + margin: EdgeInsets.only( + left: 16.h, + right: 16.h, + bottom: 50.v, + ), + buttonStyle: CustomButtonStyles.outlinePrimaryTL15, + onPressed: onTapNext(state, context), + ); + }, + ), + ], + ), + ), + ), + ); } - /// Section Widget - _buildAppBar(BuildContext context) { - return CustomAppBar( - leadingWidth: 29.h, - leading: AppbarLeadingImage( - imagePath: ImageConstant.imgArrowLeft, - margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), - onTap: () => onTapArrowLeft(context)), - centerTitle: true, - title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); - } - - /// Navigates to the previous screen. - onTapArrowLeft(BuildContext context) { - NavigatorService.goBack(); - } - - onTapNext(BuildContext context, WeightState state) { + onTapNext(WeightState state, BuildContext context) { return () { UserRegistrationSheet sheet = state.weightModelObj!.userRegistrationSheet; Navigator.pushNamed( @@ -122,7 +121,26 @@ class _WeightScreenState extends State { }; } - void _onDropDownChanged(value) { - context.read().add(ChangeDropDownEvent(value: value)); + /// Section Widget + _buildAppBar(BuildContext context) { + return CustomAppBar( + leadingWidth: 29.h, + leading: AppbarLeadingImage( + imagePath: ImageConstant.imgArrowLeft, + margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), + onTap: onTapBack(context)), + centerTitle: true, + title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio)); + } + + Function onTapBack(BuildContext context) { + return () { + onTapArrowLeft(context); + }; + } + + /// Navigates to the previous screen. + onTapArrowLeft(BuildContext context) { + NavigatorService.goBack(); } } diff --git a/lib/widgets/app_bar/appbar_title_circleimage.dart b/lib/widgets/app_bar/appbar_title_circleimage.dart index 66f82ef9..02224f3c 100644 --- a/lib/widgets/app_bar/appbar_title_circleimage.dart +++ b/lib/widgets/app_bar/appbar_title_circleimage.dart @@ -7,7 +7,6 @@ class AppbarTitleCircleimage extends StatelessWidget { Key? key, this.imagePath, this.margin, - this.onTap, }) : super( key: key, ); @@ -16,13 +15,10 @@ class AppbarTitleCircleimage extends StatelessWidget { EdgeInsetsGeometry? margin; - Function? onTap; - @override Widget build(BuildContext context) { return InkWell( borderRadius: BorderRadiusStyle.circleBorder8, - onTap: onTapCall, child: Padding( padding: margin ?? EdgeInsets.zero, child: CustomImageView( @@ -37,8 +33,4 @@ class AppbarTitleCircleimage extends StatelessWidget { ), ); } - - void onTapCall() { - onTap!.call(); - } } diff --git a/lib/widgets/custom_bottom_bar.dart b/lib/widgets/custom_bottom_bar.dart index 45928ebd..922964b0 100644 --- a/lib/widgets/custom_bottom_bar.dart +++ b/lib/widgets/custom_bottom_bar.dart @@ -1,5 +1,7 @@ import 'package:eatvio_app/core/app_export.dart'; import 'package:flutter/material.dart'; +import 'package:eatvio_app/widgets/app_bar/appbar_title_circleimage.dart'; +import 'package:eatvio_app/widgets/custom_navigation_menu.dart'; // ignore: must_be_immutable class CustomBottomBar extends StatefulWidget { @@ -16,41 +18,45 @@ class CustomBottomBarState extends State { List bottomMenuList = [ BottomMenuModel( - icon: ImageConstant.imgNav, - activeIcon: ImageConstant.imgNav, - title: "diary".tr, - type: BottomBarEnum.tf, - ), + icon: ImageConstant.imgLogo, + activeIcon: ImageConstant.imgLogo, + type: BottomBarEnum.tf, + image: false), BottomMenuModel( - icon: ImageConstant.imgNavBlueGray400, - activeIcon: ImageConstant.imgNavBlueGray400, - title: "my_blog".tr, - type: BottomBarEnum.tf, - ), + icon: ImageConstant.imgFeed, + activeIcon: ImageConstant.imgFeed, + title: "Лента", + type: BottomBarEnum.tf, + image: false), BottomMenuModel( - icon: ImageConstant.imgNavBlueGray40024x23, - activeIcon: ImageConstant.imgNavBlueGray40024x23, - title: "profile".tr, - type: BottomBarEnum.tf, - ), + icon: ImageConstant.imgDiary, + activeIcon: ImageConstant.imgDiary, + title: "diary".tr, + type: BottomBarEnum.tf, + image: false), BottomMenuModel( - icon: ImageConstant.imgNavPrimary, - activeIcon: ImageConstant.imgNavPrimary, - title: "admin".tr, - type: BottomBarEnum.tf, - ), + icon: ImageConstant.imgChat, + activeIcon: ImageConstant.imgChat, + title: "chat".tr, + type: BottomBarEnum.tf, + image: false), BottomMenuModel( - icon: ImageConstant.imgNavBlueGray40024x25, - activeIcon: ImageConstant.imgNavBlueGray40024x25, - title: "chat".tr, + icon: ImageConstant.imgBell, + activeIcon: ImageConstant.imgBell, + type: BottomBarEnum.tf, + image: false), + BottomMenuModel( + icon: ImageConstant.imgEllipse1, + activeIcon: ImageConstant.imgEllipse1, type: BottomBarEnum.tf, - ) + image: true, + ), ]; @override Widget build(BuildContext context) { return Container( - height: 80.v, + height: 83.v, decoration: BoxDecoration( border: Border.all( color: appTheme.whiteA700, @@ -72,31 +78,100 @@ class CustomBottomBarState extends State { } void changeMeny(index) { - selectedIndex = index; - widget.onChanged?.call(bottomMenuList[index].type); - setState(() {}); + setState(() { + selectedIndex = index; + }); + + switch (index) { + case 0: + Navigator.pushNamed(context, AppRoutes.myProfile); + break; + case 1: + break; + case 2: + Navigator.pushNamed(context, AppRoutes.diaryEdit); + break; + case 3: + Navigator.pushNamed(context, '/chat'); + break; + } } BottomNavigationBarItem bottomMenu(index) { + bool isSelected = selectedIndex == index; + + double iconHeight; + double iconWidth; + + if (index == 0) { + // Для логотипа- + iconHeight = 52.v; // Увеличиваем высоту + iconWidth = 48.h; // Меняем ширину, чтобы сохранить пропорции + } else if (index == bottomMenuList.length - 2) { + // Для колокольчика + iconHeight = 20.v; // Уменьшаем высоту + iconWidth = 20.h; // Меняем ширину, чтобы сохранить пропорции + } else if (index == bottomMenuList.length - 1) { + // Для колокольчика + iconHeight = 40.v; // Уменьшаем высоту + iconWidth = 40.h; // Меняем ширину, чтобы сохранить пропорции + } else { + // Для остальных иконок + iconHeight = 24.v; // Стандартная высота + iconWidth = 19.h; // Стандартная ширина + } + return BottomNavigationBarItem( icon: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ - CustomImageView( - imagePath: bottomMenuList[index].icon, - height: 24.v, - width: 19.h, - color: appTheme.blueGray400, - ), - Padding( - padding: EdgeInsets.only(top: 8.v), - child: Text( - bottomMenuList[index].title ?? "", - style: CustomTextStyles.bodySmallMulishBluegray80012.copyWith( - color: appTheme.blueGray800, + if (!bottomMenuList[index].image) + CustomImageView( + imagePath: bottomMenuList[index].icon, + height: iconHeight, + width: iconWidth, + color: + isSelected ? theme.colorScheme.primary : appTheme.blueGray400, + ), + if (bottomMenuList[index].image) + GestureDetector( + onTap: () => showMenu( + context: context, + color: Colors.white, + shadowColor: Colors.white, + surfaceTintColor: Colors.white, + position: RelativeRect.fromLTRB( + // Указываем позицию справа по центру + MediaQuery.of(context).size.width - + 50, // Расположение от правого края + kToolbarHeight + 340, // Расположение от верхнего края + 0, // Не смещаем по горизонтали + 0, // Не смещаем по вертикали + ), + items: [ + PopupMenuItem( + child: + CustomNavigationMenu(), // Используйте ваше меню здесь + ) + ], + ), + child: AppbarTitleCircleimage( + imagePath: ImageConstant.imgEllipse1, + ), + ), + if (bottomMenuList[index].title != + null) // Проверяем, существует ли title + Padding( + padding: EdgeInsets.only(top: 8.v), + child: Text( + bottomMenuList[index].title!, + style: CustomTextStyles.bodySmallMulishBluegray80012.copyWith( + color: isSelected + ? theme.colorScheme.primary + : appTheme.blueGray800, + ), ), ), - ), ], ), activeIcon: Column( @@ -104,8 +179,8 @@ class CustomBottomBarState extends State { children: [ CustomImageView( imagePath: bottomMenuList[index].activeIcon, - height: 24.adaptSize, - width: 24.adaptSize, + height: iconHeight, // Используем тот же размер для активной иконки + width: iconWidth, // Используем тот же размер для активной иконки color: theme.colorScheme.primary, ), Padding( @@ -134,6 +209,7 @@ class BottomMenuModel { required this.activeIcon, this.title, required this.type, + required this.image, }); String icon; @@ -143,4 +219,6 @@ class BottomMenuModel { String? title; BottomBarEnum type; + + bool image; } diff --git a/lib/widgets/custom_edit_text_form_field.dart b/lib/widgets/custom_edit_text_form_field.dart index aeeb19e7..0853d3e5 100644 --- a/lib/widgets/custom_edit_text_form_field.dart +++ b/lib/widgets/custom_edit_text_form_field.dart @@ -20,6 +20,7 @@ class CustomTextFormField extends StatelessWidget { this.prefixConstraints, this.suffix, this.suffixConstraints, + this.onFieldSubmitted, this.initialValue, this.contentPadding, this.inputFormatters, @@ -66,6 +67,8 @@ class CustomTextFormField extends StatelessWidget { final Widget? suffix; + final Function(String)? onFieldSubmitted; + final BoxConstraints? suffixConstraints; final EdgeInsets? contentPadding; @@ -112,6 +115,7 @@ class CustomTextFormField extends StatelessWidget { keyboardType: keyboardType, onSaved: onSaved, onChanged: onChanged, + onFieldSubmitted: onFieldSubmitted, inputFormatters: inputFormatters, initialValue: initialValue, ), diff --git a/lib/widgets/custom_expandable_list.dart b/lib/widgets/custom_expandable_list.dart index 3d2190a5..00d66cea 100644 --- a/lib/widgets/custom_expandable_list.dart +++ b/lib/widgets/custom_expandable_list.dart @@ -255,7 +255,7 @@ class _ExpandableListState extends State { ], ), NextStepButton( - onPressed: sendData(state), + onPressed: () => sendProfileData(state), buttonStyle: CustomButtonStyles.outlinePrimaryTL15, text: "save".tr.toUpperCase(), margin: EdgeInsets.only(top: 20.h, bottom: 20.h)), @@ -327,65 +327,16 @@ class _ExpandableListState extends State { Future sendProfileData(MyProfileLoadedState? state) async { try { - // Создаем JSON объект с данными профиля - Map profileData = { - 'first_name': state?.firstNameFormController?.text, - 'last_name': state?.lastNameFormController?.text, - 'chest_circumference': state?.chestCircumferenceFormController?.text, - 'waist_circumference': state?.waistCircumferenceFormController?.text, - 'hip_circumference': state?.hipCircumferenceFormController?.text, - 'birthdate': state?.dateFormController?.text, - 'height': state?.heightFormController?.text, - 'weight': state?.weightFormController?.text, - 'blood_pressure_up': state?.upPressureFormController?.text, - 'blood_pressure_down': state?.downPressureFormController?.text, - 'about_alergy': state?.allergiesFormController?.text, - 'about_taking_pils': state?.pillsFormController?.text, - 'about_sport_hobbies': state?.sportsFormController?.text, - 'favorite_foods': state?.favoriteFormController?.text, - 'unfavorite_foods': state?.unfavoriteFormController?.text, - 'additional_info': state?.additionalFormController?.text, - 'country': state?.selectedCountry ?? 'Россия', - 'city': state?.selectedCity ?? 'Москва', - 'has_hypo': state?.hypoFormController, - 'has_hyper': state?.hyperFormController, - 'activity_coefficient': - determineActivityFactor(state?.selectedActivity ?? 'сидячий') - .toString, - }; - final box = await Hive.openBox('token'); - final token = box.get('token'); - String apiUrl = dotenv.env['SERVER_ROOT']! + '/profile/update'; - http.Response response = await http.post( - Uri.parse(apiUrl), - body: json.encode(profileData), - encoding: utf8, - headers: { - 'Content-Type': 'application/json', - 'Authorization': 'Bearer $token', - }, - ); + final profileData = _createProfileData(state); + final token = await _getTokenFromBox(); + final apiUrl = _buildApiUrl(); + final response = await _sendHttpRequest(profileData, apiUrl, token); - print(response.body); if (response.statusCode == 200) { - Navigator.pushNamed( - context, - AppRoutes.myProfile, - ); + _navigateToProfilePage(); } else { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text('Ошибка'), - content: Text('Ошибка при отправке данных профиля'.tr), - actions: [ - TextButton( - onPressed: onTapOk(context), - child: Text('OK'), - ), - ], - ), - ); + final errorMessage = _getErrorMessage(response); + _showErrorDialog(errorMessage); throw Exception('Ошибка при отправке данных профиля'); } } catch (error) { @@ -393,6 +344,84 @@ class _ExpandableListState extends State { } } + Map _createProfileData(MyProfileLoadedState? state) { + return { + 'first_name': state?.firstNameFormController?.text, + 'last_name': state?.lastNameFormController?.text, + 'chest_circumference': state?.chestCircumferenceFormController?.text, + 'waist_circumference': state?.waistCircumferenceFormController?.text, + 'hip_circumference': state?.hipCircumferenceFormController?.text, + 'birthdate': state?.dateFormController?.text, + 'height': state?.heightFormController?.text, + 'weight': state?.weightFormController?.text, + 'blood_pressure_up': state?.upPressureFormController?.text, + 'blood_pressure_down': state?.downPressureFormController?.text, + 'about_alergy': state?.allergiesFormController?.text ?? 'Нет аллергий', + 'about_taking_pils': state?.pillsFormController?.text, + 'about_sport_hobbies': state?.sportsFormController?.text, + 'favorite_foods': state?.favoriteFormController?.text, + 'unfavorite_foods': state?.unfavoriteFormController?.text, + 'additional_info': state?.additionalFormController?.text, + 'country': state?.selectedCountry ?? 'Россия', + 'city': state?.selectedCity ?? 'Москва', + 'has_hypo': state?.hypoFormController, + 'has_hyper': state?.hyperFormController, + 'activity_coefficient': + determineActivityFactor(state?.selectedActivity ?? 'сидячий'), + }; + } + + Future _getTokenFromBox() async { + final box = await Hive.openBox('token'); + return box.get('token'); + } + + String _buildApiUrl() { + return dotenv.env['SERVER_ROOT']! + '/profile/update'; + } + + Future _sendHttpRequest( + Map profileData, String apiUrl, String? token) { + return http.post( + Uri.parse(apiUrl), + body: json.encode(profileData), + encoding: utf8, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': 'Bearer $token', + }, + ); + } + + void _navigateToProfilePage() { + Navigator.pushNamed( + context, + AppRoutes.myProfile, + ); + } + + String _getErrorMessage(http.Response response) { + final res = jsonDecode(response.body); + return res['message']; + } + + void _showErrorDialog(String errorMessage) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Ошибка'), + content: Text(errorMessage), + actions: [ + TextButton( + onPressed: onTapOk(context), + child: Text('OK'), + ), + ], + ), + ); + } + onTapOk(BuildContext context) { return () { Navigator.pop(context); diff --git a/lib/widgets/custom_navigation_menu.dart b/lib/widgets/custom_navigation_menu.dart new file mode 100644 index 00000000..d817a8f6 --- /dev/null +++ b/lib/widgets/custom_navigation_menu.dart @@ -0,0 +1,64 @@ +import 'package:eatvio_app/core/app_export.dart'; +import 'package:flutter/material.dart'; +import 'package:eatvio_app/widgets/custom_navigation_menu_item.dart'; + +class CustomNavigationMenu extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Container( + color: Colors.white, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MenuItem( + icon: ImageConstant.imgSettings, + text: 'Настройки профиля', + onTap: () => Navigator.pushNamed(context, AppRoutes.mySettings), + ), + MenuItem( + icon: ImageConstant.imgRecipes, + text: 'Мои рецепты', + onTap: () { + // Действие при нажатии на "Мои рецепты" + }, + ), + MenuItem( + icon: ImageConstant.imgDiets, + text: 'Мои диеты', + onTap: () { + // Действие при нажатии на "Мои диеты" + }, + ), + MenuItem( + icon: ImageConstant.imgPlans, + text: 'Мои планы', + onTap: () { + // Действие при нажатии на "Мои планы" + }, + ), + MenuItem( + icon: ImageConstant.imgFinance, + text: 'Финансы', + onTap: () { + // Действие при нажатии на "Финансы" + }, + ), + MenuItem( + icon: ImageConstant.imgSupport, + text: 'Поддержка', + onTap: () { + // Действие при нажатии на "Поддержка" + }, + ), + MenuItem( + icon: ImageConstant.imgExit, + text: 'Выход', + onTap: () { + // Действие при нажатии на "Выход" + }, + ), + ], + ), + ); + } +} diff --git a/lib/widgets/custom_navigation_menu_item.dart b/lib/widgets/custom_navigation_menu_item.dart new file mode 100644 index 00000000..f33d5342 --- /dev/null +++ b/lib/widgets/custom_navigation_menu_item.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:eatvio_app/widgets/custom_image_view.dart'; + +class MenuItem extends StatelessWidget { + final String icon; + final String text; + final VoidCallback onTap; + + const MenuItem({ + required this.icon, + required this.text, + required this.onTap, + }); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.center, // Выравнивание по центру вертикально + children: [ + CustomImageView(imagePath: icon), + SizedBox( + width: + 8.0), // Добавляем небольшой отступ между иконкой и текстом + Text(text), + ], + ), + ), + ); + } +} diff --git a/lib/widgets/custom_text_form_field.dart b/lib/widgets/custom_text_form_field.dart index 0d11d1f3..86a2a237 100644 --- a/lib/widgets/custom_text_form_field.dart +++ b/lib/widgets/custom_text_form_field.dart @@ -28,6 +28,7 @@ class CustomTextFormField extends StatelessWidget { this.filled = true, this.validator, this.keyboardType, + this.onFieldSubmitted, this.onSaved, }) : super( key: key, @@ -56,6 +57,7 @@ class CustomTextFormField extends StatelessWidget { final bool? filled; final TextInputType? keyboardType; final FormFieldValidator? validator; + final Function(String)? onFieldSubmitted; final void Function(String?)? onSaved; @override @@ -73,6 +75,7 @@ class CustomTextFormField extends StatelessWidget { obscureText: obscureText!, textInputAction: textInputAction, maxLines: maxLines ?? 1, + onFieldSubmitted: onFieldSubmitted, decoration: InputDecoration( hintText: hintText ?? "", hintStyle: hintStyle ?? theme.textTheme.bodyLarge, diff --git a/test/diary_test.dart b/test/diary_test.dart index b539eb33..224b05a3 100644 --- a/test/diary_test.dart +++ b/test/diary_test.dart @@ -24,6 +24,7 @@ void main() { diaryId: 1, selectedSatiety: 4, autocompleteList: [], + photos: [], portions: [], wakeupExpanded: false, moderationExpanded: false,