forked from eatvio/eatvio_app
Merge pull request 'GoRouter finished' (#87) from mso7nueh/eatvio_app_mso7nueh:main into diary
Reviewed-on: https://gittea.eatv.io/eatvio/eatvio_app/pulls/87
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_screen/chat_screen.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/chat_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diary/diary_edit_screen/diary_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_create_screen/diet_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_select_screen/diet_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/blog_post_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_edit_screen/blog_post_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/blog_post_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/feed_screen/feed_screen.dart';
|
||||
import 'package:eatvio_app/presentation/glossary/glossary_screen/glossary_screen.dart';
|
||||
@@ -10,14 +13,32 @@ import 'package:eatvio_app/presentation/plans/plan_select_screen/plan_select_scr
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_settings_screen.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_select_screen/recipe_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/additional_information_screen/additional_information_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/allergies_screen/allergies_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/city_of_living_screen/city_of_living_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/credentials_screen/credentials_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/gender_screen/gender_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/height_screen/height_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/language_select_screen/language_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/name_screen/name_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/weight_screen/weight_screen.dart';
|
||||
import 'package:eatvio_app/widgets/bottom_navigation_bar_widget.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
||||
class AppRouter {
|
||||
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
static GoRouter appRouter = GoRouter(
|
||||
initialLocation: '/auth-screen',
|
||||
navigatorKey: navigatorKey,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: '/auth-screen',
|
||||
@@ -36,6 +57,102 @@ class AppRouter {
|
||||
path: 'language-select-screen',
|
||||
name: 'languageSelectScreen',
|
||||
builder: (context, state) => LanguageSelectScreen.builder(context),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'credentials-screen',
|
||||
name: 'credentialsScreen',
|
||||
builder: (context, state) => CredentialsScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'name-screen',
|
||||
name: 'nameScreen',
|
||||
builder: (context, state) => NameScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'gender-screen',
|
||||
name: 'genderScreen',
|
||||
builder: (context, state) => GenderScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'date-of-birth-screen',
|
||||
name: 'dateOfBirthScreen',
|
||||
builder: (context, state) => DateOfBirthScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'city-of-living-screen',
|
||||
name: 'cityOfLivingScreen',
|
||||
builder: (context, state) => CityOfLivingScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'body-circumferences-screen',
|
||||
name: 'bodyCircumferencesScreen',
|
||||
builder: (context, state) => BodyCircumferencesScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'weight-screen',
|
||||
name: 'weightScreen',
|
||||
builder: (context, state) => WeightScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'height-screen',
|
||||
name: 'heightScreen',
|
||||
builder: (context, state) => HeightScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'blood-pressure-screen',
|
||||
name: 'bloodPressureScreen',
|
||||
builder: (context, state) => BloodPressureScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'favorite-sports-screen',
|
||||
name: 'favoriteSportsScreen',
|
||||
builder: (context, state) => FavoriteSportsScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'allergiesScreen',
|
||||
path: 'allergiesScreen',
|
||||
builder: (context, state) => AllergiesScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
name: 'medicineIntakeScreen',
|
||||
path: 'medicine-intake-screen',
|
||||
builder: (context, state) => MedicineIntakeScreen.builder(context, state.extra),
|
||||
),
|
||||
GoRoute(
|
||||
name: 'favoriteFoodsScreen',
|
||||
path: 'favorite-foods-screen',
|
||||
builder: (context, state) => FavoriteFoodsScreen.builder(context, state.extra),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'additional-information-screen',
|
||||
name: 'additionalInformationScreen',
|
||||
builder: (context, state) => AdditionalInformationScreen.builder(context, state.extra),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -66,6 +183,16 @@ class AppRouter {
|
||||
context,
|
||||
state.extra.toString(),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'blog-post-edit-screen',
|
||||
name: 'blogPostEditScreen',
|
||||
builder: (context, state) => BlogPostEditScreen.builder(
|
||||
context,
|
||||
state.extra,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -78,6 +205,13 @@ class AppRouter {
|
||||
path: '/chat-select-screen',
|
||||
name: 'chatSelectScreen',
|
||||
builder: (context, state) => ChatSelectScreen(),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'chat-screen',
|
||||
name: 'chatScreen',
|
||||
builder: (context, state) => ChatScreen.builder(context, state.extra),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -96,6 +230,11 @@ class AppRouter {
|
||||
name: 'dietSelectScreen',
|
||||
builder: (context, state) => DietSelectScreen.builder(context),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/diet-create-screen',
|
||||
name: 'dietCreateScreen',
|
||||
builder: (context, state) => DietCreateScreen.builder(context),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/plan-select-screen',
|
||||
name: 'planSelectScreen',
|
||||
|
||||
@@ -5,12 +5,10 @@ export 'package:eatvio_app/core/errors/exceptions.dart';
|
||||
export 'package:eatvio_app/core/network/network_info.dart';
|
||||
export 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
export 'package:eatvio_app/core/utils/logger.dart';
|
||||
export 'package:eatvio_app/core/utils/navigator_service.dart';
|
||||
export 'package:eatvio_app/core/utils/pref_utils.dart';
|
||||
export 'package:eatvio_app/core/utils/size_utils.dart';
|
||||
export 'package:eatvio_app/data/models/selectionPopupModel/selection_popup_model.dart';
|
||||
export 'package:eatvio_app/localization/app_localization.dart';
|
||||
export 'package:eatvio_app/routes/app_routes.dart';
|
||||
export 'package:eatvio_app/theme/app_decoration.dart';
|
||||
export 'package:eatvio_app/theme/custom_text_style.dart';
|
||||
export 'package:eatvio_app/theme/theme_helper.dart';
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavigatorService {
|
||||
static GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
static Future<dynamic> pushNamed(String routeName,
|
||||
{dynamic arguments}) async {
|
||||
return navigatorKey.currentState
|
||||
?.pushNamed(routeName, arguments: arguments);
|
||||
}
|
||||
|
||||
static void goBack() {
|
||||
return navigatorKey.currentState?.pop();
|
||||
}
|
||||
|
||||
static Future<dynamic> pushNamedAndRemoveUntil(String routeName,
|
||||
{bool routePredicate = false, dynamic arguments}) async {
|
||||
return navigatorKey.currentState?.pushNamedAndRemoveUntil(
|
||||
routeName, (route) => routePredicate,
|
||||
arguments: arguments);
|
||||
}
|
||||
|
||||
static Future<dynamic> popAndPushNamed(String routeName,
|
||||
{dynamic arguments}) async {
|
||||
return navigatorKey.currentState
|
||||
?.popAndPushNamed(routeName, arguments: arguments);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
|
||||
class ProgressDialogUtils {
|
||||
static bool isProgressVisible = false;
|
||||
|
||||
///common method for showing progress dialog
|
||||
static void showProgressDialog(
|
||||
{BuildContext? context, isCancellable = false}) async {
|
||||
if (!isProgressVisible &&
|
||||
NavigatorService.navigatorKey.currentState?.overlay?.context != null) {
|
||||
static void showProgressDialog({BuildContext? context, isCancellable = false}) async {
|
||||
if (!isProgressVisible && AppRouter.navigatorKey.currentState?.overlay?.context != null) {
|
||||
showDialog(
|
||||
barrierDismissible: isCancellable,
|
||||
context: NavigatorService.navigatorKey.currentState!.overlay!.context,
|
||||
context: AppRouter.navigatorKey.currentState!.overlay!.context,
|
||||
builder: (BuildContext context) {
|
||||
return Center(
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
@@ -28,9 +26,7 @@ class ProgressDialogUtils {
|
||||
|
||||
///common method for hiding progress dialog
|
||||
static void hideProgressDialog() {
|
||||
if (isProgressVisible)
|
||||
Navigator.pop(
|
||||
NavigatorService.navigatorKey.currentState!.overlay!.context);
|
||||
if (isProgressVisible) Navigator.pop(AppRouter.navigatorKey.currentState!.overlay!.context);
|
||||
isProgressVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
|
||||
import 'ru/ru_translations.dart';
|
||||
//import 'en_us/en_us_translations.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import '../core/app_export.dart';
|
||||
|
||||
class AppLocalization {
|
||||
AppLocalization(this.locale);
|
||||
@@ -17,7 +18,7 @@ class AppLocalization {
|
||||
};*/
|
||||
|
||||
static AppLocalization of() {
|
||||
final context = NavigatorService.navigatorKey.currentContext;
|
||||
final context = AppRouter.navigatorKey.currentContext;
|
||||
if (context != null) {
|
||||
return Localizations.of<AppLocalization>(context, AppLocalization)!;
|
||||
} else {
|
||||
|
||||
@@ -72,28 +72,28 @@ class MyApp extends StatelessWidget {
|
||||
child: BlocBuilder<ThemeBloc, ThemeState>(
|
||||
builder: (context, state) {
|
||||
return KeyboardDismisser(
|
||||
gestures: [
|
||||
GestureType.onTap,
|
||||
GestureType.onPanUpdateDownDirection,
|
||||
],
|
||||
child: MaterialApp.router(
|
||||
theme: theme,
|
||||
title: 'Eatvio',
|
||||
routerConfig: AppRouter.appRouter,
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: [
|
||||
AppLocalizationDelegate(),
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [
|
||||
Locale(
|
||||
'ru',
|
||||
'',
|
||||
),
|
||||
],
|
||||
));
|
||||
gestures: [
|
||||
GestureType.onTap,
|
||||
GestureType.onPanUpdateDownDirection,
|
||||
],
|
||||
child: MaterialApp.router(
|
||||
theme: theme,
|
||||
title: 'Eatvio',
|
||||
routerConfig: AppRouter.appRouter,
|
||||
debugShowCheckedModeBanner: false,
|
||||
localizationsDelegates: [
|
||||
AppLocalizationDelegate(),
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: [
|
||||
Locale(
|
||||
'ru',
|
||||
'',
|
||||
),
|
||||
],
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
@@ -21,7 +21,9 @@ class AuthScreen extends StatelessWidget {
|
||||
AuthState(
|
||||
authModelObj: AuthModel(),
|
||||
),
|
||||
)..add(AuthInitialEvent()),
|
||||
)..add(
|
||||
AuthInitialEvent(),
|
||||
),
|
||||
child: AuthScreen(),
|
||||
);
|
||||
}
|
||||
@@ -61,10 +63,11 @@ class AuthScreen extends StatelessWidget {
|
||||
}),
|
||||
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)),
|
||||
text: "no_account".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNoAccount(context),
|
||||
),
|
||||
/*NextStepButton(
|
||||
text: "Тест дневника".toUpperCase(),
|
||||
margin:
|
||||
@@ -145,19 +148,19 @@ class AuthScreen extends StatelessWidget {
|
||||
|
||||
onTapOk(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pop(context);
|
||||
GoRouter.of(context).pop(context);
|
||||
};
|
||||
}
|
||||
|
||||
onTapDiaryTest(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pushNamed(context, AppRoutes.diaryEdit);
|
||||
GoRouter.of(context).goNamed('diaryScreen');
|
||||
};
|
||||
}
|
||||
|
||||
onTapProfileTest(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pushNamed(context, AppRoutes.mySettings);
|
||||
GoRouter.of(context).goNamed('mySettingsScreen');
|
||||
};
|
||||
}
|
||||
|
||||
@@ -169,7 +172,13 @@ class AuthScreen extends StatelessWidget {
|
||||
|
||||
/// Section Widget
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(leadingWidth: 29.h, centerTitle: true, title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
return CustomAppBar(
|
||||
leadingWidth: 29.h,
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(
|
||||
imagePath: ImageConstant.imgLogoEatvio,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<String> validateFields(String email, String password) {
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/auth/auth_screen/models/auth_model.dart';
|
||||
|
||||
part 'auth_event.dart';
|
||||
|
||||
part 'auth_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Auth according to the event that is dispatched to it.
|
||||
@@ -15,8 +17,11 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
|
||||
AuthInitialEvent event,
|
||||
Emitter<AuthState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(
|
||||
emit(
|
||||
state.copyWith(
|
||||
emailController: TextEditingController(),
|
||||
passwordController: TextEditingController()));
|
||||
passwordController: TextEditingController(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_screen/models/chat_model.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_screen/models/chat_message_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.
|
||||
@@ -24,9 +28,7 @@ class ChatBloc extends Bloc<ChatEvent, ChatState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? chatID = state.chatModelObj?.chatID;
|
||||
final response = await http.get(
|
||||
@@ -37,17 +39,12 @@ class ChatBloc extends Bloc<ChatEvent, ChatState> {
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
final data = jsonDecode(response.body);
|
||||
if (data is Map<String, dynamic> &&
|
||||
data.containsKey('chatRoom') &&
|
||||
data['chatRoom'].containsKey('messages')) {
|
||||
if (data is Map<String, dynamic> && data.containsKey('chatRoom') && data['chatRoom'].containsKey('messages')) {
|
||||
if (state is ChatLoadedState) {
|
||||
var currentState = state as ChatLoadedState;
|
||||
emit(currentState.copyWith(
|
||||
chatModelObj: currentState.chatModelObj,
|
||||
messages: currentState.messages));
|
||||
emit(currentState.copyWith(chatModelObj: currentState.chatModelObj, messages: currentState.messages));
|
||||
} else {
|
||||
emit(ChatLoadedState(
|
||||
messages: fillMessages(data['chatRoom']['messages'])));
|
||||
emit(ChatLoadedState(messages: fillMessages(data['chatRoom']['messages'])));
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/chat_bloc.dart';
|
||||
import 'models/chat_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -5,12 +7,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_subtitle.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_leading_image.dart';
|
||||
import 'package:eatvio_app/widgets/app_bar/appbar_title_image.dart';
|
||||
|
||||
class ChatScreen extends StatelessWidget {
|
||||
const ChatScreen({Key? key}) : super(key: key);
|
||||
static Widget builder(BuildContext context) {
|
||||
final chatID = ModalRoute.of(context)!.settings.arguments;
|
||||
|
||||
static Widget builder(BuildContext context, chatID) {
|
||||
return BlocProvider<ChatBloc>(
|
||||
create: (context) => ChatBloc(
|
||||
ChatState(chatModelObj: ChatModel(chatID: chatID.toString())))
|
||||
@@ -22,9 +23,8 @@ class ChatScreen extends StatelessWidget {
|
||||
return BlocBuilder<ChatBloc, ChatState>(
|
||||
builder: (context, state) {
|
||||
if (state is ChatInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(child: CircularProgressIndicator(),),
|
||||
);
|
||||
} else if (state is ChatLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
@@ -33,8 +33,9 @@ class ChatScreen extends StatelessWidget {
|
||||
// Произошла ошибка при загрузке данных.
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(child: CircularProgressIndicator(),),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -77,16 +78,13 @@ class ChatScreen extends StatelessWidget {
|
||||
padding: EdgeInsets.only(left: 12.h),
|
||||
child: Row(
|
||||
children: [
|
||||
AppbarTitleImage(
|
||||
imagePath: ImageConstant.imgIconMoreHorizontal,
|
||||
margin: EdgeInsets.only(bottom: 3.v),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 12.h,
|
||||
top: 2.v,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
AppbarSubtitle(
|
||||
text: "Валерий Леонтьев",
|
||||
@@ -102,21 +100,8 @@ class ChatScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
///Handling page based on route
|
||||
Widget getCurrentPage(
|
||||
BuildContext context,
|
||||
String currentRoute,
|
||||
) {
|
||||
switch (currentRoute) {
|
||||
case AppRoutes.chatScreen:
|
||||
return ChatScreen.builder(context);
|
||||
default:
|
||||
return ChatScreen();
|
||||
}
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
@@ -8,7 +9,9 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_select_model.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart'; // ignore: must_be_immutable
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'chat_select_event.dart';
|
||||
part 'chat_select_state.dart';
|
||||
|
||||
@@ -47,9 +50,7 @@ class ChatSelectBloc extends Bloc<ChatSelectEvent, ChatSelectState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/chat/index'),
|
||||
|
||||
@@ -11,75 +11,77 @@ class ChatSelectScreen extends StatelessWidget {
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<ChatSelectBloc>(
|
||||
create: (context) => ChatSelectBloc(ChatSelectState(chatSelectModelObj: ChatSelectModel()))..add(ChatSelectInitialEvent()), child: ChatSelectScreen());
|
||||
create: (context) => ChatSelectBloc(ChatSelectState(chatSelectModelObj: ChatSelectModel()))
|
||||
..add(
|
||||
ChatSelectInitialEvent(),
|
||||
),
|
||||
child: ChatSelectScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ChatSelectBloc, ChatSelectState>(
|
||||
builder: (context, state) {
|
||||
if (state is ChatSelectInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
);
|
||||
} else if (state is ChatSelectLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildScreen(context, state);
|
||||
} else if (state is ChatSelectErrorState) {
|
||||
// Произошла ошибка при загрузке данных.
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
if (state is ChatSelectInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
);
|
||||
} else if (state is ChatSelectLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildScreen(context, state);
|
||||
} else if (state is ChatSelectErrorState) {
|
||||
// Произошла ошибка при загрузке данных.
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
_buildScreen(BuildContext context, ChatSelectLoadedState state) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 30.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 20.h,
|
||||
bottom: 10.h,
|
||||
),
|
||||
padding: EdgeInsets.all(12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomSearchView(
|
||||
controller: state.searchController,
|
||||
hintText: "Поиск",
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildChatList(context, state),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 30.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 20.h,
|
||||
bottom: 10.h,
|
||||
),
|
||||
padding: EdgeInsets.all(12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomSearchView(
|
||||
controller: state.searchController,
|
||||
hintText: "Поиск",
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildChatList(context, state),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/models/chat_entry.dart';
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class ChatEntryWidget extends StatelessWidget {
|
||||
ChatEntryWidget(this.chatEntryObj, {Key? key})
|
||||
@@ -17,10 +18,9 @@ class ChatEntryWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.chatScreen,
|
||||
arguments: chatEntryObj.id.toString(),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'chatScreen',
|
||||
extra: chatEntryObj.id.toString(),
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(8.h),
|
||||
@@ -28,23 +28,23 @@ class ChatEntryWidget extends StatelessWidget {
|
||||
borderRadius: BorderRadiusStyle.circleBorder8,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + chatEntryObj.userImage!,
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + chatEntryObj.userImage!,
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
/*CustomImageView(
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
),
|
||||
/*CustomImageView(
|
||||
imagePath:
|
||||
dotenv.env['STORAGE_URL']! + chatEntryObj.userImage!,
|
||||
height: 60.adaptSize,
|
||||
@@ -53,57 +53,55 @@ class ChatEntryWidget extends StatelessWidget {
|
||||
30.h,
|
||||
),
|
||||
),*/
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 12.h,
|
||||
top: 2.v,
|
||||
bottom: 11.v,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 227.h,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
chatEntryObj.username!.length <= 15
|
||||
? chatEntryObj.username!
|
||||
: chatEntryObj.username!.substring(0, 15) +
|
||||
'...',
|
||||
style: theme.textTheme.titleMedium,
|
||||
),
|
||||
Spacer(),
|
||||
CustomImageView(
|
||||
imagePath: ImageConstant.imageNotFound,
|
||||
height: 9.v,
|
||||
width: 16.h,
|
||||
margin: EdgeInsets.only(
|
||||
top: 4.v,
|
||||
bottom: 6.v,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 6.h),
|
||||
child: Text(
|
||||
chatEntryObj.dateText!,
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6.v),
|
||||
Text(
|
||||
chatEntryObj.greetingText!,
|
||||
style: CustomTextStyles.bodyMediumBluegray800,
|
||||
)
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: 12.h,
|
||||
top: 2.v,
|
||||
bottom: 11.v,
|
||||
),
|
||||
)
|
||||
]),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 227.h,
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
chatEntryObj.username!.length <= 15 ? chatEntryObj.username! : chatEntryObj.username!.substring(0, 15) + '...',
|
||||
style: theme.textTheme.titleMedium,
|
||||
),
|
||||
Spacer(),
|
||||
CustomImageView(
|
||||
imagePath: ImageConstant.imageNotFound,
|
||||
height: 9.v,
|
||||
width: 16.h,
|
||||
margin: EdgeInsets.only(
|
||||
top: 4.v,
|
||||
bottom: 6.v,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 6.h),
|
||||
child: Text(
|
||||
chatEntryObj.dateText!,
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6.v),
|
||||
Text(
|
||||
chatEntryObj.greetingText!,
|
||||
style: CustomTextStyles.bodyMediumBluegray800,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// ignore_for_file: unused_local_variable
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/diary_edit_bloc.dart';
|
||||
import 'models/diary_edit_model.dart';
|
||||
@@ -55,38 +54,40 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
alignment: Alignment.bottomCenter,
|
||||
children: [
|
||||
FormBuilder(
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
backgroundColor: Color.fromARGB(255, 240, 242, 245),
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 5.v),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildHeaderRow(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildWakupRetire(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildMeal(context, state),
|
||||
SizedBox(height: 20.v),
|
||||
_buildMood(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildNutritionChart(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildComment(context, state),
|
||||
],
|
||||
),
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Color.fromARGB(255, 240, 242, 245),
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SizedBox(
|
||||
width: double.maxFinite,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(bottom: 5.v),
|
||||
child: Column(
|
||||
children: [
|
||||
_buildHeaderRow(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildWakupRetire(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildMeal(context, state),
|
||||
SizedBox(height: 20.v),
|
||||
_buildMood(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildNutritionChart(context, state),
|
||||
SizedBox(height: 30.v),
|
||||
_buildComment(context, state),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -142,12 +143,8 @@ class DiaryEditScreen extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CustomImageView(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
onTap: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 1.v),
|
||||
child: Column(
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_create_screen/models/diet_create_model.dart';
|
||||
|
||||
part 'diet_create_event.dart';
|
||||
part 'diet_create_state.dart';
|
||||
|
||||
@@ -25,9 +28,7 @@ class DietCreateBloc extends Bloc<DietCreateEvent, DietCreateState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is DietCreateLoadedState) {
|
||||
var currentState = state as DietCreateLoadedState;
|
||||
@@ -55,7 +56,7 @@ class DietCreateBloc extends Bloc<DietCreateEvent, DietCreateState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.dietSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('dietSelectScreen');
|
||||
} else {
|
||||
print(
|
||||
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_edit_screen/models/diet_edit_model.dart';
|
||||
|
||||
part 'diet_edit_event.dart';
|
||||
|
||||
part 'diet_edit_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a DietEdit according to the event that is dispatched to it.
|
||||
@@ -26,9 +30,7 @@ class DietEditBloc extends Bloc<DietEditEvent, DietEditState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? dietID = state.dietModelObj?.dietID;
|
||||
final response = await http.get(
|
||||
@@ -74,15 +76,15 @@ class DietEditBloc extends Bloc<DietEditEvent, DietEditState> {
|
||||
var currentState = state as DietEditLoadedState;
|
||||
int duration = int.parse(currentState.duration!.text) * 7;
|
||||
print(duration);
|
||||
var response = await sendDiet(currentState.diet, currentState.name?.text,
|
||||
currentState.details?.text, duration.toString());
|
||||
var response = await sendDiet(currentState.diet, currentState.name?.text, currentState.details?.text, duration.toString());
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.dietScreen,
|
||||
arguments: currentState.diet?['id'].toString());
|
||||
AppRouter.navigatorKey.currentContext?.goNamed(
|
||||
'dietScreen',
|
||||
extra: currentState.diet?['id'].toString(),
|
||||
);
|
||||
} else {
|
||||
print(
|
||||
'Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
print('Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -10,6 +11,7 @@ import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'diet_select_event.dart';
|
||||
part 'diet_select_state.dart';
|
||||
@@ -28,9 +30,7 @@ class DietSelectBloc extends Bloc<DietSelectEvent, DietSelectState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/diets/index'),
|
||||
|
||||
@@ -13,10 +13,7 @@ import 'package:flutter/material.dart';
|
||||
class DietSelectScreen extends StatelessWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<DietSelectBloc>(
|
||||
create: (context) => DietSelectBloc(
|
||||
DietSelectState(myProfileModelObj: DietSelectModel()))
|
||||
..add(DietSelectInitialEvent()),
|
||||
child: DietSelectScreen());
|
||||
create: (context) => DietSelectBloc(DietSelectState(myProfileModelObj: DietSelectModel()))..add(DietSelectInitialEvent()), child: DietSelectScreen());
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
@@ -24,16 +21,21 @@ class DietSelectScreen extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
if (state is DietSelectInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is DietSelectLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildSetingsScreen(context, state);
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -41,6 +43,10 @@ class DietSelectScreen extends StatelessWidget {
|
||||
|
||||
_buildSetingsScreen(BuildContext context, DietSelectLoadedState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
@@ -71,8 +77,7 @@ class DietSelectScreen extends StatelessWidget {
|
||||
leadingWidth: 28.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, top: 15.v, bottom: 15.v),
|
||||
margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v),
|
||||
onTap: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
title: Padding(
|
||||
@@ -81,18 +86,15 @@ class DietSelectScreen extends StatelessWidget {
|
||||
children: [
|
||||
AppbarSubtitle(
|
||||
text: "Диеты",
|
||||
margin: EdgeInsets.only(
|
||||
left: 80.h, top: 12.v, bottom: 9.v),
|
||||
margin: EdgeInsets.only(left: 80.h, top: 12.v, bottom: 9.v),
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 20.0),
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.dietCreateScreen,
|
||||
),
|
||||
child: Icon(Icons.create_outlined)),
|
||||
onTap: () => GoRouter.of(context).goNamed('dietCreateScreen'),
|
||||
child: Icon(Icons.create_outlined),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -148,18 +150,17 @@ class DietSelectScreen extends StatelessWidget {
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
subtitle: Text(post?['details'] ?? ''),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.dietScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'dietScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
trailing: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.dietEditScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
),
|
||||
child: Icon(Icons.edit)),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'dietEditScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
child: Icon(Icons.edit),
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
@@ -172,6 +173,6 @@ class DietSelectScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,7 +9,10 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_show_screen/models/diet_show_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'diet_show_event.dart';
|
||||
|
||||
part 'diet_show_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Diet according to the event that is dispatched to it.
|
||||
@@ -26,9 +30,7 @@ class DietBloc extends Bloc<DietEvent, DietState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? dietID = state.dietModelObj?.dietID;
|
||||
final response = await http.get(
|
||||
@@ -42,9 +44,7 @@ class DietBloc extends Bloc<DietEvent, DietState> {
|
||||
if (data is Map<String, dynamic>) {
|
||||
if (state is DietLoadedState) {
|
||||
var currentState = state as DietLoadedState;
|
||||
emit(currentState.copyWith(
|
||||
dietModelObj: currentState.dietModelObj,
|
||||
diet: currentState.diet));
|
||||
emit(currentState.copyWith(dietModelObj: currentState.dietModelObj, diet: currentState.diet));
|
||||
} else {
|
||||
emit(DietLoadedState(diet: data));
|
||||
}
|
||||
@@ -62,14 +62,11 @@ class DietBloc extends Bloc<DietEvent, DietState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _deleteEntry(
|
||||
DeleteEntry event, Emitter<DietState> emit) async {
|
||||
FutureOr<void> _deleteEntry(DeleteEntry event, Emitter<DietState> emit) async {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final int id = event.id;
|
||||
final response = await http.post(
|
||||
@@ -79,7 +76,7 @@ class DietBloc extends Bloc<DietEvent, DietState> {
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.dietSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('dietSelectScreen');
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(DietErrorState('Ошибка: ${response.statusCode}'));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/diet_show_bloc.dart';
|
||||
import 'models/diet_show_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -91,10 +93,9 @@ class DietScreen extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.dietEditScreen,
|
||||
arguments: state.diet?['id'].toString(),
|
||||
onPressed: () => GoRouter.of(context).goNamed(
|
||||
'dietEditScreen',
|
||||
extra: state.diet?['id'].toString(),
|
||||
),
|
||||
child: Text('Редактировать'),
|
||||
),
|
||||
@@ -119,7 +120,7 @@ class DietScreen extends StatelessWidget {
|
||||
String currentRoute,
|
||||
) {
|
||||
switch (currentRoute) {
|
||||
case AppRoutes.dietScreen:
|
||||
case '/diet':
|
||||
return DietScreen.builder(context);
|
||||
default:
|
||||
return DietScreen();
|
||||
@@ -128,6 +129,6 @@ class DietScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/models/blog_post_create_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'blog_post_create_event.dart';
|
||||
part 'blog_post_create_state.dart';
|
||||
|
||||
@@ -26,9 +28,7 @@ class BlogPostCreateBloc
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is BlogPostCreateLoadedState) {
|
||||
var currentState = state as BlogPostCreateLoadedState;
|
||||
@@ -59,7 +59,7 @@ class BlogPostCreateBloc
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.feedScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('feedScreen');
|
||||
} else {
|
||||
print(
|
||||
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,7 +9,10 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_edit_screen/models/blog_post_edit_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'blog_post_edit_event.dart';
|
||||
|
||||
part 'blog_post_edit_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a BlogPostEdit according to the event that is dispatched to it.
|
||||
@@ -26,9 +30,7 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? blog_postID = state.blog_postModelObj?.blog_postID;
|
||||
final response = await http.get(
|
||||
@@ -57,8 +59,7 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
emit(BlogPostEditErrorState(
|
||||
'Некоторые необходимые данные отсутствуют.'));
|
||||
emit(BlogPostEditErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
}
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
@@ -70,8 +71,7 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _editBlogPost(
|
||||
EditBlogPost event, Emitter<BlogPostEditState> emit) async {
|
||||
FutureOr<void> _editBlogPost(EditBlogPost event, Emitter<BlogPostEditState> emit) async {
|
||||
if (state is BlogPostEditLoadedState) {
|
||||
var currentState = state as BlogPostEditLoadedState;
|
||||
|
||||
@@ -83,11 +83,9 @@ class BlogPostEditBloc extends Bloc<BlogPostEditEvent, BlogPostEditState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.blogPostScreen,
|
||||
arguments: currentState.blog_post?['id'].toString());
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('blogPostScreen', extra: currentState.blog_post?['id'].toString());
|
||||
} else {
|
||||
print(
|
||||
'Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
print('Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
class BlogPostEditScreen extends StatelessWidget {
|
||||
const BlogPostEditScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final blog_postID = ModalRoute.of(context)!.settings.arguments;
|
||||
static Widget builder(BuildContext context, blog_postID) {
|
||||
return BlocProvider<BlogPostEditBloc>(
|
||||
create: (context) =>
|
||||
BlogPostEditBloc(BlogPostEditState(blog_postModelObj: BlogPostEditModel(blog_postID: blog_postID.toString())))..add(BlogPostEditInitialEvent()),
|
||||
@@ -20,9 +19,10 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
return BlocBuilder<BlogPostEditBloc, BlogPostEditState>(
|
||||
builder: (context, state) {
|
||||
if (state is BlogPostEditInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is BlogPostEditLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
@@ -31,8 +31,11 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
// Произошла ошибка при загрузке данных.
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -40,76 +43,74 @@ class BlogPostEditScreen extends StatelessWidget {
|
||||
|
||||
_buildBlogPostEdit(BuildContext context, BlogPostEditLoadedState state) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 30.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 20.h,
|
||||
bottom: 10.h,
|
||||
),
|
||||
padding: EdgeInsets.all(12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 30.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 20.h,
|
||||
bottom: 10.h,
|
||||
),
|
||||
padding: EdgeInsets.all(12.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.blog_post?['image'] ?? ''),
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.blog_post?['image'] ?? ''),
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.title,
|
||||
decoration: InputDecoration(labelText: 'Заголовок'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.description,
|
||||
decoration: InputDecoration(labelText: 'Описание'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.youtube_url,
|
||||
decoration: InputDecoration(labelText: 'Ссылка'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
// Здесь нужно добавить виджет для загрузки картинки
|
||||
ElevatedButton(
|
||||
onPressed: () => context.read<BlogPostEditBloc>().add(EditBlogPost()),
|
||||
child: Text('Сохранить'),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.title,
|
||||
decoration: InputDecoration(labelText: 'Заголовок'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.description,
|
||||
decoration: InputDecoration(labelText: 'Описание'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
TextFormField(
|
||||
controller: state.youtube_url,
|
||||
decoration: InputDecoration(labelText: 'Ссылка'),
|
||||
),
|
||||
SizedBox(height: 16.0),
|
||||
// Здесь нужно добавить виджет для загрузки картинки
|
||||
ElevatedButton(
|
||||
onPressed: () => context.read<BlogPostEditBloc>().add(EditBlogPost()),
|
||||
child: Text('Сохранить'),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/models/comment_model.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -10,6 +11,7 @@ import 'package:intl/intl.dart';
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/models/blog_post_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'blog_post_event.dart';
|
||||
part 'blog_post_state.dart';
|
||||
|
||||
@@ -29,9 +31,7 @@ class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? blog_postID = state.blog_postModelObj?.blog_postID;
|
||||
final response = await http.get(
|
||||
@@ -98,9 +98,7 @@ class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final int id = event.id;
|
||||
final response = await http.post(
|
||||
@@ -110,7 +108,7 @@ class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.feedScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('feedScreen');
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(BlogPostErrorState('Ошибка: ${response.statusCode}'));
|
||||
@@ -122,9 +120,7 @@ class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
final token = box.get('token');
|
||||
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
@@ -141,9 +137,7 @@ class BlogPostBloc extends Bloc<BlogPostEvent, BlogPostState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/feed/getComments/$id'),
|
||||
|
||||
@@ -308,10 +308,9 @@ class BlogPostScreen extends StatelessWidget {
|
||||
|
||||
void tapMenu(String value, BuildContext context, BlogPostLoadedState state) {
|
||||
if (value == 'edit') {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.blogPostEditScreen,
|
||||
arguments: state.blog_post?['id'].toString(),
|
||||
GoRouter.of(context).goNamed(
|
||||
'blogPostEditScreen',
|
||||
extra: state.blog_post?['id'].toString(),
|
||||
);
|
||||
} else if (value == 'delete') {
|
||||
context.read<BlogPostBloc>().add(DeleteEntry(state.blog_post?['id']));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -10,6 +11,7 @@ import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'feed_event.dart';
|
||||
part 'feed_state.dart';
|
||||
@@ -28,9 +30,7 @@ class FeedBloc extends Bloc<FeedEvent, FeedState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/feed/index'),
|
||||
|
||||
@@ -267,7 +267,7 @@ class FeedScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
_buildMenu(BuildContext context, FeedLoadedState state) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/glossary/glossary_screen/models/glossary_screen_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'glossary_screen_event.dart';
|
||||
part 'glossary_screen_state.dart';
|
||||
|
||||
@@ -26,9 +28,7 @@ class GlossaryBloc extends Bloc<GlossaryEvent, GlossaryState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final responseProductGroups = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/glossary/getProductGroups'),
|
||||
|
||||
@@ -22,8 +22,10 @@ class GlossaryScreen extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
if (state is GlossaryInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is GlossaryLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
@@ -33,7 +35,11 @@ class GlossaryScreen extends StatelessWidget {
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -41,6 +47,10 @@ class GlossaryScreen extends StatelessWidget {
|
||||
|
||||
_buildGlossary(BuildContext context, GlossaryLoadedState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
@@ -292,7 +302,7 @@ class GlossaryScreen extends StatelessWidget {
|
||||
String currentRoute,
|
||||
) {
|
||||
switch (currentRoute) {
|
||||
case AppRoutes.glossaryScreen:
|
||||
case '/glossary':
|
||||
return GlossaryScreen.builder(context);
|
||||
default:
|
||||
return GlossaryScreen();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_create_screen/models/plan_create_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'plan_create_event.dart';
|
||||
part 'plan_create_state.dart';
|
||||
|
||||
@@ -25,9 +27,7 @@ class PlanCreateBloc extends Bloc<PlanCreateEvent, PlanCreateState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is PlanCreateLoadedState) {
|
||||
var currentState = state as PlanCreateLoadedState;
|
||||
@@ -55,7 +55,7 @@ class PlanCreateBloc extends Bloc<PlanCreateEvent, PlanCreateState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.planSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('planSelectScreen');
|
||||
} else {
|
||||
print(
|
||||
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,7 +9,10 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_edit_screen/models/plan_edit_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'plan_edit_event.dart';
|
||||
|
||||
part 'plan_edit_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a PlanEdit according to the event that is dispatched to it.
|
||||
@@ -26,9 +30,7 @@ class PlanEditBloc extends Bloc<PlanEditEvent, PlanEditState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? planID = state.planModelObj?.planID;
|
||||
final response = await http.get(
|
||||
@@ -53,8 +55,7 @@ class PlanEditBloc extends Bloc<PlanEditEvent, PlanEditState> {
|
||||
plan: data,
|
||||
name: TextEditingController(text: data['name']),
|
||||
details: TextEditingController(text: data['details']),
|
||||
duration:
|
||||
TextEditingController(text: data['duration'].toString())));
|
||||
duration: TextEditingController(text: data['duration'].toString())));
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
@@ -75,15 +76,15 @@ class PlanEditBloc extends Bloc<PlanEditEvent, PlanEditState> {
|
||||
var currentState = state as PlanEditLoadedState;
|
||||
int duration = int.parse(currentState.duration!.text) * 7;
|
||||
print(duration);
|
||||
var response = await sendPlan(currentState.plan, currentState.name?.text,
|
||||
currentState.details?.text, duration.toString());
|
||||
var response = await sendPlan(currentState.plan, currentState.name?.text, currentState.details?.text, duration.toString());
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.planScreen,
|
||||
arguments: currentState.plan?['id'].toString());
|
||||
AppRouter.navigatorKey.currentContext?.goNamed(
|
||||
'planScreen',
|
||||
extra: currentState.plan?['id'].toString(),
|
||||
);
|
||||
} else {
|
||||
print(
|
||||
'Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
print('Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -10,6 +11,7 @@ import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'plan_select_event.dart';
|
||||
part 'plan_select_state.dart';
|
||||
@@ -28,9 +30,7 @@ class PlanSelectBloc extends Bloc<PlanSelectEvent, PlanSelectState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/plans/index'),
|
||||
|
||||
@@ -13,10 +13,7 @@ import 'package:flutter/material.dart';
|
||||
class PlanSelectScreen extends StatelessWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<PlanSelectBloc>(
|
||||
create: (context) => PlanSelectBloc(
|
||||
PlanSelectState(myProfileModelObj: PlanSelectModel()))
|
||||
..add(PlanSelectInitialEvent()),
|
||||
child: PlanSelectScreen());
|
||||
create: (context) => PlanSelectBloc(PlanSelectState(myProfileModelObj: PlanSelectModel()))..add(PlanSelectInitialEvent()), child: PlanSelectScreen());
|
||||
}
|
||||
|
||||
Widget build(BuildContext context) {
|
||||
@@ -24,16 +21,21 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
if (state is PlanSelectInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is PlanSelectLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildSetingsScreen(context, state);
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -41,6 +43,10 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
|
||||
_buildSetingsScreen(BuildContext context, PlanSelectLoadedState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
@@ -71,8 +77,7 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
leadingWidth: 28.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, top: 15.v, bottom: 15.v),
|
||||
margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v),
|
||||
onTap: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
title: Padding(
|
||||
@@ -81,18 +86,15 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
children: [
|
||||
AppbarSubtitle(
|
||||
text: "Планы",
|
||||
margin: EdgeInsets.only(
|
||||
left: 80.h, top: 12.v, bottom: 9.v),
|
||||
margin: EdgeInsets.only(left: 80.h, top: 12.v, bottom: 9.v),
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 20.0),
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.planCreateScreen,
|
||||
),
|
||||
child: Icon(Icons.create_outlined)),
|
||||
onTap: () => GoRouter.of(context).goNamed('planCreateScreen'),
|
||||
child: Icon(Icons.create_outlined),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -116,51 +118,51 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
itemBuilder: (context, index) {
|
||||
final post = state.posts?[index];
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: const BorderRadius.all(Radius.circular(12)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 2,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 3),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: ListTile(
|
||||
leading: CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + post['image'],
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
),
|
||||
child: ListTile(
|
||||
leading: CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + post['image'],
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
),
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => CircleAvatar(
|
||||
child: Icon(Icons.person),
|
||||
backgroundColor: Colors.white,
|
||||
radius: 25,
|
||||
),
|
||||
title: Text(
|
||||
post?['name'] ?? '',
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
subtitle: Text(post?['details'] ?? ''),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'planScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
trailing: GestureDetector(
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'planEditScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
title: Text(
|
||||
post?['name'] ?? '',
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
subtitle: Text(post?['details'] ?? ''),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.planScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
),
|
||||
trailing: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.planEditScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
),
|
||||
child: Icon(Icons.edit)),
|
||||
));
|
||||
child: Icon(Icons.edit),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -172,6 +174,6 @@ class PlanSelectScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,7 +9,10 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_show_screen/models/plan_show_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'plan_show_event.dart';
|
||||
|
||||
part 'plan_show_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Plan according to the event that is dispatched to it.
|
||||
@@ -26,9 +30,7 @@ class PlanBloc extends Bloc<PlanEvent, PlanState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? planID = state.planModelObj?.planID;
|
||||
final response = await http.get(
|
||||
@@ -42,9 +44,7 @@ class PlanBloc extends Bloc<PlanEvent, PlanState> {
|
||||
if (data is Map<String, dynamic>) {
|
||||
if (state is PlanLoadedState) {
|
||||
var currentState = state as PlanLoadedState;
|
||||
emit(currentState.copyWith(
|
||||
planModelObj: currentState.planModelObj,
|
||||
plan: currentState.plan));
|
||||
emit(currentState.copyWith(planModelObj: currentState.planModelObj, plan: currentState.plan));
|
||||
} else {
|
||||
emit(PlanLoadedState(plan: data));
|
||||
}
|
||||
@@ -62,14 +62,11 @@ class PlanBloc extends Bloc<PlanEvent, PlanState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _deleteEntry(
|
||||
DeleteEntry event, Emitter<PlanState> emit) async {
|
||||
FutureOr<void> _deleteEntry(DeleteEntry event, Emitter<PlanState> emit) async {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final int id = event.id;
|
||||
final response = await http.post(
|
||||
@@ -79,7 +76,7 @@ class PlanBloc extends Bloc<PlanEvent, PlanState> {
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.planSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('planSelectScreen');
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(PlanErrorState('Ошибка: ${response.statusCode}'));
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/plan_show_bloc.dart';
|
||||
import 'models/plan_show_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -117,7 +120,7 @@ class PlanScreen extends StatelessWidget {
|
||||
String currentRoute,
|
||||
) {
|
||||
switch (currentRoute) {
|
||||
case AppRoutes.planScreen:
|
||||
case '/plan':
|
||||
return PlanScreen.builder(context);
|
||||
default:
|
||||
return PlanScreen();
|
||||
@@ -126,6 +129,6 @@ class PlanScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -10,6 +11,7 @@ import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'my_profile_event.dart';
|
||||
part 'my_profile_state.dart';
|
||||
@@ -29,9 +31,7 @@ class MyProfileBloc extends Bloc<MyProfileEvent, MyProfileState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
//final token =
|
||||
// "9|laravel_sanctum_KFXbccDcWEvTPfJmV99EQv1ne AggmpR2TidVGDPN34fa201a";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:eatvio_app/widgets/app_bar/custom_app_bar.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/my_profile_bloc.dart';
|
||||
import 'models/my_profile_model.dart';
|
||||
@@ -34,9 +34,10 @@ class MyProfileScreen extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
if (state is MyProfileInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is MyProfileLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
@@ -46,7 +47,11 @@ class MyProfileScreen extends StatelessWidget {
|
||||
return Center(child: Text(state.errorMessage));
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -55,8 +60,9 @@ class MyProfileScreen extends StatelessWidget {
|
||||
_buildMyProfileScreen(BuildContext context, MyProfileLoadedState state) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return Scaffold(
|
||||
appBar: CustomAppBar(
|
||||
height: 0,
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
@@ -182,7 +188,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
|
||||
onTapSettings(BuildContext context) {
|
||||
return () {
|
||||
Navigator.pushNamed(context, AppRoutes.mySettings);
|
||||
GoRouter.of(context).goNamed('mySettingsScreen');
|
||||
};
|
||||
}
|
||||
|
||||
@@ -811,10 +817,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
GoRouter.of(context).go('/my-profile-screen');
|
||||
} else {
|
||||
// Ошибка от сервера
|
||||
print("Ошибка при отправке данных. Код ответа: ${response.statusCode}");
|
||||
@@ -903,10 +906,7 @@ class MyProfileScreen extends StatelessWidget {
|
||||
);
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
GoRouter.of(context).go('/my-profile-screen');
|
||||
} else {
|
||||
// Ошибка от сервера
|
||||
print("Ошибка при отправке данных. Код ответа: ${response.statusCode}");
|
||||
|
||||
@@ -24,16 +24,21 @@ class MySettingsScreen extends StatelessWidget {
|
||||
builder: (context, state) {
|
||||
if (state is MyProfileInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is MyProfileLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildSetingsScreen(context, state);
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -41,6 +46,10 @@ class MySettingsScreen extends StatelessWidget {
|
||||
|
||||
_buildSetingsScreen(BuildContext context, MyProfileLoadedState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
@@ -170,6 +179,6 @@ class MySettingsScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,6 +9,7 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_create_screen/models/recipe_create_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
part 'recipe_create_event.dart';
|
||||
part 'recipe_create_state.dart';
|
||||
|
||||
@@ -28,9 +30,7 @@ class RecipeCreateBloc extends Bloc<RecipeCreateEvent, RecipeCreateState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is RecipeCreateLoadedState) {
|
||||
var currentState = state as RecipeCreateLoadedState;
|
||||
@@ -109,7 +109,7 @@ class RecipeCreateBloc extends Bloc<RecipeCreateEvent, RecipeCreateState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.recipeSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('recipeSelectScreen');
|
||||
} else {
|
||||
print(
|
||||
'Failed to create blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
@@ -146,9 +146,7 @@ class RecipeCreateBloc extends Bloc<RecipeCreateEvent, RecipeCreateState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is RecipeCreateLoadedState) {
|
||||
var currentState = state as RecipeCreateLoadedState;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/recipe_create_bloc.dart';
|
||||
import 'models/recipe_create_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -10,12 +12,12 @@ import 'package:eatvio_app/widgets/custom_outlined_button.dart';
|
||||
|
||||
class RecipeCreateScreen extends StatelessWidget {
|
||||
const RecipeCreateScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final recipeID = ModalRoute.of(context)!.settings.arguments;
|
||||
return BlocProvider<RecipeCreateBloc>(
|
||||
create: (context) => RecipeCreateBloc(RecipeCreateState(
|
||||
recipeModelObj: RecipeCreateModel(recipeID: recipeID.toString())))
|
||||
..add(RecipeCreateInitialEvent()),
|
||||
create: (context) =>
|
||||
RecipeCreateBloc(RecipeCreateState(recipeModelObj: RecipeCreateModel(recipeID: recipeID.toString())))..add(RecipeCreateInitialEvent()),
|
||||
child: RecipeCreateScreen());
|
||||
}
|
||||
|
||||
@@ -52,25 +54,28 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: refreshPage(context),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: Colors.grey[200]),
|
||||
child: ListView(children: [
|
||||
_buldAppBar(context),
|
||||
SizedBox(height: 20.v),
|
||||
_buildRecipeInfo(state, context),
|
||||
SizedBox(height: 20.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildAdditional(context, state)
|
||||
]),
|
||||
))));
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: Colors.grey[200]),
|
||||
child: ListView(children: [
|
||||
_buldAppBar(context),
|
||||
SizedBox(height: 20.v),
|
||||
_buildRecipeInfo(state, context),
|
||||
SizedBox(height: 20.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildAdditional(context, state)
|
||||
]),
|
||||
)));
|
||||
}
|
||||
|
||||
_buldAppBar(BuildContext context) {
|
||||
@@ -280,8 +285,7 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
text: "Добавить шаг",
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
),
|
||||
if (isLastStep &&
|
||||
!isFirstStep) // Добавляем кнопку "Добавить шаг" только для последнего шага
|
||||
if (isLastStep && !isFirstStep) // Добавляем кнопку "Добавить шаг" только для последнего шага
|
||||
Column(
|
||||
children: [
|
||||
SizedBox(height: 16.0),
|
||||
@@ -290,8 +294,7 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
Flexible(
|
||||
flex: 5,
|
||||
child: CustomOutlinedButton(
|
||||
onPressed: () =>
|
||||
context.read<RecipeCreateBloc>().add(AddStep()),
|
||||
onPressed: () => context.read<RecipeCreateBloc>().add(AddStep()),
|
||||
text: "Добавить шаг",
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
),
|
||||
@@ -301,8 +304,7 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
flex: 1,
|
||||
child: CustomOutlinedButton(
|
||||
text: "х",
|
||||
onPressed: () =>
|
||||
context.read<RecipeCreateBloc>().add(RemoveStep(i)),
|
||||
onPressed: () => context.read<RecipeCreateBloc>().add(RemoveStep(i)),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
),
|
||||
),
|
||||
@@ -312,8 +314,7 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
),
|
||||
if (!isLastStep && !isFirstStep)
|
||||
CustomOutlinedButton(
|
||||
onPressed: () =>
|
||||
context.read<RecipeCreateBloc>().add(RemoveStep(i)),
|
||||
onPressed: () => context.read<RecipeCreateBloc>().add(RemoveStep(i)),
|
||||
text: "x",
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
),
|
||||
@@ -356,9 +357,7 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 8.0),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text("Ссылка на видео (необязательно)")),
|
||||
Align(alignment: Alignment.centerLeft, child: Text("Ссылка на видео (необязательно)")),
|
||||
CustomTextFormField(
|
||||
controller: state.video_url,
|
||||
hintText: "YouTube",
|
||||
@@ -380,7 +379,6 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Function onTapBack(BuildContext context) {
|
||||
return () {
|
||||
onTapArrowLeft(context);
|
||||
@@ -388,6 +386,6 @@ class RecipeCreateScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -8,7 +9,10 @@ import 'package:http/http.dart' as http;
|
||||
import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_edit_screen/models/recipe_edit_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'recipe_edit_event.dart';
|
||||
|
||||
part 'recipe_edit_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a RecipeEdit according to the event that is dispatched to it.
|
||||
@@ -29,9 +33,7 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? recipeID = state.recipeModelObj?.recipeID;
|
||||
final response = await http.get(
|
||||
@@ -69,8 +71,7 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
data['steps'].add(defaultStep);
|
||||
} else {
|
||||
for (var step in steps) {
|
||||
stepDescriptions
|
||||
.add(TextEditingController(text: step['description']));
|
||||
stepDescriptions.add(TextEditingController(text: step['description']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,8 +89,7 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
}
|
||||
} else {
|
||||
// Один или несколько ключевых полей отсутствуют, обрабатываем ошибку
|
||||
emit(RecipeEditErrorState(
|
||||
'Некоторые необходимые данные отсутствуют.'));
|
||||
emit(RecipeEditErrorState('Некоторые необходимые данные отсутствуют.'));
|
||||
}
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
@@ -101,8 +101,7 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _editRecipe(
|
||||
EditRecipe event, Emitter<RecipeEditState> emit) async {
|
||||
FutureOr<void> _editRecipe(EditRecipe event, Emitter<RecipeEditState> emit) async {
|
||||
if (state is RecipeEditLoadedState) {
|
||||
var currentState = state as RecipeEditLoadedState;
|
||||
|
||||
@@ -114,11 +113,12 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.recipeScreen,
|
||||
arguments: currentState.recipe?['id'].toString());
|
||||
AppRouter.navigatorKey.currentContext?.goNamed(
|
||||
'recipeScreen',
|
||||
extra: currentState.recipe?['id'].toString(),
|
||||
);
|
||||
} else {
|
||||
print(
|
||||
'Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
print('Failed to edit blog post. Status Code: ${response.statusCode} ${response.body}');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -128,33 +128,28 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
var currentState = state as RecipeEditLoadedState;
|
||||
|
||||
List<dynamic>? updatedSteps = currentState.steps;
|
||||
List<TextEditingController>? updatedStepDescriptions =
|
||||
currentState.stepDescriptions;
|
||||
List<TextEditingController>? updatedStepDescriptions = currentState.stepDescriptions;
|
||||
|
||||
updatedSteps!.add({
|
||||
'description': '',
|
||||
'image': '',
|
||||
});
|
||||
updatedStepDescriptions!.add(TextEditingController());
|
||||
emit(currentState.copyWith(
|
||||
steps: updatedSteps, stepDescriptions: updatedStepDescriptions));
|
||||
emit(currentState.copyWith(steps: updatedSteps, stepDescriptions: updatedStepDescriptions));
|
||||
await _reloadScreen(event, emit);
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _removeStep(
|
||||
RemoveStep event, Emitter<RecipeEditState> emit) async {
|
||||
FutureOr<void> _removeStep(RemoveStep event, Emitter<RecipeEditState> emit) async {
|
||||
if (state is RecipeEditLoadedState) {
|
||||
var currentState = state as RecipeEditLoadedState;
|
||||
|
||||
List<dynamic>? updatedSteps = currentState.steps;
|
||||
List<TextEditingController>? updatedStepDescriptions =
|
||||
currentState.stepDescriptions;
|
||||
List<TextEditingController>? updatedStepDescriptions = currentState.stepDescriptions;
|
||||
|
||||
updatedSteps!.removeAt(event.id);
|
||||
updatedStepDescriptions!.removeAt(event.id);
|
||||
emit(currentState.copyWith(
|
||||
steps: updatedSteps, stepDescriptions: updatedStepDescriptions));
|
||||
emit(currentState.copyWith(steps: updatedSteps, stepDescriptions: updatedStepDescriptions));
|
||||
await _reloadScreen(event, emit);
|
||||
}
|
||||
}
|
||||
@@ -196,9 +191,7 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
final token = box.get('token');
|
||||
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
@@ -211,15 +204,12 @@ class RecipeEditBloc extends Bloc<RecipeEditEvent, RecipeEditState> {
|
||||
return data;
|
||||
}
|
||||
|
||||
FutureOr<void> _reloadScreen(
|
||||
RecipeEditEvent? event, Emitter<RecipeEditState> emit) async {
|
||||
FutureOr<void> _reloadScreen(RecipeEditEvent? event, Emitter<RecipeEditState> emit) async {
|
||||
print('Reloading..');
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
if (state is RecipeEditLoadedState) {
|
||||
var currentState = state as RecipeEditLoadedState;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/recipe_edit_bloc.dart';
|
||||
import 'models/recipe_edit_model.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -54,25 +56,28 @@ class RecipeEditScreen extends StatelessWidget {
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: refreshPage(context),
|
||||
child: SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: Colors.grey[200]),
|
||||
child: ListView(children: [
|
||||
_buldAppBar(context),
|
||||
SizedBox(height: 20.v),
|
||||
_buildRecipeInfo(state, context),
|
||||
SizedBox(height: 20.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildAdditional(context, state)
|
||||
]),
|
||||
))));
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: BoxDecoration(color: Colors.grey[200]),
|
||||
child: ListView(children: [
|
||||
_buldAppBar(context),
|
||||
SizedBox(height: 20.v),
|
||||
_buildRecipeInfo(state, context),
|
||||
SizedBox(height: 20.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
SizedBox(height: 20.v),
|
||||
_buildAdditional(context, state)
|
||||
]),
|
||||
)));
|
||||
}
|
||||
|
||||
_buldAppBar(BuildContext context) {
|
||||
@@ -424,6 +429,6 @@ class RecipeEditScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '/core/app_export.dart';
|
||||
@@ -10,6 +10,7 @@ import 'dart:convert';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'recipe_select_event.dart';
|
||||
part 'recipe_select_state.dart';
|
||||
@@ -28,9 +29,7 @@ class RecipeSelectBloc extends Bloc<RecipeSelectEvent, RecipeSelectState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
); // Если токен есть, запускаем приложение
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/index'),
|
||||
|
||||
@@ -13,9 +13,7 @@ import 'package:flutter/material.dart';
|
||||
class RecipeSelectScreen extends StatelessWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
return BlocProvider<RecipeSelectBloc>(
|
||||
create: (context) => RecipeSelectBloc(
|
||||
RecipeSelectState(myProfileModelObj: RecipeSelectModel()))
|
||||
..add(RecipeSelectInitialEvent()),
|
||||
create: (context) => RecipeSelectBloc(RecipeSelectState(myProfileModelObj: RecipeSelectModel()))..add(RecipeSelectInitialEvent()),
|
||||
child: RecipeSelectScreen());
|
||||
}
|
||||
|
||||
@@ -23,17 +21,20 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
return BlocBuilder<RecipeSelectBloc, RecipeSelectState>(
|
||||
builder: (context, state) {
|
||||
if (state is RecipeSelectInitialState) {
|
||||
// Это начальное состояние, данные ещё не загружены.
|
||||
return CircularProgressIndicator(
|
||||
color: Colors.white,
|
||||
backgroundColor: Colors.white,
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
} else if (state is RecipeSelectLoadedState) {
|
||||
// Данные загружены, можно строить экран.
|
||||
return _buildRecipeScreen(context, state);
|
||||
} else {
|
||||
// Другие состояния, если они есть.
|
||||
return Container(); // Пустой контейнер для необработанных состояний.
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
@@ -41,6 +42,10 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
|
||||
_buildRecipeScreen(BuildContext context, RecipeSelectLoadedState state) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
backgroundColor: Colors.grey[200],
|
||||
resizeToAvoidBottomInset: true,
|
||||
body: SingleChildScrollView(
|
||||
@@ -71,8 +76,7 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
leadingWidth: 28.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, top: 15.v, bottom: 15.v),
|
||||
margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v),
|
||||
onTap: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
title: Padding(
|
||||
@@ -81,18 +85,15 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
children: [
|
||||
AppbarSubtitle(
|
||||
text: "Рецепты",
|
||||
margin: EdgeInsets.only(
|
||||
left: 80.h, top: 12.v, bottom: 9.v),
|
||||
margin: EdgeInsets.only(left: 80.h, top: 12.v, bottom: 9.v),
|
||||
),
|
||||
Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 20.0),
|
||||
child: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.recipeCreateScreen,
|
||||
),
|
||||
child: Icon(Icons.create_outlined)),
|
||||
onTap: () => GoRouter.of(context).goNamed('recipeCreateScreen'),
|
||||
child: Icon(Icons.create_outlined),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
@@ -148,18 +149,17 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
style: CustomTextStyles.titleMediumSemiBold,
|
||||
),
|
||||
subtitle: Text(post?['description'] ?? ''),
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.recipeScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'recipeScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
trailing: GestureDetector(
|
||||
onTap: () => Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.recipeEditScreen,
|
||||
arguments: post?['id'].toString(),
|
||||
),
|
||||
child: Icon(Icons.edit)),
|
||||
onTap: () => GoRouter.of(context).goNamed(
|
||||
'recipeEditScreen',
|
||||
extra: post?['id'].toString(),
|
||||
),
|
||||
child: Icon(Icons.edit),
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
@@ -172,6 +172,6 @@ class RecipeSelectScreen extends StatelessWidget {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
@@ -10,7 +11,10 @@ import 'dart:convert';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_show_screen/models/recipe_show_model.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/models/comment_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
part 'recipe_show_event.dart';
|
||||
|
||||
part 'recipe_show_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Recipe according to the event that is dispatched to it.
|
||||
@@ -29,9 +33,7 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final String? recipeID = state.recipeModelObj?.recipeID;
|
||||
final response = await http.get(
|
||||
@@ -77,14 +79,11 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _deleteEntry(
|
||||
DeleteEntry event, Emitter<RecipeState> emit) async {
|
||||
FutureOr<void> _deleteEntry(DeleteEntry event, Emitter<RecipeState> emit) async {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final int id = event.id;
|
||||
final response = await http.post(
|
||||
@@ -94,27 +93,23 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
},
|
||||
);
|
||||
if (response.statusCode == 200) {
|
||||
NavigatorService.pushNamed(AppRoutes.recipeSelectScreen);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('recipeSelectScreen');
|
||||
} else {
|
||||
// Статус ответа не равен 200, обрабатываем ошибку
|
||||
emit(RecipeErrorState('Ошибка: ${response.statusCode}'));
|
||||
}
|
||||
}
|
||||
|
||||
FutureOr<void> _createComment(
|
||||
CreateComment event, Emitter<RecipeState> emit) async {
|
||||
FutureOr<void> _createComment(CreateComment event, Emitter<RecipeState> emit) async {
|
||||
if (state is RecipeLoadedState) {
|
||||
var currentState = state as RecipeLoadedState;
|
||||
// Отправляем данные по HTTP маршруту и ждем ответ
|
||||
var response = await _sendCommentData(
|
||||
currentState.token, event.body, currentState.recipe?['id']);
|
||||
var response = await _sendCommentData(currentState.token, event.body, currentState.recipe?['id']);
|
||||
if (response.statusCode == 200) {
|
||||
var updatedComments =
|
||||
fillCommentList(await _fetchComments(currentState.recipe?['id']));
|
||||
var updatedComments = fillCommentList(await _fetchComments(currentState.recipe?['id']));
|
||||
var updatedState = currentState.copyWith(
|
||||
comments: updatedComments,
|
||||
commentController:
|
||||
TextEditingController(), // Clear the comment input field
|
||||
commentController: TextEditingController(), // Clear the comment input field
|
||||
);
|
||||
emit(updatedState); // Emit the updated state to trigger a screen update
|
||||
}
|
||||
@@ -126,9 +121,7 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
final token = box.get('token');
|
||||
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
@@ -145,9 +138,7 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = box.get('token');
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
final response = await http.get(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/recipe/getComments/$id'),
|
||||
@@ -164,9 +155,7 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
final token = box.get('token');
|
||||
|
||||
if (token == null) {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.authScreen,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('authScreen');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
@@ -186,15 +175,13 @@ class RecipeBloc extends Bloc<RecipeEvent, RecipeState> {
|
||||
id: comments[i]['id'].toString(),
|
||||
userImage: comments[i]['profile_photo_path'],
|
||||
username: comments[i]['name'],
|
||||
dateText: DateFormat('dd.MM')
|
||||
.format(DateTime.parse(comments[i]['updated_at'])),
|
||||
dateText: DateFormat('dd.MM').format(DateTime.parse(comments[i]['updated_at'])),
|
||||
greetingText: comments[i]['body']));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Future<http.Response> _sendCommentData(
|
||||
String? token, String body, int id) async {
|
||||
Future<http.Response> _sendCommentData(String? token, String body, int id) async {
|
||||
String url = dotenv.env['SERVER_ROOT']! + '/recipe/createComment/$id';
|
||||
final Map<String, dynamic> credentials = {
|
||||
'id': id,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/recipe_show_bloc.dart';
|
||||
import 'models/recipe_show_model.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_screen/widgets/comment_widget.dart';
|
||||
@@ -11,12 +13,11 @@ import 'package:flutter_dotenv/flutter_dotenv.dart';
|
||||
|
||||
class RecipeScreen extends StatelessWidget {
|
||||
const RecipeScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final recipeID = ModalRoute.of(context)!.settings.arguments;
|
||||
return BlocProvider<RecipeBloc>(
|
||||
create: (context) => RecipeBloc(RecipeState(
|
||||
recipeModelObj: RecipeModel(recipeID: recipeID.toString())))
|
||||
..add(RecipeInitialEvent()),
|
||||
create: (context) => RecipeBloc(RecipeState(recipeModelObj: RecipeModel(recipeID: recipeID.toString())))..add(RecipeInitialEvent()),
|
||||
child: RecipeScreen());
|
||||
}
|
||||
|
||||
@@ -50,30 +51,33 @@ class RecipeScreen extends StatelessWidget {
|
||||
steps.add(_buildStep(context, state, i));
|
||||
}
|
||||
}
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 15.v),
|
||||
_buildHeaderRow(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
_buildRecipeData(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
SizedBox(height: 15.v),
|
||||
_buildTextField(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
_buildCommentSection(context, state),
|
||||
],
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
toolbarHeight: 0,
|
||||
automaticallyImplyLeading: false,
|
||||
),
|
||||
resizeToAvoidBottomInset: false,
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
decoration: AppDecoration.fillGray,
|
||||
child: ListView(
|
||||
children: [
|
||||
SizedBox(height: 15.v),
|
||||
_buildHeaderRow(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
_buildRecipeData(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: steps,
|
||||
),
|
||||
)));
|
||||
SizedBox(height: 15.v),
|
||||
_buildTextField(context, state),
|
||||
SizedBox(height: 15.v),
|
||||
_buildCommentSection(context, state),
|
||||
],
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
_buildHeaderRow(BuildContext context, RecipeLoadedState state) {
|
||||
@@ -100,8 +104,9 @@ class RecipeScreen extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
CustomImageView(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
onTap: () => NavigatorService.goBack()),
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
onTap: () => GoRouter.of(context).pop(),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 1.v),
|
||||
child: Row(
|
||||
@@ -114,8 +119,7 @@ class RecipeScreen extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! +
|
||||
(state.author?['profile_photo_path'] ?? ''),
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.author?['profile_photo_path'] ?? ''),
|
||||
imageBuilder: (context, imageProvider) => CircleAvatar(
|
||||
backgroundImage: imageProvider,
|
||||
radius: 25,
|
||||
@@ -189,8 +193,7 @@ class RecipeScreen extends StatelessWidget {
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
DateFormat('dd.MM.yyyy')
|
||||
.format(DateTime.parse(state.recipe?['updated_at'])),
|
||||
DateFormat('dd.MM.yyyy').format(DateTime.parse(state.recipe?['updated_at'])),
|
||||
style: theme.textTheme.bodyMedium,
|
||||
)),
|
||||
SizedBox(height: 16.0),
|
||||
@@ -317,10 +320,9 @@ class RecipeScreen extends StatelessWidget {
|
||||
|
||||
void tapMenu(String value, BuildContext context, RecipeLoadedState state) {
|
||||
if (value == 'edit') {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.recipeEditScreen,
|
||||
arguments: state.recipe?['id'].toString(),
|
||||
GoRouter.of(context).goNamed(
|
||||
'recipeEditScreen',
|
||||
extra: state.recipe?['id'].toString(),
|
||||
);
|
||||
} else if (value == 'delete') {
|
||||
context.read<RecipeBloc>().add(DeleteEntry(state.recipe?['id']));
|
||||
@@ -364,9 +366,7 @@ class RecipeScreen extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
onPressed: () => context
|
||||
.read<RecipeBloc>()
|
||||
.add(CreateComment(state.commentController!.text)),
|
||||
onPressed: () => context.read<RecipeBloc>().add(CreateComment(state.commentController!.text)),
|
||||
// Установите прозрачный фон
|
||||
)
|
||||
],
|
||||
@@ -408,7 +408,7 @@ class RecipeScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowleftone(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
Widget _buildStep(BuildContext context, RecipeLoadedState state, int i) {
|
||||
@@ -442,9 +442,10 @@ class RecipeScreen extends StatelessWidget {
|
||||
SizedBox(height: 16.0),
|
||||
CachedNetworkImage(
|
||||
imageUrl: dotenv.env['STORAGE_URL']! + (state.steps?[i]['image']),
|
||||
width: double
|
||||
.infinity, // Установите ширину равной ширине родительского элемента
|
||||
height: 200.0, // Задайте постоянную высоту элемента
|
||||
width: double.infinity,
|
||||
// Установите ширину равной ширине родительского элемента
|
||||
height: 200.0,
|
||||
// Задайте постоянную высоту элемента
|
||||
fit: BoxFit.cover,
|
||||
placeholder: (context, url) => CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/additional_information_bloc.dart';
|
||||
import 'models/additional_information_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -16,85 +18,63 @@ import 'package:http/http.dart' as http;
|
||||
class AdditionalInformationScreen extends StatelessWidget {
|
||||
const AdditionalInformationScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<AdditionalInformationBloc>(
|
||||
create: (context) => AdditionalInformationBloc(
|
||||
AdditionalInformationState(
|
||||
additionalInformationModelObj:
|
||||
AdditionalInformationModel(userRegistrationSheet: sheet)))
|
||||
..add(AdditionalInformationInitialEvent()),
|
||||
create: (context) =>
|
||||
AdditionalInformationBloc(AdditionalInformationState(additionalInformationModelObj: AdditionalInformationModel(userRegistrationSheet: sheet)))
|
||||
..add(AdditionalInformationInitialEvent()),
|
||||
child: AdditionalInformationScreen());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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: 1,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 20.v),
|
||||
SizedBox(height: 73.v),
|
||||
_buildTextFormField(context),
|
||||
Spacer(),
|
||||
BlocBuilder<AdditionalInformationBloc,
|
||||
AdditionalInformationState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "finish".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapFinish(state, context));
|
||||
}),
|
||||
]))));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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: 1, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 20.v),
|
||||
SizedBox(height: 73.v),
|
||||
_buildTextFormField(context),
|
||||
Spacer(),
|
||||
BlocBuilder<AdditionalInformationBloc, AdditionalInformationState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "finish".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapFinish(state, context));
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapFinish(AdditionalInformationState state, BuildContext context) {
|
||||
return () async {
|
||||
UserRegistrationSheet sheet =
|
||||
state.additionalInformationModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.additionalInformationModelObj!.userRegistrationSheet;
|
||||
sheet.additionalInfo = state.editTextController!.text;
|
||||
|
||||
final response = await http.post(
|
||||
Uri.parse(dotenv.env['SERVER_ROOT']! + '/register'),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: jsonEncode(sheet.toJson()),
|
||||
encoding: utf8);
|
||||
final response = await http.post(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) {
|
||||
final box = await Hive.openBox('token');
|
||||
final token = res['token'];
|
||||
box.put('token', token);
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
GoRouter.of(context).goNamed('myProfileScreen');
|
||||
} else {
|
||||
showErrorMessage(context, res['message']);
|
||||
}
|
||||
@@ -105,10 +85,8 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 31.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v),
|
||||
onTap: onTapBack(context)),
|
||||
leading:
|
||||
AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
@@ -132,19 +110,14 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
width: 294.h,
|
||||
margin: EdgeInsets.only(left: 24.h, right: 23.h),
|
||||
child: Text("enter_additional_information".tr,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: CustomTextStyles.titleMediumSegoeUI)),
|
||||
maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: CustomTextStyles.titleMediumSegoeUI)),
|
||||
SizedBox(height: 10.v),
|
||||
BlocSelector<AdditionalInformationBloc,
|
||||
AdditionalInformationState, TextEditingController?>(
|
||||
BlocSelector<AdditionalInformationBloc, AdditionalInformationState, TextEditingController?>(
|
||||
selector: (state) => state.editTextController,
|
||||
builder: (context, editTextController) {
|
||||
return CustomTextFormField(
|
||||
controller: editTextController,
|
||||
hintText:
|
||||
"У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни",
|
||||
hintText: "У меня крепкое здоровье, но последнее время часто утомляюсь, однако, это мне не мешает радоваться жизни",
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 8);
|
||||
})
|
||||
@@ -154,7 +127,7 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
/// Displays an alert dialog when the action is triggered.
|
||||
@@ -165,9 +138,7 @@ class AdditionalInformationScreen extends StatelessWidget {
|
||||
builder: (_) => AlertDialog(
|
||||
title: const Text('Ошибка'),
|
||||
content: Text(text),
|
||||
actions: [
|
||||
TextButton(onPressed: onTapOk(context), child: const Text('Ok'))
|
||||
],
|
||||
actions: [TextButton(onPressed: onTapOk(context), child: const Text('Ok'))],
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/allergies_bloc.dart';
|
||||
import 'models/allergies_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -12,13 +14,9 @@ import 'package:flutter/material.dart';
|
||||
class AllergiesScreen extends StatefulWidget {
|
||||
const AllergiesScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<AllergiesBloc>(
|
||||
create: (context) => AllergiesBloc(AllergiesState(
|
||||
allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet)))
|
||||
..add(AllergiesInitialEvent()),
|
||||
create: (context) => AllergiesBloc(AllergiesState(allergiesModelObj: AllergiesModel(userRegistrationSheet: sheet)))..add(AllergiesInitialEvent()),
|
||||
child: AllergiesScreen());
|
||||
}
|
||||
|
||||
@@ -29,78 +27,58 @@ class AllergiesScreen extends StatefulWidget {
|
||||
class _AllergiesScreenState extends State<AllergiesScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.76,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 22.v),
|
||||
Text("allergies_presence".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 36),
|
||||
_buildTextFormField(context),
|
||||
Spacer(flex: 54),
|
||||
BlocBuilder<AllergiesBloc, AllergiesState>(
|
||||
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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<AllergiesBloc, AllergiesState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.76, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 22.v),
|
||||
Text("allergies_presence".tr, style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 36),
|
||||
_buildTextFormField(context),
|
||||
Spacer(flex: 54),
|
||||
BlocBuilder<AllergiesBloc, AllergiesState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<AllergiesBloc, AllergiesState>(builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapSkip(AllergiesState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.allergiesModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.medicineIntakeScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
UserRegistrationSheet sheet = state.allergiesModelObj!.userRegistrationSheet;
|
||||
GoRouter.of(context).goNamed('medicineIntakeScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onTapContinue(AllergiesState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.allergiesModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.allergiesModelObj!.userRegistrationSheet;
|
||||
sheet.aboutAllergy = state.enterInformationController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.medicineIntakeScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('medicineIntakeScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -108,10 +86,8 @@ class _AllergiesScreenState extends State<AllergiesScreen> {
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 31.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v),
|
||||
onTap: onTapBack(context)),
|
||||
leading:
|
||||
AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
@@ -125,23 +101,19 @@ class _AllergiesScreenState extends State<AllergiesScreen> {
|
||||
/// Section Widget
|
||||
_buildTextFormField(BuildContext context) {
|
||||
return Column(children: [
|
||||
Text("fill_in_information".tr,
|
||||
style: CustomTextStyles.titleMediumSegoeUI),
|
||||
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<AllergiesBloc, AllergiesState, TextEditingController?>(
|
||||
selector: (state) => state.enterInformationController,
|
||||
builder: (context, enterInformationController) {
|
||||
return CustomTextFormField(
|
||||
controller: enterInformationController,
|
||||
hintText: "enter_information".tr,
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 8);
|
||||
controller: enterInformationController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 8);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/app_navigation_bloc.dart';
|
||||
import 'models/app_navigation_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -49,92 +51,77 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "date_of_birth".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.dateOfBirthScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('dateOfBirthScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "city_of_living".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.cityOfLivingScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('cityOfLivingScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "body_circumferences".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.bodyCircumferencesScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('bodyCircumferencesScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "weight".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.weightScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('weightScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "allergies".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.allergiesScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('allergiesScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "medicine_intake".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.medicineIntakeScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('medicineIntakeScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "splash_screen".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.splashScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('splashScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "gender".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.genderScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('genderScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "blood_pressure".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.bloodPressureScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('bloodPressureScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "favorite_sports".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.favoriteSportsScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('favoriteSportsScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "favorite_foods".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.favoriteFoodsScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('favoriteFoodsScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "schedule".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.scheduleScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('scheduleScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "additional_information".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.additionalInformationScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('additionalInformationScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "language_select".tr,
|
||||
onTapScreenTitle: () => onTapScreenTitle(
|
||||
AppRoutes.languageSelectScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('languageSelectScreen'),
|
||||
),
|
||||
_buildScreenTitle(
|
||||
context,
|
||||
screenTitle: "auth".tr,
|
||||
onTapScreenTitle: () =>
|
||||
onTapScreenTitle(AppRoutes.authScreen),
|
||||
onTapScreenTitle: () => GoRouter.of(context).goNamed('authScreen'),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -181,8 +168,7 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 20.h),
|
||||
child: Text(
|
||||
"Check your app's UI from the below demo screens of your app."
|
||||
.tr,
|
||||
"Check your app's UI from the below demo screens of your app.".tr,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Color(0XFF888888),
|
||||
@@ -247,9 +233,4 @@ class _AppNavigationScreenState extends State<AppNavigationScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Common click event
|
||||
void onTapScreenTitle(String routeName) {
|
||||
NavigatorService.pushNamed(routeName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/blood_pressure_bloc.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'models/blood_pressure_model.dart';
|
||||
@@ -14,14 +17,10 @@ import 'package:flutter/material.dart';
|
||||
class BloodPressureScreen extends StatefulWidget {
|
||||
const BloodPressureScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<BloodPressureBloc>(
|
||||
create: (context) => BloodPressureBloc(BloodPressureState(
|
||||
bloodPressureModelObj:
|
||||
BloodPressureModel(userRegistrationSheet: sheet)))
|
||||
..add(BloodPressureInitialEvent()),
|
||||
create: (context) =>
|
||||
BloodPressureBloc(BloodPressureState(bloodPressureModelObj: BloodPressureModel(userRegistrationSheet: sheet)))..add(BloodPressureInitialEvent()),
|
||||
child: BloodPressureScreen());
|
||||
}
|
||||
|
||||
@@ -33,184 +32,133 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
4.h), // Apply padding directly to the Container
|
||||
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.62,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation<Color>(appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
SizedBox(height: 7.v),
|
||||
Container(
|
||||
height: 16.v,
|
||||
width: 343.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
// Apply padding directly to the Container
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
width: 1.h,
|
||||
),
|
||||
SizedBox(height: 21.v),
|
||||
SizedBox(
|
||||
width: 224.h,
|
||||
child: Text("your_blood_pressure".tr,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 21.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 1.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.h),
|
||||
child: Column(children: [
|
||||
Text("up_pressure".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<BloodPressureBloc, BloodPressureState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.upPressureController,
|
||||
builder: (context, upPressureController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly],
|
||||
controller: upPressureController,
|
||||
hintText: "90".tr);
|
||||
})
|
||||
])),
|
||||
SizedBox(height: 21.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 1.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.h),
|
||||
child: Column(children: [
|
||||
Text("down_pressure".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<BloodPressureBloc, BloodPressureState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.downPressureController,
|
||||
builder: (context, downPressureController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly],
|
||||
controller: downPressureController,
|
||||
hintText: "90".tr);
|
||||
})
|
||||
])),
|
||||
SizedBox(height: 22.v),
|
||||
Text("do_you_have_hypotension_tendency".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
child: BlocSelector<BloodPressureBloc, BloodPressureState,
|
||||
BloodPressureModel?>(
|
||||
selector: (state) => state.bloodPressureModelObj,
|
||||
builder: (context, bloodPressureModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(
|
||||
30.h, 11.v, 13.h, 11.v),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize)),
|
||||
hintText: "Не выбрано".tr,
|
||||
items:
|
||||
bloodPressureModelObj?.dropdownItemList ??
|
||||
[],
|
||||
onChanged: onChangeHyper(context));
|
||||
})),
|
||||
SizedBox(height: 22.v),
|
||||
Text("do_you_have_hypertension_tendency".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
child: BlocSelector<BloodPressureBloc, BloodPressureState,
|
||||
BloodPressureModel?>(
|
||||
selector: (state) => state.bloodPressureModelObj,
|
||||
builder: (context, bloodPressureModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(
|
||||
30.h, 11.v, 13.h, 11.v),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize)),
|
||||
hintText: "Не выбрано".tr,
|
||||
items:
|
||||
bloodPressureModelObj?.dropdownItemList ??
|
||||
[],
|
||||
onChanged: onChangeHypo(context));
|
||||
})),
|
||||
Spacer(),
|
||||
BlocBuilder<BloodPressureBloc, BloodPressureState>(
|
||||
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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<BloodPressureBloc, BloodPressureState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.62,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 21.v),
|
||||
SizedBox(
|
||||
width: 224.h,
|
||||
child: Text("your_blood_pressure".tr,
|
||||
maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 21.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 1.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.h),
|
||||
child: Column(children: [
|
||||
Text("up_pressure".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
|
||||
selector: (state) => state.upPressureController,
|
||||
builder: (context, upPressureController) {
|
||||
return CustomTextFormField(inputFormatters: [digitsOnly], controller: upPressureController, hintText: "90".tr);
|
||||
})
|
||||
])),
|
||||
SizedBox(height: 21.v),
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 1.h),
|
||||
padding: EdgeInsets.symmetric(horizontal: 3.h),
|
||||
child: Column(children: [
|
||||
Text("down_pressure".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<BloodPressureBloc, BloodPressureState, TextEditingController?>(
|
||||
selector: (state) => state.downPressureController,
|
||||
builder: (context, downPressureController) {
|
||||
return CustomTextFormField(inputFormatters: [digitsOnly], controller: downPressureController, hintText: "90".tr);
|
||||
})
|
||||
])),
|
||||
SizedBox(height: 22.v),
|
||||
Text("do_you_have_hypotension_tendency".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
|
||||
selector: (state) => state.bloodPressureModelObj,
|
||||
builder: (context, bloodPressureModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)),
|
||||
hintText: "Не выбрано".tr,
|
||||
items: bloodPressureModelObj?.dropdownItemList ?? [],
|
||||
onChanged: onChangeHyper(context));
|
||||
})),
|
||||
SizedBox(height: 22.v),
|
||||
Text("do_you_have_hypertension_tendency".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h),
|
||||
child: BlocSelector<BloodPressureBloc, BloodPressureState, BloodPressureModel?>(
|
||||
selector: (state) => state.bloodPressureModelObj,
|
||||
builder: (context, bloodPressureModelObj) {
|
||||
return CustomDropDown(
|
||||
icon: Container(
|
||||
margin: EdgeInsets.fromLTRB(30.h, 11.v, 13.h, 11.v),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(1.h)),
|
||||
child: CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize)),
|
||||
hintText: "Не выбрано".tr,
|
||||
items: bloodPressureModelObj?.dropdownItemList ?? [],
|
||||
onChanged: onChangeHypo(context));
|
||||
})),
|
||||
Spacer(),
|
||||
BlocBuilder<BloodPressureBloc, BloodPressureState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<BloodPressureBloc, BloodPressureState>(builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapSkip(BloodPressureState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.bloodPressureModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.allergiesScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
UserRegistrationSheet sheet = state.bloodPressureModelObj!.userRegistrationSheet;
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('allergiesScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onTapContinue(BloodPressureState state, BuildContext context) {
|
||||
return () {
|
||||
List<String> errors = validateFields(
|
||||
state.upPressureController!.text, state.downPressureController!.text);
|
||||
List<String> errors = validateFields(state.upPressureController!.text, state.downPressureController!.text);
|
||||
if (errors.isEmpty) {
|
||||
UserRegistrationSheet sheet =
|
||||
state.bloodPressureModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.bloodPressureModelObj!.userRegistrationSheet;
|
||||
sheet.bloodPressureUp = state.upPressureController!.text;
|
||||
sheet.bloodPressureDown = state.downPressureController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.favoriteSportsScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('favoriteSportsScreen', extra: sheet);
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
@@ -243,9 +191,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
|
||||
onChangeHypo(BuildContext context) {
|
||||
return (value) {
|
||||
context
|
||||
.read<BloodPressureBloc>()
|
||||
.add(ChangeHyperDropDownEvent(value: value));
|
||||
context.read<BloodPressureBloc>().add(ChangeHyperDropDownEvent(value: value));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -259,10 +205,8 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -275,7 +219,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
List<String> validateFields(
|
||||
@@ -288,8 +232,7 @@ class _BloodPressureScreenState extends State<BloodPressureScreen> {
|
||||
errors.add('pressure_empty'.tr);
|
||||
}
|
||||
|
||||
if (![bloodPressureUp, bloodPressureDown]
|
||||
.every((pressure) => int.tryParse(pressure) != null)) {
|
||||
if (![bloodPressureUp, bloodPressureDown].every((pressure) => int.tryParse(pressure) != null)) {
|
||||
errors.add('pressure_is_not_a_number'.tr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/body_circumferences_bloc.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'models/body_circumferences_model.dart';
|
||||
@@ -13,120 +15,87 @@ import 'package:flutter/material.dart';
|
||||
class BodyCircumferencesScreen extends StatelessWidget {
|
||||
const BodyCircumferencesScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<BodyCircumferencesBloc>(
|
||||
create: (context) => BodyCircumferencesBloc(BodyCircumferencesState(
|
||||
bodyCircumferencesModelObj:
|
||||
BodyCircumferencesModel(userRegistrationSheet: sheet)))
|
||||
..add(BodyCircumferencesInitialEvent()),
|
||||
child: BodyCircumferencesScreen());
|
||||
create: (context) => BodyCircumferencesBloc(BodyCircumferencesState(bodyCircumferencesModelObj: BodyCircumferencesModel(userRegistrationSheet: sheet)))
|
||||
..add(BodyCircumferencesInitialEvent()),
|
||||
child: BodyCircumferencesScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final digitsOnly = FilteringTextInputFormatter.digitsOnly;
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.40,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("initial_measurements".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 93.v),
|
||||
Column(children: [
|
||||
Text("chest_circumference".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<BodyCircumferencesBloc,
|
||||
BodyCircumferencesState, TextEditingController?>(
|
||||
selector: (state) => state.chestCircumferenceController,
|
||||
builder: (context, chestCircumferenceController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly],
|
||||
controller: chestCircumferenceController,
|
||||
hintText: "90".tr);
|
||||
})
|
||||
]),
|
||||
SizedBox(height: 19.v),
|
||||
Text("waist_circumference".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.waistCircumferenceController,
|
||||
builder: (context, waistCircumferenceController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly],
|
||||
controller: waistCircumferenceController,
|
||||
hintText: "60".tr);
|
||||
}),
|
||||
SizedBox(height: 21.v),
|
||||
Text("hip_circumference".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState,
|
||||
TextEditingController?>(
|
||||
selector: (state) => state.hipCircumferenceController,
|
||||
builder: (context, hipCircumferenceController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly],
|
||||
controller: hipCircumferenceController,
|
||||
hintText: "90".tr,
|
||||
textInputAction: TextInputAction.done);
|
||||
}),
|
||||
Spacer(),
|
||||
BlocBuilder<BodyCircumferencesBloc, BodyCircumferencesState>(
|
||||
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: onTapContinue(state, context));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.40, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("initial_measurements".tr, style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 93.v),
|
||||
Column(children: [
|
||||
Text("chest_circumference".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
|
||||
selector: (state) => state.chestCircumferenceController,
|
||||
builder: (context, chestCircumferenceController) {
|
||||
return CustomTextFormField(inputFormatters: [digitsOnly], controller: chestCircumferenceController, hintText: "90".tr);
|
||||
})
|
||||
]),
|
||||
SizedBox(height: 19.v),
|
||||
Text("waist_circumference".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
|
||||
selector: (state) => state.waistCircumferenceController,
|
||||
builder: (context, waistCircumferenceController) {
|
||||
return CustomTextFormField(inputFormatters: [digitsOnly], controller: waistCircumferenceController, hintText: "60".tr);
|
||||
}),
|
||||
]))));
|
||||
SizedBox(height: 21.v),
|
||||
Text("hip_circumference".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<BodyCircumferencesBloc, BodyCircumferencesState, TextEditingController?>(
|
||||
selector: (state) => state.hipCircumferenceController,
|
||||
builder: (context, hipCircumferenceController) {
|
||||
return CustomTextFormField(
|
||||
inputFormatters: [digitsOnly], controller: hipCircumferenceController, hintText: "90".tr, textInputAction: TextInputAction.done);
|
||||
}),
|
||||
Spacer(),
|
||||
BlocBuilder<BodyCircumferencesBloc, BodyCircumferencesState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapContinue(BodyCircumferencesState state, BuildContext context) {
|
||||
return () {
|
||||
List<String> errors = validateFields(
|
||||
state.chestCircumferenceController!.text,
|
||||
state.waistCircumferenceController!.text,
|
||||
state.hipCircumferenceController!.text);
|
||||
List<String> errors =
|
||||
validateFields(state.chestCircumferenceController!.text, state.waistCircumferenceController!.text, state.hipCircumferenceController!.text);
|
||||
if (errors.isEmpty) {
|
||||
UserRegistrationSheet sheet =
|
||||
state.bodyCircumferencesModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.bodyCircumferencesModelObj!.userRegistrationSheet;
|
||||
sheet.chestCircumference = state.chestCircumferenceController!.text;
|
||||
sheet.waistCircumference = state.waistCircumferenceController!.text;
|
||||
sheet.hipCircumference = state.hipCircumferenceController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.weightScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('weightScreen', extra: sheet);
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
@@ -161,10 +130,8 @@ class BodyCircumferencesScreen extends StatelessWidget {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -177,15 +144,11 @@ class BodyCircumferencesScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
/// Navigates to the weightScreen when the action is triggered.
|
||||
navigateToWeight(BuildContext context) {
|
||||
NavigatorService.pushNamed(
|
||||
AppRoutes.weightScreen,
|
||||
);
|
||||
}
|
||||
navigateToWeight(BuildContext context) => GoRouter.of(context).goNamed('weightScreen');
|
||||
|
||||
List<String> validateFields(
|
||||
String chestCircumference,
|
||||
@@ -194,14 +157,11 @@ class BodyCircumferencesScreen extends StatelessWidget {
|
||||
) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (chestCircumference.isEmpty |
|
||||
waistCircumference.isEmpty |
|
||||
hipCircumference.isEmpty) {
|
||||
if (chestCircumference.isEmpty | waistCircumference.isEmpty | hipCircumference.isEmpty) {
|
||||
errors.add('circumference_empty'.tr);
|
||||
}
|
||||
|
||||
if (![chestCircumference, waistCircumference, hipCircumference]
|
||||
.every((circumference) => int.tryParse(circumference) != null)) {
|
||||
if (![chestCircumference, waistCircumference, hipCircumference].every((circumference) => int.tryParse(circumference) != null)) {
|
||||
errors.add('circumference_is_not_a_number'.tr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/city_of_living_bloc.dart';
|
||||
import 'models/city_of_living_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -13,15 +15,12 @@ import 'package:flutter/material.dart';
|
||||
class CityOfLivingScreen extends StatelessWidget {
|
||||
const CityOfLivingScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<CityOfLivingBloc>(
|
||||
create: (context) => CityOfLivingBloc(CityOfLivingState(
|
||||
cityOfLivingModelObj:
|
||||
CityOfLivingModel(userRegistrationSheet: sheet)))
|
||||
..add(CityOfLivingInitialEvent()),
|
||||
child: CityOfLivingScreen());
|
||||
create: (context) =>
|
||||
CityOfLivingBloc(CityOfLivingState(cityOfLivingModelObj: CityOfLivingModel(userRegistrationSheet: sheet)))..add(CityOfLivingInitialEvent()),
|
||||
child: CityOfLivingScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -1145,132 +1144,106 @@ class CityOfLivingScreen extends StatelessWidget {
|
||||
"Ясный",
|
||||
"Яхрома"
|
||||
];
|
||||
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.32,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("place_of_living".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 34),
|
||||
Text("country".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<CityOfLivingBloc, CityOfLivingState,
|
||||
CityOfLivingModel?>(
|
||||
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?.dropdownItemList ?? [],
|
||||
onChanged: onDropDownChange(context));
|
||||
}),
|
||||
SizedBox(height: 22.v),
|
||||
Text("Населенный пункт", style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocBuilder<CityOfLivingBloc, CityOfLivingState>(
|
||||
builder: (context, state) {
|
||||
return RawAutocomplete<String>(
|
||||
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<String> onSelected,
|
||||
Iterable<String> 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),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
return 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.32, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("place_of_living".tr, style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 34),
|
||||
Text("country".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<CityOfLivingBloc, CityOfLivingState, CityOfLivingModel?>(
|
||||
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?.dropdownItemList ?? [],
|
||||
onChanged: onDropDownChange(context));
|
||||
}),
|
||||
SizedBox(height: 22.v),
|
||||
Text("Населенный пункт", style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 2.v),
|
||||
BlocBuilder<CityOfLivingBloc, CityOfLivingState>(builder: (context, state) {
|
||||
return RawAutocomplete<String>(
|
||||
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(),
|
||||
);
|
||||
}),
|
||||
Spacer(flex: 65),
|
||||
BlocBuilder<CityOfLivingBloc, CityOfLivingState>(
|
||||
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: onTapContinue(state, context));
|
||||
}),
|
||||
]))));
|
||||
},
|
||||
optionsViewBuilder: (
|
||||
BuildContext context,
|
||||
AutocompleteOnSelected<String> onSelected,
|
||||
Iterable<String> 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<CityOfLivingBloc, CityOfLivingState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapContinue(CityOfLivingState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.cityOfLivingModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.bodyCircumferencesScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
UserRegistrationSheet sheet = state.cityOfLivingModelObj!.userRegistrationSheet;
|
||||
GoRouter.of(context).goNamed('bodyCircumferencesScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1284,10 +1257,8 @@ class CityOfLivingScreen extends StatelessWidget {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -1300,12 +1271,11 @@ class CityOfLivingScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
selectProduct(AutocompleteOnSelected<String> onSelected, String option,
|
||||
CityOfLivingState state) {
|
||||
selectProduct(AutocompleteOnSelected<String> onSelected, String option, CityOfLivingState state) {
|
||||
state.cityController?.text = option;
|
||||
return () {
|
||||
onSelected(option);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/credentials_bloc.dart';
|
||||
import 'models/credentials_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -10,9 +12,7 @@ import 'package:eatvio_app/widgets/custom_text_form_field.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class CredentialsScreen extends StatelessWidget {
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<CredentialsBloc>(
|
||||
create: (context) => CredentialsBloc(
|
||||
CredentialsState(
|
||||
@@ -40,45 +40,33 @@ class CredentialsScreen extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.onPrimary,
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary, width: 1.h)),
|
||||
border: Border.all(color: theme.colorScheme.primary, width: 1.h)),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.05,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
value: 0.05, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("user_registration".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
Text("user_registration".tr, style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 16.v),
|
||||
Text("email".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<CredentialsBloc, CredentialsState, TextEditingController?>(
|
||||
selector: (state) => state.emailController,
|
||||
builder: (context, emailController) {
|
||||
return CustomTextFormField(
|
||||
controller: emailController,
|
||||
textInputAction: TextInputAction.done);
|
||||
return CustomTextFormField(controller: emailController, textInputAction: TextInputAction.done);
|
||||
}),
|
||||
SizedBox(height: 22.v),
|
||||
Text("username".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<CredentialsBloc, CredentialsState, TextEditingController?>(
|
||||
selector: (state) => state.nameController,
|
||||
builder: (context, nameController) {
|
||||
return CustomTextFormField(
|
||||
controller: nameController,
|
||||
textInputAction: TextInputAction.done);
|
||||
return CustomTextFormField(controller: nameController, textInputAction: TextInputAction.done);
|
||||
}),
|
||||
SizedBox(height: 19.v),
|
||||
Text("password".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<CredentialsBloc, CredentialsState, TextEditingController?>(
|
||||
selector: (state) => state.passwordController,
|
||||
builder: (context, passwordController) {
|
||||
return CustomTextFormField(
|
||||
@@ -87,25 +75,18 @@ class CredentialsScreen extends StatelessWidget {
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 21.v),
|
||||
Text("password_confirmation".tr,
|
||||
style: theme.textTheme.bodyLarge),
|
||||
Text("password_confirmation".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<CredentialsBloc, CredentialsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<CredentialsBloc, CredentialsState, TextEditingController?>(
|
||||
selector: (state) => state.passwordConfirmationController,
|
||||
builder: (context, passwordConfirmationController) {
|
||||
return CustomTextFormField(
|
||||
obscureText: true,
|
||||
controller: passwordConfirmationController,
|
||||
textInputAction: TextInputAction.done);
|
||||
return CustomTextFormField(obscureText: true, controller: passwordConfirmationController, textInputAction: TextInputAction.done);
|
||||
}),
|
||||
Spacer(),
|
||||
BlocBuilder<CredentialsBloc, CredentialsState>(
|
||||
builder: (context, state) {
|
||||
BlocBuilder<CredentialsBloc, CredentialsState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin:
|
||||
EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 50.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapContinue(state, context));
|
||||
}),
|
||||
@@ -114,23 +95,15 @@ class CredentialsScreen extends StatelessWidget {
|
||||
|
||||
onTapContinue(CredentialsState state, BuildContext context) {
|
||||
return () {
|
||||
List<String> errors = validateFields(
|
||||
state.emailController!.text,
|
||||
state.nameController!.text,
|
||||
state.passwordController!.text,
|
||||
state.passwordConfirmationController!.text);
|
||||
List<String> errors =
|
||||
validateFields(state.emailController!.text, state.nameController!.text, state.passwordController!.text, state.passwordConfirmationController!.text);
|
||||
if (errors.isEmpty) {
|
||||
UserRegistrationSheet sheet =
|
||||
state.credentialsModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.credentialsModelObj!.userRegistrationSheet;
|
||||
sheet.email = state.emailController!.text;
|
||||
sheet.name = state.nameController!.text;
|
||||
sheet.password = state.passwordController!.text;
|
||||
sheet.passwordConfirmation = state.passwordConfirmationController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.nameScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('nameScreen', extra: sheet);
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
@@ -163,14 +136,10 @@ class CredentialsScreen extends StatelessWidget {
|
||||
|
||||
/// Section Widget
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 29.h,
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
return CustomAppBar(leadingWidth: 29.h, centerTitle: true, title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
|
||||
List<String> validateFields(
|
||||
String email, String name, String password, String passwordConfirmation) {
|
||||
List<String> validateFields(String email, String name, String password, String passwordConfirmation) {
|
||||
List<String> errors = [];
|
||||
|
||||
if (!isEmail(email)) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/date_of_birth_bloc.dart';
|
||||
import 'models/date_of_birth_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -11,15 +13,17 @@ import 'package:flutter/material.dart';
|
||||
class DateOfBirthScreen extends StatefulWidget {
|
||||
const DateOfBirthScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<DateOfBirthBloc>(
|
||||
create: (context) => DateOfBirthBloc(DateOfBirthState(
|
||||
dateOfBirthModelObj:
|
||||
DateOfBirthModel(userRegistrationSheet: sheet)))
|
||||
..add(DateOfBirthInitialEvent()),
|
||||
child: DateOfBirthScreen());
|
||||
create: (context) => DateOfBirthBloc(
|
||||
DateOfBirthState(
|
||||
dateOfBirthModelObj: DateOfBirthModel(
|
||||
userRegistrationSheet: sheet,
|
||||
),
|
||||
),
|
||||
)..add(DateOfBirthInitialEvent()),
|
||||
child: DateOfBirthScreen(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -28,63 +32,49 @@ class DateOfBirthScreen extends StatefulWidget {
|
||||
|
||||
class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
DateTime selectedDate = DateTime.now();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return BlocBuilder<DateOfBirthBloc, DateOfBirthState>(
|
||||
builder: (context, state) {
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
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.24,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 38.v),
|
||||
Text("date_of_birth".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 39),
|
||||
_buildDateInput(context),
|
||||
Spacer(flex: 60),
|
||||
BlocBuilder<DateOfBirthBloc, DateOfBirthState>(
|
||||
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: onTapContinue(state, context));
|
||||
}),
|
||||
]))));
|
||||
return BlocBuilder<DateOfBirthBloc, DateOfBirthState>(builder: (context, state) {
|
||||
return Scaffold(
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 9.v),
|
||||
child: Column(children: [
|
||||
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.24, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 38.v),
|
||||
Text("date_of_birth".tr, style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 39),
|
||||
_buildDateInput(context),
|
||||
Spacer(flex: 60),
|
||||
BlocBuilder<DateOfBirthBloc, DateOfBirthState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
])));
|
||||
});
|
||||
}
|
||||
|
||||
onTapContinue(DateOfBirthState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.dateOfBirthModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.dateOfBirthModelObj!.userRegistrationSheet;
|
||||
sheet.birthdate = selectedDate.toString();
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.cityOfLivingScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('cityOfLivingScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -92,10 +82,8 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -111,28 +99,17 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
return Container(
|
||||
width: 343.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 4.h, vertical: 1.v),
|
||||
decoration: AppDecoration.outlineBlueA
|
||||
.copyWith(borderRadius: BorderRadiusStyle.circleBorder8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CustomImageView(
|
||||
imagePath: ImageConstant.imgFavorite,
|
||||
height: 12.adaptSize,
|
||||
width: 12.adaptSize,
|
||||
radius: BorderRadius.circular(1.h)),
|
||||
SizedBox(height: 6.v),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: onTapCalendar(context),
|
||||
child: Text(
|
||||
'${selectedDate.day}.${selectedDate.month}.${selectedDate.year}',
|
||||
style: theme.textTheme.titleMedium))),
|
||||
SizedBox(height: 6.v)
|
||||
]));
|
||||
decoration: AppDecoration.outlineBlueA.copyWith(borderRadius: BorderRadiusStyle.circleBorder8),
|
||||
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
CustomImageView(imagePath: ImageConstant.imgFavorite, height: 12.adaptSize, width: 12.adaptSize, radius: BorderRadius.circular(1.h)),
|
||||
SizedBox(height: 6.v),
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: GestureDetector(
|
||||
onTap: onTapCalendar(context),
|
||||
child: Text('${selectedDate.day}.${selectedDate.month}.${selectedDate.year}', style: theme.textTheme.titleMedium))),
|
||||
SizedBox(height: 6.v)
|
||||
]));
|
||||
}
|
||||
|
||||
onTapCalendar(BuildContext context) {
|
||||
@@ -143,7 +120,7 @@ class _DateOfBirthScreenState extends State<DateOfBirthScreen> {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
/// Displays a date picker dialog to update the selected date
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/favorite_foods_bloc.dart';
|
||||
import 'models/favorite_foods_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -12,14 +14,10 @@ import 'package:flutter/material.dart';
|
||||
class FavoriteFoodsScreen extends StatefulWidget {
|
||||
const FavoriteFoodsScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<FavoriteFoodsBloc>(
|
||||
create: (context) => FavoriteFoodsBloc(FavoriteFoodsState(
|
||||
favoriteFoodsModelObj:
|
||||
FavoriteFoodsModel(userRegistrationSheet: sheet)))
|
||||
..add(FavoriteFoodsInitialEvent()),
|
||||
create: (context) =>
|
||||
FavoriteFoodsBloc(FavoriteFoodsState(favoriteFoodsModelObj: FavoriteFoodsModel(userRegistrationSheet: sheet)))..add(FavoriteFoodsInitialEvent()),
|
||||
child: FavoriteFoodsScreen());
|
||||
}
|
||||
|
||||
@@ -30,87 +28,65 @@ class FavoriteFoodsScreen extends StatefulWidget {
|
||||
class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.90,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 19.v),
|
||||
Container(
|
||||
width: 327.h,
|
||||
margin: EdgeInsets.only(left: 8.h, right: 7.h),
|
||||
child: Text("favorite_unfavorite_foods".tr,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 13.v),
|
||||
_buildTextFormFieldFav(context),
|
||||
SizedBox(height: 12.v),
|
||||
_buildTextFormFieldUnfav(context),
|
||||
Spacer(),
|
||||
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h, right: 16.h, bottom: 40.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.90, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 19.v),
|
||||
Container(
|
||||
width: 327.h,
|
||||
margin: EdgeInsets.only(left: 8.h, right: 7.h),
|
||||
child: Text("favorite_unfavorite_foods".tr,
|
||||
maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 13.v),
|
||||
_buildTextFormFieldFav(context),
|
||||
SizedBox(height: 12.v),
|
||||
_buildTextFormFieldUnfav(context),
|
||||
Spacer(),
|
||||
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(left: 16.h, right: 16.h, bottom: 40.v),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<FavoriteFoodsBloc, FavoriteFoodsState>(builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapSkip(FavoriteFoodsState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.favoriteFoodsModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.additionalInformationScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
UserRegistrationSheet sheet = state.favoriteFoodsModelObj!.userRegistrationSheet;
|
||||
GoRouter.of(context).goNamed('additionalInformationScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onTapContinue(FavoriteFoodsState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.favoriteFoodsModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.favoriteFoodsModelObj!.userRegistrationSheet;
|
||||
sheet.favoriteFoods = state.favoriteFoodsController!.text;
|
||||
sheet.unfavoriteFoods = state.unfavoriteFoodsController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.additionalInformationScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('additionalInformationScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -118,10 +94,8 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 31.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v),
|
||||
onTap: onTapBack(context)),
|
||||
leading:
|
||||
AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
@@ -137,14 +111,10 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
|
||||
return Column(children: [
|
||||
Text("favorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<FavoriteFoodsBloc, FavoriteFoodsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<FavoriteFoodsBloc, FavoriteFoodsState, TextEditingController?>(
|
||||
selector: (state) => state.favoriteFoodsController,
|
||||
builder: (context, favoriteFoodsController) {
|
||||
return CustomTextFormField(
|
||||
controller: favoriteFoodsController,
|
||||
hintText: "enter_information".tr,
|
||||
maxLines: 7);
|
||||
return CustomTextFormField(controller: favoriteFoodsController, hintText: "enter_information".tr, maxLines: 7);
|
||||
})
|
||||
]);
|
||||
}
|
||||
@@ -154,28 +124,22 @@ class _FavoriteFoodsScreenState extends State<FavoriteFoodsScreen> {
|
||||
return Column(children: [
|
||||
Text("unfavorite_foods".tr, style: CustomTextStyles.titleMediumSegoeUI),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<FavoriteFoodsBloc, FavoriteFoodsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<FavoriteFoodsBloc, FavoriteFoodsState, TextEditingController?>(
|
||||
selector: (state) => state.unfavoriteFoodsController,
|
||||
builder: (context, unfavoriteFoodsController) {
|
||||
return CustomTextFormField(
|
||||
controller: unfavoriteFoodsController,
|
||||
hintText: "enter_information".tr,
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 7);
|
||||
controller: unfavoriteFoodsController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 7);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
/// Navigates to the scheduleScreen when the action is triggered.
|
||||
navigateToAdditionalInformationScreen(BuildContext context) {
|
||||
NavigatorService.pushNamed(
|
||||
AppRoutes.additionalInformationScreen,
|
||||
);
|
||||
GoRouter.of(context).goNamed('additionalInformationScreen');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/favorite_sports_bloc.dart';
|
||||
import 'models/favorite_sports_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -12,13 +14,9 @@ import 'package:flutter/material.dart';
|
||||
class FavoriteSportsScreen extends StatefulWidget {
|
||||
const FavoriteSportsScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<FavoriteSportsBloc>(
|
||||
create: (context) => FavoriteSportsBloc(FavoriteSportsState(
|
||||
favoriteSportsModelObj:
|
||||
FavoriteSportsModel(userRegistrationSheet: sheet)))
|
||||
create: (context) => FavoriteSportsBloc(FavoriteSportsState(favoriteSportsModelObj: FavoriteSportsModel(userRegistrationSheet: sheet)))
|
||||
..add(FavoriteSportsInitialEvent()),
|
||||
child: FavoriteSportsScreen());
|
||||
}
|
||||
@@ -30,92 +28,66 @@ class FavoriteSportsScreen extends StatefulWidget {
|
||||
class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: 20.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.83,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 38.v),
|
||||
Text("your_favorite_sports".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 32),
|
||||
_buildTextFormFieldSection(context),
|
||||
Spacer(flex: 67),
|
||||
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
|
||||
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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child:
|
||||
Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: _buildAppBar(context),
|
||||
body: Container(
|
||||
width: double.maxFinite,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16.h, vertical: 5.v),
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
SizedBox(height: 20.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.83, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 38.v),
|
||||
Text("your_favorite_sports".tr, style: theme.textTheme.headlineSmall),
|
||||
Spacer(flex: 32),
|
||||
_buildTextFormFieldSection(context),
|
||||
Spacer(flex: 67),
|
||||
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(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: onTapContinue(state, context));
|
||||
}),
|
||||
BlocBuilder<FavoriteSportsBloc, FavoriteSportsState>(builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapSkip(FavoriteSportsState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.favoriteSportsModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.favoriteFoodsScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
UserRegistrationSheet sheet = state.favoriteSportsModelObj!.userRegistrationSheet;
|
||||
GoRouter.of(context).goNamed('favoriteFoodsScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onTapContinue(FavoriteSportsState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.favoriteSportsModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.favoriteSportsModelObj!.userRegistrationSheet;
|
||||
sheet.aboutSportHobbies = state.enterinformationController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.favoriteFoodsScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('favoriteFoodsScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -129,11 +101,9 @@ class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
|
||||
/// Section Widget
|
||||
_buildTextFormFieldSection(BuildContext context) {
|
||||
return Column(children: [
|
||||
Text("fill_in_information".tr,
|
||||
style: CustomTextStyles.titleMediumSegoeUI),
|
||||
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<FavoriteSportsBloc, FavoriteSportsState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<FavoriteSportsBloc, FavoriteSportsState, TextEditingController?>(
|
||||
selector: (state) => state.enterinformationController,
|
||||
builder: (context, enterinformationController) {
|
||||
return CustomTextFormField(
|
||||
@@ -147,6 +117,6 @@ class _FavoriteSportsScreenState extends State<FavoriteSportsScreen> {
|
||||
}
|
||||
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/gender_bloc.dart';
|
||||
import 'models/gender_model.dart';
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
@@ -11,9 +13,7 @@ import 'package:flutter/material.dart';
|
||||
class GenderScreen extends StatefulWidget {
|
||||
const GenderScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<GenderBloc>(
|
||||
create: (context) => GenderBloc(
|
||||
GenderState(
|
||||
@@ -32,66 +32,57 @@ class _GenderScreenState extends State<GenderScreen> {
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return BlocBuilder<GenderBloc, GenderState>(builder: (context, state) {
|
||||
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.16,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 36.v),
|
||||
Text("your_gender".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
RadioListTile(
|
||||
title: Text('Мужской'),
|
||||
value: 'male',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onMale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_male.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
RadioListTile(
|
||||
title: Text('Женский'),
|
||||
value: 'female',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onFemale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_female.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
Spacer(flex: 66),
|
||||
BlocBuilder<GenderBloc, GenderState>(
|
||||
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));
|
||||
}),
|
||||
]))));
|
||||
return 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.16, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 36.v),
|
||||
Text("your_gender".tr, style: theme.textTheme.headlineSmall),
|
||||
RadioListTile(
|
||||
title: Text('Мужской'),
|
||||
value: 'male',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onMale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_male.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
RadioListTile(
|
||||
title: Text('Женский'),
|
||||
value: 'female',
|
||||
groupValue: state.selectedRadioValue,
|
||||
onChanged: onFemale(context),
|
||||
secondary: Image.asset(
|
||||
'assets/images/img_female.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
),
|
||||
),
|
||||
Spacer(flex: 66),
|
||||
BlocBuilder<GenderBloc, GenderState>(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));
|
||||
}),
|
||||
])));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -99,50 +90,42 @@ class _GenderScreenState extends State<GenderScreen> {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.genderModelObj!.userRegistrationSheet;
|
||||
sheet.gender = state.selectedRadioValue!;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.dateOfBirthScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('dateOfBirthScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
onMale(BuildContext context) {
|
||||
return (value) {
|
||||
BlocProvider.of<GenderBloc>(context)
|
||||
.add(GenderSelectEvent(value: 'male'));
|
||||
BlocProvider.of<GenderBloc>(context).add(GenderSelectEvent(value: 'male'));
|
||||
};
|
||||
}
|
||||
|
||||
onFemale(BuildContext context) {
|
||||
return (value) {
|
||||
BlocProvider.of<GenderBloc>(context)
|
||||
.add(GenderSelectEvent(value: 'female'));
|
||||
BlocProvider.of<GenderBloc>(context).add(GenderSelectEvent(value: 'female'));
|
||||
};
|
||||
}
|
||||
|
||||
/// 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()),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
leadingWidth: 29.h,
|
||||
leading: AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 16.h, top: 15.v, bottom: 15.v), onTap: onTapBack()),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(
|
||||
imagePath: ImageConstant.imgLogoEatvio,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Function onTapBack() {
|
||||
return () {
|
||||
NavigatorService.pushNamed(
|
||||
AppRoutes.dateOfBirthScreen,
|
||||
);
|
||||
GoRouter.of(context).pop();
|
||||
};
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/height_bloc.dart';
|
||||
import 'models/height_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -13,98 +15,91 @@ import 'package:flutter/material.dart';
|
||||
class HeightScreen extends StatelessWidget {
|
||||
const HeightScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<HeightBloc>(
|
||||
create: (context) => HeightBloc(HeightState(
|
||||
heightModelObj: HeightModel(userRegistrationSheet: sheet)))
|
||||
..add(HeightInitialEvent()),
|
||||
create: (context) => HeightBloc(HeightState(heightModelObj: HeightModel(userRegistrationSheet: sheet)))..add(HeightInitialEvent()),
|
||||
child: HeightScreen());
|
||||
}
|
||||
|
||||
@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,
|
||||
),
|
||||
return 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<Color>(
|
||||
appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.55,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
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),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.heightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 16.h,
|
||||
bottom: 50.v,
|
||||
),
|
||||
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,
|
||||
),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(state, context),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4.v),
|
||||
BlocBuilder<HeightBloc, HeightState>(builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.heightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<HeightBloc, HeightState>(
|
||||
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),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -113,11 +108,7 @@ class HeightScreen extends StatelessWidget {
|
||||
onTapNext(HeightState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.heightModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.bloodPressureScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('bloodPressureScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,10 +116,8 @@ class HeightScreen extends StatelessWidget {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -141,6 +130,6 @@ class HeightScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:eatvio_app/data/models/userRegistrationModel/user_registration_model.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/language_select_bloc.dart';
|
||||
import 'models/language_select_model.dart';
|
||||
@@ -107,10 +108,9 @@ class LanguageSelectScreen extends StatelessWidget {
|
||||
void Function()? _saveAndPush(LanguageSelectState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.languageSelectModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.credentialsScreen,
|
||||
arguments: sheet,
|
||||
GoRouter.of(context).goNamed(
|
||||
'credentialsScreen',
|
||||
extra: sheet,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/medicine_intake_bloc.dart';
|
||||
import 'models/medicine_intake_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -12,13 +14,9 @@ import 'package:flutter/material.dart';
|
||||
class MedicineIntakeScreen extends StatefulWidget {
|
||||
const MedicineIntakeScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<MedicineIntakeBloc>(
|
||||
create: (context) => MedicineIntakeBloc(MedicineIntakeState(
|
||||
medicineIntakeModelObj:
|
||||
MedicineIntakeModel(userRegistrationSheet: sheet)))
|
||||
create: (context) => MedicineIntakeBloc(MedicineIntakeState(medicineIntakeModelObj: MedicineIntakeModel(userRegistrationSheet: sheet)))
|
||||
..add(MedicineIntakeInitialEvent()),
|
||||
child: MedicineIntakeScreen());
|
||||
}
|
||||
@@ -31,82 +29,67 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.69,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 20.v),
|
||||
Container(
|
||||
width: 271.h,
|
||||
margin: EdgeInsets.only(left: 35.h, right: 36.h),
|
||||
child: Text("do_you_take_pills".tr,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.center,
|
||||
style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 86.v),
|
||||
_buildTextFormField(context),
|
||||
Spacer(),
|
||||
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
|
||||
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));
|
||||
}),
|
||||
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(
|
||||
builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.69, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 20.v),
|
||||
Container(
|
||||
width: 271.h,
|
||||
margin: EdgeInsets.only(left: 35.h, right: 36.h),
|
||||
child: Text("do_you_take_pills".tr,
|
||||
maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: theme.textTheme.headlineSmall)),
|
||||
SizedBox(height: 86.v),
|
||||
_buildTextFormField(context),
|
||||
Spacer(),
|
||||
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(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));
|
||||
}),
|
||||
BlocBuilder<MedicineIntakeBloc, MedicineIntakeState>(builder: (context, state) {
|
||||
return GestureDetector(
|
||||
onTap: onTapSkip(state, context),
|
||||
child: Text("skip".tr, style: theme.textTheme.bodyLarge),
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
onTapSkip(MedicineIntakeState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.medicineIntakeModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.bloodPressureScreen,
|
||||
arguments: sheet,
|
||||
UserRegistrationSheet sheet = state.medicineIntakeModelObj!.userRegistrationSheet;
|
||||
GoRouter.of(context).goNamed(
|
||||
'bloodPressureScreen',
|
||||
extra: sheet,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
onTapNext(MedicineIntakeState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet =
|
||||
state.medicineIntakeModelObj!.userRegistrationSheet;
|
||||
UserRegistrationSheet sheet = state.medicineIntakeModelObj!.userRegistrationSheet;
|
||||
sheet.aboutTakingPils = state.enterInformationController!.text;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.bloodPressureScreen,
|
||||
arguments: sheet,
|
||||
GoRouter.of(context).goNamed(
|
||||
'bloodPressureScreen',
|
||||
extra: sheet,
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -115,10 +98,8 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
|
||||
_buildAppBar(BuildContext context) {
|
||||
return CustomAppBar(
|
||||
leadingWidth: 31.h,
|
||||
leading: AppbarLeadingImage(
|
||||
imagePath: ImageConstant.imgArrowLeft,
|
||||
margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v),
|
||||
onTap: onTapBack(context)),
|
||||
leading:
|
||||
AppbarLeadingImage(imagePath: ImageConstant.imgArrowLeft, margin: EdgeInsets.only(left: 18.h, top: 15.v, bottom: 15.v), onTap: onTapBack(context)),
|
||||
centerTitle: true,
|
||||
title: AppbarTitleImage(imagePath: ImageConstant.imgLogoEatvio));
|
||||
}
|
||||
@@ -132,24 +113,19 @@ class _MedicineIntakeScreenState extends State<MedicineIntakeScreen> {
|
||||
/// Section Widget
|
||||
_buildTextFormField(BuildContext context) {
|
||||
return Column(children: [
|
||||
Text("fill_in_information".tr,
|
||||
style: CustomTextStyles.titleMediumSegoeUI),
|
||||
Text("fill_in_information".tr, style: CustomTextStyles.titleMediumSegoeUI),
|
||||
SizedBox(height: 2.v),
|
||||
BlocSelector<MedicineIntakeBloc, MedicineIntakeState,
|
||||
TextEditingController?>(
|
||||
BlocSelector<MedicineIntakeBloc, MedicineIntakeState, TextEditingController?>(
|
||||
selector: (state) => state.enterInformationController,
|
||||
builder: (context, enterInformationController) {
|
||||
return CustomTextFormField(
|
||||
controller: enterInformationController,
|
||||
hintText: "enter_information".tr,
|
||||
textInputAction: TextInputAction.done,
|
||||
maxLines: 8);
|
||||
controller: enterInformationController, hintText: "enter_information".tr, textInputAction: TextInputAction.done, maxLines: 8);
|
||||
})
|
||||
]);
|
||||
}
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/name_bloc.dart';
|
||||
import 'models/name_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -11,10 +14,8 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class NameScreen extends StatelessWidget {
|
||||
const NameScreen({Key? key}) : super(key: key);
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<NameBloc>(
|
||||
create: (context) => NameBloc(
|
||||
NameState(
|
||||
@@ -27,65 +28,55 @@ class NameScreen extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
mediaQueryData = MediaQuery.of(context);
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.1,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("what_is_your_name".tr,
|
||||
style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 93.v),
|
||||
Text("first_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.firstNameController,
|
||||
builder: (context, firstNameController) {
|
||||
return CustomTextFormField(
|
||||
controller: firstNameController,
|
||||
textInputAction: TextInputAction.done);
|
||||
}),
|
||||
SizedBox(height: 19.v),
|
||||
Text("last_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.lastNameController,
|
||||
builder: (context, lastNameController) {
|
||||
return CustomTextFormField(
|
||||
controller: lastNameController,
|
||||
);
|
||||
}),
|
||||
Spacer(),
|
||||
BlocBuilder<NameBloc, NameState>(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), // Assign callback function here
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
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.1, backgroundColor: theme.colorScheme.onPrimary, valueColor: AlwaysStoppedAnimation<Color>(appTheme.blueA400)))),
|
||||
SizedBox(height: 39.v),
|
||||
Text("what_is_your_name".tr, style: theme.textTheme.headlineSmall),
|
||||
SizedBox(height: 93.v),
|
||||
Text("first_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 3.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.firstNameController,
|
||||
builder: (context, firstNameController) {
|
||||
return CustomTextFormField(controller: firstNameController, textInputAction: TextInputAction.done);
|
||||
}),
|
||||
SizedBox(height: 19.v),
|
||||
Text("last_name".tr, style: theme.textTheme.bodyLarge),
|
||||
SizedBox(height: 5.v),
|
||||
BlocSelector<NameBloc, NameState, TextEditingController?>(
|
||||
selector: (state) => state.lastNameController,
|
||||
builder: (context, lastNameController) {
|
||||
return CustomTextFormField(
|
||||
controller: lastNameController,
|
||||
);
|
||||
}),
|
||||
]))));
|
||||
Spacer(),
|
||||
BlocBuilder<NameBloc, NameState>(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), // Assign callback function here
|
||||
);
|
||||
}),
|
||||
])));
|
||||
}
|
||||
|
||||
/// Section Widget
|
||||
@@ -93,33 +84,25 @@ class NameScreen extends StatelessWidget {
|
||||
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)),
|
||||
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();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
|
||||
_onTapNext(BuildContext context, NameState state) {
|
||||
if (state.firstNameController != null && state.lastNameController != null) {
|
||||
List<String> errors = validateFields(
|
||||
state.firstNameController!.text, state.lastNameController!.text);
|
||||
List<String> errors = validateFields(state.firstNameController!.text, state.lastNameController!.text);
|
||||
|
||||
if (errors.isEmpty) {
|
||||
UserRegistrationSheet sheet = state.nameModelObj!.userRegistrationSheet;
|
||||
sheet.firstName = state.firstNameController!.text;
|
||||
sheet.lastName = state.lastNameController!.text;
|
||||
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.genderScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('genderScreen', extra: sheet);
|
||||
} else {
|
||||
String errorMessage = '';
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import 'package:eatvio_app/app_router.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import '/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/registration/splash_screen/models/splash_model.dart';
|
||||
|
||||
part 'splash_event.dart';
|
||||
|
||||
part 'splash_state.dart';
|
||||
|
||||
/// A bloc that manages the state of a Splash according to the event that is dispatched to it.
|
||||
@@ -16,9 +20,7 @@ class SplashBloc extends Bloc<SplashEvent, SplashState> {
|
||||
Emitter<SplashState> emit,
|
||||
) async {
|
||||
Future.delayed(const Duration(milliseconds: 3000), () {
|
||||
NavigatorService.popAndPushNamed(
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
AppRouter.navigatorKey.currentContext?.goNamed('myProfileScreen');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
import 'bloc/weight_bloc.dart';
|
||||
import 'models/weight_model.dart';
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
@@ -13,98 +15,90 @@ import 'package:flutter/material.dart';
|
||||
class WeightScreen extends StatelessWidget {
|
||||
const WeightScreen({Key? key}) : super(key: key);
|
||||
|
||||
static Widget builder(BuildContext context) {
|
||||
final sheet =
|
||||
ModalRoute.of(context)!.settings.arguments as UserRegistrationSheet;
|
||||
static Widget builder(BuildContext context, sheet) {
|
||||
return BlocProvider<WeightBloc>(
|
||||
create: (context) => WeightBloc(WeightState(
|
||||
weightModelObj: WeightModel(userRegistrationSheet: sheet)))
|
||||
..add(WeightInitialEvent()),
|
||||
create: (context) => WeightBloc(WeightState(weightModelObj: WeightModel(userRegistrationSheet: sheet)))..add(WeightInitialEvent()),
|
||||
child: WeightScreen());
|
||||
}
|
||||
|
||||
@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,
|
||||
),
|
||||
return 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<Color>(
|
||||
appTheme.blueA400,
|
||||
),
|
||||
),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.h),
|
||||
child: LinearProgressIndicator(
|
||||
value: 0.55,
|
||||
backgroundColor: theme.colorScheme.onPrimary,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
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),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
builder: (context, state) {
|
||||
return NextStepButton(
|
||||
text: "continue".tr.toUpperCase(),
|
||||
margin: EdgeInsets.only(
|
||||
left: 16.h,
|
||||
right: 16.h,
|
||||
bottom: 50.v,
|
||||
),
|
||||
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,
|
||||
),
|
||||
buttonStyle: CustomButtonStyles.outlinePrimaryTL15,
|
||||
onPressed: onTapNext(state, context),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4.v),
|
||||
BlocBuilder<WeightBloc, WeightState>(builder: (context, state) {
|
||||
return CustomTextFormField(
|
||||
width: 150.h,
|
||||
textInputAction: TextInputAction.done,
|
||||
controller: state.weightController,
|
||||
keyboardType: TextInputType.number,
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
FilteringTextInputFormatter.digitsOnly,
|
||||
],
|
||||
);
|
||||
})
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
BlocBuilder<WeightBloc, WeightState>(
|
||||
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),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -113,11 +107,7 @@ class WeightScreen extends StatelessWidget {
|
||||
onTapNext(WeightState state, BuildContext context) {
|
||||
return () {
|
||||
UserRegistrationSheet sheet = state.weightModelObj!.userRegistrationSheet;
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.heightScreen,
|
||||
arguments: sheet,
|
||||
);
|
||||
GoRouter.of(context).goNamed('heightScreen', extra: sheet);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -125,10 +115,8 @@ class WeightScreen extends StatelessWidget {
|
||||
_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)),
|
||||
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));
|
||||
}
|
||||
@@ -141,6 +129,6 @@ class WeightScreen extends StatelessWidget {
|
||||
|
||||
/// Navigates to the previous screen.
|
||||
onTapArrowLeft(BuildContext context) {
|
||||
NavigatorService.goBack();
|
||||
GoRouter.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
import 'package:eatvio_app/presentation/diets/diet_select_screen/diet_select_screen.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:eatvio_app/presentation/registration/date_of_birth_screen/date_of_birth_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/city_of_living_screen/city_of_living_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/body_circumferences_screen/body_circumferences_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/weight_screen/weight_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/allergies_screen/allergies_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/medicine_intake_screen/medicine_intake_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/splash_screen/splash_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/gender_screen/gender_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/blood_pressure_screen/blood_pressure_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/favorite_sports_screen/favorite_sports_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/favorite_foods_screen/favorite_foods_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/additional_information_screen/additional_information_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/language_select_screen/language_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/height_screen/height_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/credentials_screen/credentials_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/name_screen/name_screen.dart';
|
||||
import 'package:eatvio_app/presentation/registration/app_navigation_screen/app_navigation_screen.dart';
|
||||
import 'package:eatvio_app/presentation/auth/auth_screen/auth_screen.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_profile_screen.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/my_settings_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diary/diary_edit_screen/diary_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_screen/chat_screen.dart';
|
||||
import 'package:eatvio_app/presentation/chat/chat_select_screen/chat_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/feed_screen/feed_screen.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_select_screen/recipe_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_select_screen/plan_select_screen.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_edit_screen/plan_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_create_screen/plan_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_show_screen/diet_show_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_edit_screen/diet_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/diets/diet_create_screen/diet_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/plans/plan_show_screen/plan_show_screen.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_show_screen/recipe_show_screen.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_create_screen/recipe_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/recipe/recipe_edit_screen/recipe_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_edit_screen/blog_post_edit_screen.dart';
|
||||
import 'package:eatvio_app/presentation/feed/blog_post_create_screen/blog_post_create_screen.dart';
|
||||
import 'package:eatvio_app/presentation/glossary/glossary_screen/glossary_screen.dart';
|
||||
|
||||
class AppRoutes {
|
||||
// REGISTRATION
|
||||
|
||||
static const String dateOfBirthScreen = '/date_of_birth_screen';
|
||||
|
||||
static const String cityOfLivingScreen = '/city_of_living_screen';
|
||||
|
||||
static const String bodyCircumferencesScreen = '/body_circumferences_screen';
|
||||
|
||||
static const String weightScreen = '/weight_screen';
|
||||
|
||||
static const String heightScreen = '/height_screen';
|
||||
|
||||
static const String allergiesScreen = '/allergies_screen';
|
||||
|
||||
static const String medicineIntakeScreen = '/medicine_intake_screen';
|
||||
|
||||
static const String splashScreen = '/splash_screen';
|
||||
|
||||
static const String genderScreen = '/gender_screen';
|
||||
|
||||
static const String bloodPressureScreen = '/blood_pressure_screen';
|
||||
|
||||
static const String favoriteSportsScreen = '/favorite_sports_screen';
|
||||
|
||||
static const String favoriteFoodsScreen = '/favorite_foods_screen';
|
||||
|
||||
static const String scheduleScreen = '/schedule_screen';
|
||||
|
||||
static const String additionalInformationScreen =
|
||||
'/additional_information_screen';
|
||||
|
||||
static const String languageSelectScreen = '/language_select_screen';
|
||||
|
||||
static const String nameScreen = '/name_screen';
|
||||
|
||||
static const String credentialsScreen = '/credentials_screen';
|
||||
|
||||
static const String appNavigationScreen = '/app_navigation_screen';
|
||||
|
||||
static const String authScreen = '/auth_screen';
|
||||
|
||||
static const String initialRoute = '/initialRoute';
|
||||
|
||||
//PROFILE
|
||||
static const String myProfile = '/myProfile';
|
||||
|
||||
static const String mySettings = '/mySettings';
|
||||
|
||||
static const String diaryEdit = '/diaryEdit';
|
||||
|
||||
static const String chatScreen = '/chat';
|
||||
|
||||
static const String chatSelectScreen = '/chatSelect';
|
||||
|
||||
static const String feedScreen = '/feed';
|
||||
|
||||
static const String blogPostScreen = '/blogPost';
|
||||
|
||||
static const String blogPostEditScreen = '/blogPostEdit';
|
||||
|
||||
static const String blogPostCreateScreen = '/blogPostCreate';
|
||||
|
||||
static const String recipeSelectScreen = '/recipeSelect';
|
||||
|
||||
static const String recipeScreen = '/recipe';
|
||||
|
||||
static const String recipeEditScreen = '/recipeEdit';
|
||||
|
||||
static const String recipeCreateScreen = '/recipeCreate';
|
||||
|
||||
static const String dietSelectScreen = '/dietSelect';
|
||||
|
||||
static const String dietScreen = '/diet';
|
||||
|
||||
static const String dietEditScreen = '/dietEdit';
|
||||
|
||||
static const String dietCreateScreen = '/dietCreate';
|
||||
|
||||
static const String planSelectScreen = '/planSelect';
|
||||
|
||||
static const String planScreen = '/plan';
|
||||
|
||||
static const String planEditScreen = '/planEdit';
|
||||
|
||||
static const String planCreateScreen = '/planCreate';
|
||||
|
||||
static const String glossaryScreen = '/glossary';
|
||||
|
||||
static Map<String, WidgetBuilder> get routes => {
|
||||
dateOfBirthScreen: (context) =>
|
||||
_buildFadeRoute(context, DateOfBirthScreen.builder),
|
||||
cityOfLivingScreen: (context) =>
|
||||
_buildFadeRoute(context, CityOfLivingScreen.builder),
|
||||
bodyCircumferencesScreen: (context) =>
|
||||
_buildFadeRoute(context, BodyCircumferencesScreen.builder),
|
||||
weightScreen: (context) =>
|
||||
_buildFadeRoute(context, WeightScreen.builder),
|
||||
heightScreen: (context) =>
|
||||
_buildFadeRoute(context, HeightScreen.builder),
|
||||
nameScreen: (context) => _buildFadeRoute(context, NameScreen.builder),
|
||||
credentialsScreen: (context) =>
|
||||
_buildFadeRoute(context, CredentialsScreen.builder),
|
||||
allergiesScreen: (context) =>
|
||||
_buildFadeRoute(context, AllergiesScreen.builder),
|
||||
medicineIntakeScreen: (context) =>
|
||||
_buildFadeRoute(context, MedicineIntakeScreen.builder),
|
||||
splashScreen: (context) =>
|
||||
_buildFadeRoute(context, SplashScreen.builder),
|
||||
authScreen: (context) => _buildFadeRoute(context, AuthScreen.builder),
|
||||
genderScreen: (context) =>
|
||||
_buildFadeRoute(context, GenderScreen.builder),
|
||||
bloodPressureScreen: (context) =>
|
||||
_buildFadeRoute(context, BloodPressureScreen.builder),
|
||||
favoriteSportsScreen: (context) =>
|
||||
_buildFadeRoute(context, FavoriteSportsScreen.builder),
|
||||
favoriteFoodsScreen: (context) =>
|
||||
_buildFadeRoute(context, FavoriteFoodsScreen.builder),
|
||||
additionalInformationScreen: (context) =>
|
||||
_buildFadeRoute(context, AdditionalInformationScreen.builder),
|
||||
languageSelectScreen: (context) =>
|
||||
_buildFadeRoute(context, LanguageSelectScreen.builder),
|
||||
appNavigationScreen: (context) =>
|
||||
_buildFadeRoute(context, AppNavigationScreen.builder),
|
||||
initialRoute: (context) =>
|
||||
_buildFadeRoute(context, SplashScreen.builder),
|
||||
myProfile: (context) =>
|
||||
_buildFadeRoute(context, MyProfileScreen.builder),
|
||||
mySettings: (context) =>
|
||||
_buildFadeRoute(context, MySettingsScreen.builder),
|
||||
diaryEdit: (context) =>
|
||||
_buildFadeRoute(context, DiaryEditScreen.builder),
|
||||
chatScreen: (context) => _buildFadeRoute(context, ChatScreen.builder),
|
||||
chatSelectScreen: (context) =>
|
||||
_buildFadeRoute(context, ChatSelectScreen.builder),
|
||||
recipeSelectScreen: (context) =>
|
||||
_buildFadeRoute(context, RecipeSelectScreen.builder),
|
||||
recipeScreen: (context) =>
|
||||
_buildFadeRoute(context, RecipeScreen.builder),
|
||||
recipeEditScreen: (context) =>
|
||||
_buildFadeRoute(context, RecipeEditScreen.builder),
|
||||
recipeCreateScreen: (context) =>
|
||||
_buildFadeRoute(context, RecipeCreateScreen.builder),
|
||||
dietSelectScreen: (context) =>
|
||||
_buildFadeRoute(context, DietSelectScreen.builder),
|
||||
dietScreen: (context) => _buildFadeRoute(context, DietScreen.builder),
|
||||
dietEditScreen: (context) =>
|
||||
_buildFadeRoute(context, DietEditScreen.builder),
|
||||
dietCreateScreen: (context) =>
|
||||
_buildFadeRoute(context, DietCreateScreen.builder),
|
||||
planSelectScreen: (context) =>
|
||||
_buildFadeRoute(context, PlanSelectScreen.builder),
|
||||
planScreen: (context) => _buildFadeRoute(context, PlanScreen.builder),
|
||||
planEditScreen: (context) =>
|
||||
_buildFadeRoute(context, PlanEditScreen.builder),
|
||||
planCreateScreen: (context) =>
|
||||
_buildFadeRoute(context, PlanCreateScreen.builder),
|
||||
feedScreen: (context) => _buildFadeRoute(context, FeedScreen.builder),
|
||||
// blogPostScreen: (context) =>
|
||||
// _buildFadeRoute(context, BlogPostScreen.builder),
|
||||
blogPostEditScreen: (context) =>
|
||||
_buildFadeRoute(context, BlogPostEditScreen.builder),
|
||||
blogPostCreateScreen: (context) =>
|
||||
_buildFadeRoute(context, BlogPostCreateScreen.builder),
|
||||
glossaryScreen: (context) =>
|
||||
_buildFadeRoute(context, GlossaryScreen.builder),
|
||||
};
|
||||
|
||||
static Widget _buildFadeRoute(BuildContext context, WidgetBuilder builder) {
|
||||
return FadeTransition(
|
||||
opacity: AlwaysStoppedAnimation<double>(1.0),
|
||||
child: builder(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class FadeTransitionPage extends PageRouteBuilder {
|
||||
final WidgetBuilder builder;
|
||||
|
||||
FadeTransitionPage({required this.builder})
|
||||
: super(
|
||||
pageBuilder: (BuildContext context, Animation<double> animation,
|
||||
Animation<double> secondaryAnimation) {
|
||||
return builder(context);
|
||||
},
|
||||
transitionsBuilder: (BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child) {
|
||||
return FadeTransition(opacity: animation, child: child);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import '../../core/app_export.dart';
|
||||
|
||||
/// Helper class for managing themes and colors.
|
||||
@@ -50,6 +51,13 @@ class ThemeHelper {
|
||||
colorScheme: colorScheme,
|
||||
textTheme: TextThemes.textTheme(colorScheme),
|
||||
scaffoldBackgroundColor: colorScheme.onPrimary,
|
||||
appBarTheme: AppBarTheme(
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
statusBarBrightness: Brightness.light,
|
||||
systemNavigationBarColor: Colors.white,
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: Colors.transparent,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@@ -31,10 +30,6 @@ class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarIconBrightness: Brightness.dark,
|
||||
statusBarBrightness: Brightness.light,
|
||||
),
|
||||
toolbarHeight: height ?? 56.v,
|
||||
automaticallyImplyLeading: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
|
||||
@@ -73,13 +73,21 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
items: [
|
||||
BottomNavigationBarItem(
|
||||
label: '',
|
||||
icon: SvgPicture.asset(ImageConstant.imgLogo),
|
||||
icon: SvgPicture.asset(
|
||||
ImageConstant.imgLogo,
|
||||
),
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: 'Лента',
|
||||
icon: SvgPicture.asset(ImageConstant.imgFeed),
|
||||
icon: SvgPicture.asset(
|
||||
width: 24,
|
||||
height: 24,
|
||||
ImageConstant.imgFeed,
|
||||
),
|
||||
activeIcon: SvgPicture.asset(
|
||||
ImageConstant.imgFeed,
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
appTheme.blueA400,
|
||||
BlendMode.srcIn,
|
||||
@@ -88,9 +96,15 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: "diary".tr,
|
||||
icon: SvgPicture.asset(ImageConstant.imgDiary),
|
||||
icon: SvgPicture.asset(
|
||||
ImageConstant.imgDiary,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
activeIcon: SvgPicture.asset(
|
||||
ImageConstant.imgDiary,
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
appTheme.blueA400,
|
||||
BlendMode.srcIn,
|
||||
@@ -99,9 +113,15 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: "chat".tr,
|
||||
icon: SvgPicture.asset(ImageConstant.imgChat),
|
||||
icon: SvgPicture.asset(
|
||||
ImageConstant.imgChat,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
activeIcon: SvgPicture.asset(
|
||||
ImageConstant.imgChat,
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
appTheme.blueA400,
|
||||
BlendMode.srcIn,
|
||||
@@ -110,9 +130,15 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
label: '',
|
||||
icon: SvgPicture.asset(ImageConstant.imgBell),
|
||||
icon: SvgPicture.asset(
|
||||
ImageConstant.imgBell,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
activeIcon: SvgPicture.asset(
|
||||
ImageConstant.imgBell,
|
||||
width: 24,
|
||||
height: 24,
|
||||
colorFilter: ColorFilter.mode(
|
||||
appTheme.blueA400,
|
||||
BlendMode.srcIn,
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:eatvio_app/core/app_export.dart';
|
||||
import 'package:eatvio_app/presentation/profile/my_profile_screen/bloc/my_profile_bloc.dart';
|
||||
import 'package:eatvio_app/widgets/custom_hyper_switch.dart';
|
||||
import 'package:eatvio_app/widgets/custom_hypo_switch.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:eatvio_app/widgets/next_step_button.dart';
|
||||
import 'dart:convert';
|
||||
@@ -395,10 +396,7 @@ class _ExpandableListState extends State<ExpandableList> {
|
||||
}
|
||||
|
||||
void _navigateToProfilePage() {
|
||||
Navigator.pushNamed(
|
||||
context,
|
||||
AppRoutes.myProfile,
|
||||
);
|
||||
GoRouter.of(context).go('/my-profile-screen');
|
||||
}
|
||||
|
||||
String _getErrorMessage(http.Response response) {
|
||||
|
||||
Reference in New Issue
Block a user