diff --git a/StudioProjects/yimaru_app/assets/fonts/Aeonik-Regular.ttf b/StudioProjects/yimaru_app/assets/fonts/Aeonik-Regular.ttf
new file mode 100644
index 0000000..4d6eaf5
Binary files /dev/null and b/StudioProjects/yimaru_app/assets/fonts/Aeonik-Regular.ttf differ
diff --git a/StudioProjects/yimaru_app/assets/icons/alert.svg b/StudioProjects/yimaru_app/assets/icons/alert.svg
new file mode 100644
index 0000000..0cac7fa
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/alert.svg
@@ -0,0 +1,5 @@
+
diff --git a/StudioProjects/yimaru_app/assets/icons/b1.svg b/StudioProjects/yimaru_app/assets/icons/b1.svg
new file mode 100644
index 0000000..4a75083
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/b1.svg
@@ -0,0 +1,10 @@
+
+
+
diff --git a/StudioProjects/yimaru_app/assets/icons/complete.svg b/StudioProjects/yimaru_app/assets/icons/complete.svg
new file mode 100644
index 0000000..4bf1bc3
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/complete.svg
@@ -0,0 +1,5 @@
+
diff --git a/StudioProjects/yimaru_app/assets/icons/logo.svg b/StudioProjects/yimaru_app/assets/icons/logo.svg
new file mode 100644
index 0000000..d6ffb10
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/logo.svg
@@ -0,0 +1,15 @@
+
+
+
diff --git a/StudioProjects/yimaru_app/assets/icons/mascot.svg b/StudioProjects/yimaru_app/assets/icons/mascot.svg
new file mode 100644
index 0000000..4641e42
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/mascot.svg
@@ -0,0 +1,8 @@
+
diff --git a/StudioProjects/yimaru_app/assets/icons/progress_indicator.svg b/StudioProjects/yimaru_app/assets/icons/progress_indicator.svg
new file mode 100644
index 0000000..ad20a93
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/progress_indicator.svg
@@ -0,0 +1,4 @@
+
diff --git a/StudioProjects/yimaru_app/assets/icons/question.svg b/StudioProjects/yimaru_app/assets/icons/question.svg
new file mode 100644
index 0000000..cb9a01d
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/question.svg
@@ -0,0 +1,8 @@
+
diff --git a/StudioProjects/yimaru_app/assets/icons/success.svg b/StudioProjects/yimaru_app/assets/icons/success.svg
new file mode 100644
index 0000000..4bf1bc3
--- /dev/null
+++ b/StudioProjects/yimaru_app/assets/icons/success.svg
@@ -0,0 +1,5 @@
+
diff --git a/StudioProjects/yimaru_app/assets/images/onboarding_1.png b/StudioProjects/yimaru_app/assets/images/onboarding_1.png
new file mode 100644
index 0000000..8650c79
Binary files /dev/null and b/StudioProjects/yimaru_app/assets/images/onboarding_1.png differ
diff --git a/StudioProjects/yimaru_app/assets/images/onboarding_2.png b/StudioProjects/yimaru_app/assets/images/onboarding_2.png
new file mode 100644
index 0000000..a53af54
Binary files /dev/null and b/StudioProjects/yimaru_app/assets/images/onboarding_2.png differ
diff --git a/StudioProjects/yimaru_app/assets/images/onboarding_3.png b/StudioProjects/yimaru_app/assets/images/onboarding_3.png
new file mode 100644
index 0000000..4d300f4
Binary files /dev/null and b/StudioProjects/yimaru_app/assets/images/onboarding_3.png differ
diff --git a/StudioProjects/yimaru_app/lib/app/app.dart b/StudioProjects/yimaru_app/lib/app/app.dart
index 4e96242..c6a337a 100644
--- a/StudioProjects/yimaru_app/lib/app/app.dart
+++ b/StudioProjects/yimaru_app/lib/app/app.dart
@@ -1,17 +1,18 @@
import 'package:yimaru_app/ui/bottom_sheets/notice/notice_sheet.dart';
import 'package:yimaru_app/ui/dialogs/info_alert/info_alert_dialog.dart';
import 'package:yimaru_app/ui/views/home/home_view.dart';
-import 'package:yimaru_app/ui/views/startup/startup_view.dart';
import 'package:stacked/stacked_annotations.dart';
import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart';
+import 'package:yimaru_app/ui/views/startup/startup_view.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/language_selector.dart';
// @stacked-import
@StackedApp(
routes: [
MaterialRoute(page: HomeView),
- MaterialRoute(page: StartupView),
MaterialRoute(page: OnboardingView),
+ MaterialRoute(page: StartupView),
// @stacked-route
],
dependencies: [
diff --git a/StudioProjects/yimaru_app/lib/app/app.router.dart b/StudioProjects/yimaru_app/lib/app/app.router.dart
index b85ee7b..b3725f5 100644
--- a/StudioProjects/yimaru_app/lib/app/app.router.dart
+++ b/StudioProjects/yimaru_app/lib/app/app.router.dart
@@ -5,25 +5,28 @@
// **************************************************************************
// ignore_for_file: no_leading_underscores_for_library_prefixes
-import 'package:flutter/material.dart' as _i5;
+import 'package:flutter/material.dart' as _i6;
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart' as _i1;
-import 'package:stacked_services/stacked_services.dart' as _i6;
+import 'package:stacked_services/stacked_services.dart' as _i7;
import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2;
-import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i4;
-import 'package:yimaru_app/ui/views/startup/startup_view.dart' as _i3;
+import 'package:yimaru_app/ui/views/onboarding/screens/language_selector.dart' as _i5;
+import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i3;
+import 'package:yimaru_app/ui/views/startup/startup_view.dart' as _i4;
class Routes {
static const homeView = '/home-view';
+ static const onboardingView = '/onboarding-view';
+
static const startupView = '/startup-view';
- static const onboardingView = '/onboarding-view';
+
static const all = {
homeView,
- startupView,
onboardingView,
+ startupView,
};
}
@@ -34,31 +37,38 @@ class StackedRouter extends _i1.RouterBase {
page: _i2.HomeView,
),
_i1.RouteDef(
- Routes.startupView,
- page: _i3.StartupView,
+ Routes.onboardingView,
+ page: _i3.OnboardingView,
),
_i1.RouteDef(
- Routes.onboardingView,
- page: _i4.OnboardingView,
+ Routes.startupView,
+ page: _i4.StartupView,
),
+
];
final _pagesMap = {
_i2.HomeView: (data) {
- return _i5.MaterialPageRoute(
+ return _i6.MaterialPageRoute(
builder: (context) => const _i2.HomeView(),
settings: data,
);
},
- _i3.StartupView: (data) {
- return _i5.MaterialPageRoute(
- builder: (context) => const _i3.StartupView(),
+ _i3.OnboardingView: (data) {
+ return _i6.MaterialPageRoute(
+ builder: (context) => const _i3.OnboardingView(),
settings: data,
);
},
- _i4.OnboardingView: (data) {
- return _i5.MaterialPageRoute(
- builder: (context) => const _i4.OnboardingView(),
+ _i4.StartupView: (data) {
+ return _i6.MaterialPageRoute(
+ builder: (context) => const _i4.StartupView(),
+ settings: data,
+ );
+ },
+ _i5.LanguageSelector: (data) {
+ return _i6.MaterialPageRoute(
+ builder: (context) => const _i5.LanguageSelector(),
settings: data,
);
},
@@ -71,7 +81,7 @@ class StackedRouter extends _i1.RouterBase {
Map get pagesMap => _pagesMap;
}
-extension NavigatorStateExtension on _i6.NavigationService {
+extension NavigatorStateExtension on _i7.NavigationService {
Future navigateToHomeView([
int? routerId,
bool preventDuplicates = true,
@@ -86,20 +96,6 @@ extension NavigatorStateExtension on _i6.NavigationService {
transition: transition);
}
- Future navigateToStartupView([
- int? routerId,
- bool preventDuplicates = true,
- Map? parameters,
- Widget Function(BuildContext, Animation, Animation, Widget)?
- transition,
- ]) async {
- return navigateTo(Routes.startupView,
- id: routerId,
- preventDuplicates: preventDuplicates,
- parameters: parameters,
- transition: transition);
- }
-
Future navigateToOnboardingView([
int? routerId,
bool preventDuplicates = true,
@@ -114,6 +110,22 @@ extension NavigatorStateExtension on _i6.NavigationService {
transition: transition);
}
+ Future navigateToStartupView([
+ int? routerId,
+ bool preventDuplicates = true,
+ Map? parameters,
+ Widget Function(BuildContext, Animation, Animation, Widget)?
+ transition,
+ ]) async {
+ return navigateTo(Routes.startupView,
+ id: routerId,
+ preventDuplicates: preventDuplicates,
+ parameters: parameters,
+ transition: transition);
+ }
+
+
+
Future replaceWithHomeView([
int? routerId,
bool preventDuplicates = true,
@@ -128,6 +140,20 @@ extension NavigatorStateExtension on _i6.NavigationService {
transition: transition);
}
+ Future replaceWithOnboardingView([
+ int? routerId,
+ bool preventDuplicates = true,
+ Map? parameters,
+ Widget Function(BuildContext, Animation, Animation, Widget)?
+ transition,
+ ]) async {
+ return replaceWith(Routes.onboardingView,
+ id: routerId,
+ preventDuplicates: preventDuplicates,
+ parameters: parameters,
+ transition: transition);
+ }
+
Future replaceWithStartupView([
int? routerId,
bool preventDuplicates = true,
@@ -142,17 +168,5 @@ extension NavigatorStateExtension on _i6.NavigationService {
transition: transition);
}
- Future replaceWithOnboardingView([
- int? routerId,
- bool preventDuplicates = true,
- Map? parameters,
- Widget Function(BuildContext, Animation, Animation, Widget)?
- transition,
- ]) async {
- return replaceWith(Routes.onboardingView,
- id: routerId,
- preventDuplicates: preventDuplicates,
- parameters: parameters,
- transition: transition);
- }
+
}
diff --git a/StudioProjects/yimaru_app/lib/main.dart b/StudioProjects/yimaru_app/lib/main.dart
index 9d7a4de..d23ff42 100644
--- a/StudioProjects/yimaru_app/lib/main.dart
+++ b/StudioProjects/yimaru_app/lib/main.dart
@@ -20,6 +20,7 @@ class MainApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: Routes.startupView,
+ theme: ThemeData(fontFamily: 'Aeonik'),
onGenerateRoute: StackedRouter().onGenerateRoute,
navigatorKey: StackedService.navigatorKey,
navigatorObservers: [StackedService.routeObserver],
diff --git a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.dart b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.dart
index e4200db..4206bcc 100644
--- a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.dart
+++ b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.dart
@@ -1,25 +1,47 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked/stacked_annotations.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/age_group_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/country_region_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/educational_background_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/full_name_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/learning_goal_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/learning_reason_form.dart';
-import 'package:yimaru_app/ui/views/onboarding/forms/occupation_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/assessment_completion.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/assessment_failure.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/assessment_intro.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/assessment_result.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/first_assessment_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/fourth_assessment_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/result_analysis.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/retake_assessment.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/second_assessment_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/start_lesson.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/assessment/third_assessment_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/age_group_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/challenge_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/country_region_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/educational_background_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/full_name_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/learning_goal_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/learning_reason_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/occupation_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/forms/topic_form.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/language_selector.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/welcome/first_welcome.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/welcome/second_welcome.dart';
+import 'package:yimaru_app/ui/views/onboarding/screens/welcome/third_welcome.dart';
import '../../common/validators/onboarding_form_validator.dart';
import 'onboarding_viewmodel.dart';
import 'onboarding_view.form.dart';
@FormView(fields: [
+ FormTextField(
+ name: 'answer', validator: OnboardingFormValidator.validateForm),
FormTextField(
name: 'fullName', validator: OnboardingFormValidator.validateForm),
+ FormTextField(
+ name: 'challenge', validator: OnboardingFormValidator.validateForm),
FormTextField(
name: 'occupation', validator: OnboardingFormValidator.validateForm),
FormTextField(
- name: 'learningReason', validator: OnboardingFormValidator.validateForm)
+ name: 'learningReason', validator: OnboardingFormValidator.validateForm),
+ FormTextField(name: 'topic', validator: OnboardingFormValidator.validateForm),
])
class OnboardingView extends StackedView
with $OnboardingView {
@@ -31,42 +53,99 @@ class OnboardingView extends StackedView
OnboardingViewModel viewModel,
Widget? child,
) =>
- _buildOnboardingScreens(viewModel);
+ _buildOnboardingScreensWrapper(viewModel);
+
+ Widget _buildOnboardingScreensWrapper(OnboardingViewModel viewModel) =>
+ PopScope(
+ canPop: false,
+ onPopInvokedWithResult: (value, data) => viewModel.pop(
+ language: viewModel.currentPage == 23 ? true : false),
+ child: _buildOnboardingScreens(viewModel));
Widget _buildOnboardingScreens(OnboardingViewModel viewModel) => IndexedStack(
- index: viewModel.currentStep,
+ index: viewModel.currentPage,
children: _buildScreens(),
);
List _buildScreens() => [
+ _buildFirstWelcome(),
+ _buildSecondWelcome(),
+ _buildThirdWelcome(),
_buildFullNameForm(),
_buildEducationalBackgroundForm(),
_buildAgeGroupForm(),
_buildOccupationForm(),
_buildCountryRegionForm(),
_buildLearningGoalForm(),
- _buildLearningReasonForm()
+ _buildLearningReasonForm(),
+ _buildChallengeForm(),
+ _buildTopicForm(),
+ _buildAssessmentIntro(),
+ _buildFirstAssessmentForm(),
+ _buildSecondAssessment(),
+ _buildThirdAssessment(),
+ _buildFourthAssessment(),
+ _buildAssessmentFailure(),
+ _buildRetakeAssessment(),
+ _buildResultAnalysis(),
+ _buildAssessmentCompletion(),
+ _buildAssessmentResult(),
+ _buildStartLesson(),
+ _buildLanguageSelector()
];
- Widget _buildFullNameForm() => FullNameForm(
- fullNameController: fullNameController,
- );
+ Widget _buildFirstWelcome() => const FirstWelcome();
+
+ Widget _buildSecondWelcome() => const SecondWelcome();
+
+ Widget _buildThirdWelcome() => const ThirdWelcome();
+
+ Widget _buildFullNameForm() =>
+ FullNameForm(fullNameController: fullNameController);
Widget _buildEducationalBackgroundForm() => const EducationalBackgroundForm();
Widget _buildAgeGroupForm() => const AgeGroupForm();
- Widget _buildOccupationForm() => OccupationForm(
- occupationController: occupationController,
- );
+ Widget _buildOccupationForm() =>
+ OccupationForm(occupationController: occupationController);
Widget _buildCountryRegionForm() => const CountryRegionForm();
Widget _buildLearningGoalForm() => const LearningGoalForm();
- Widget _buildLearningReasonForm() => LearningReasonForm(
- learningReasonController: learningReasonController,
- );
+ Widget _buildLearningReasonForm() =>
+ LearningReasonForm(learningReasonController: learningReasonController);
+
+ Widget _buildChallengeForm() =>
+ ChallengeForm(challengeController: challengeController);
+
+ Widget _buildTopicForm() => TopicForm(topicController: topicController);
+
+ Widget _buildAssessmentIntro() => const AssessmentIntro();
+
+ Widget _buildFirstAssessmentForm() =>
+ FirstAssessmentForm(answerController: answerController);
+
+ Widget _buildSecondAssessment() => const SecondAssessmentForm();
+
+ Widget _buildThirdAssessment() => const ThirdAssessmentForm();
+
+ Widget _buildFourthAssessment() => const FourthAssessmentForm();
+
+ Widget _buildAssessmentFailure() => const AssessmentFailure();
+
+ Widget _buildRetakeAssessment() => const RetakeAssessment();
+
+ Widget _buildResultAnalysis() => const ResultAnalysis();
+
+ Widget _buildAssessmentCompletion() => const AssessmentCompletion();
+
+ Widget _buildAssessmentResult() => const AssessmentResult();
+
+ Widget _buildStartLesson() => const StartLesson();
+
+ Widget _buildLanguageSelector() => const LanguageSelector();
@override
void onViewModelReady(OnboardingViewModel viewModel) {
diff --git a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.form.dart b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.form.dart
index 58d4ae0..c2c4d89 100644
--- a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.form.dart
+++ b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_view.form.dart
@@ -12,9 +12,12 @@ import 'package:yimaru_app/ui/common/validators/onboarding_form_validator.dart';
const bool _autoTextFieldValidation = true;
+const String AnswerValueKey = 'answer';
const String FullNameValueKey = 'fullName';
+const String ChallengeValueKey = 'challenge';
const String OccupationValueKey = 'occupation';
const String LearningReasonValueKey = 'learningReason';
+const String TopicValueKey = 'topic';
final Map _OnboardingViewTextEditingControllers =
{};
@@ -22,23 +25,35 @@ final Map _OnboardingViewTextEditingControllers =
final Map _OnboardingViewFocusNodes = {};
final Map _OnboardingViewTextValidations = {
+ AnswerValueKey: OnboardingFormValidator.validateForm,
FullNameValueKey: OnboardingFormValidator.validateForm,
+ ChallengeValueKey: OnboardingFormValidator.validateForm,
OccupationValueKey: OnboardingFormValidator.validateForm,
LearningReasonValueKey: OnboardingFormValidator.validateForm,
+ TopicValueKey: OnboardingFormValidator.validateForm,
};
mixin $OnboardingView {
+ TextEditingController get answerController =>
+ _getFormTextEditingController(AnswerValueKey);
TextEditingController get fullNameController =>
_getFormTextEditingController(FullNameValueKey);
+ TextEditingController get challengeController =>
+ _getFormTextEditingController(ChallengeValueKey);
TextEditingController get occupationController =>
_getFormTextEditingController(OccupationValueKey);
TextEditingController get learningReasonController =>
_getFormTextEditingController(LearningReasonValueKey);
+ TextEditingController get topicController =>
+ _getFormTextEditingController(TopicValueKey);
+ FocusNode get answerFocusNode => _getFormFocusNode(AnswerValueKey);
FocusNode get fullNameFocusNode => _getFormFocusNode(FullNameValueKey);
+ FocusNode get challengeFocusNode => _getFormFocusNode(ChallengeValueKey);
FocusNode get occupationFocusNode => _getFormFocusNode(OccupationValueKey);
FocusNode get learningReasonFocusNode =>
_getFormFocusNode(LearningReasonValueKey);
+ FocusNode get topicFocusNode => _getFormFocusNode(TopicValueKey);
TextEditingController _getFormTextEditingController(
String key, {
@@ -64,9 +79,12 @@ mixin $OnboardingView {
/// Registers a listener on every generated controller that calls [model.setData()]
/// with the latest textController values
void syncFormWithViewModel(FormStateHelper model) {
+ answerController.addListener(() => _updateFormData(model));
fullNameController.addListener(() => _updateFormData(model));
+ challengeController.addListener(() => _updateFormData(model));
occupationController.addListener(() => _updateFormData(model));
learningReasonController.addListener(() => _updateFormData(model));
+ topicController.addListener(() => _updateFormData(model));
_updateFormData(model, forceValidate: _autoTextFieldValidation);
}
@@ -78,9 +96,12 @@ mixin $OnboardingView {
'This feature was deprecated after 3.1.0.',
)
void listenToFormUpdated(FormViewModel model) {
+ answerController.addListener(() => _updateFormData(model));
fullNameController.addListener(() => _updateFormData(model));
+ challengeController.addListener(() => _updateFormData(model));
occupationController.addListener(() => _updateFormData(model));
learningReasonController.addListener(() => _updateFormData(model));
+ topicController.addListener(() => _updateFormData(model));
_updateFormData(model, forceValidate: _autoTextFieldValidation);
}
@@ -90,9 +111,12 @@ mixin $OnboardingView {
model.setData(
model.formValueMap
..addAll({
+ AnswerValueKey: answerController.text,
FullNameValueKey: fullNameController.text,
+ ChallengeValueKey: challengeController.text,
OccupationValueKey: occupationController.text,
LearningReasonValueKey: learningReasonController.text,
+ TopicValueKey: topicController.text,
}),
);
@@ -134,11 +158,24 @@ extension ValueProperties on FormStateHelper {
return !hasAnyValidationMessage;
}
+ String? get answerValue => this.formValueMap[AnswerValueKey] as String?;
String? get fullNameValue => this.formValueMap[FullNameValueKey] as String?;
+ String? get challengeValue => this.formValueMap[ChallengeValueKey] as String?;
String? get occupationValue =>
this.formValueMap[OccupationValueKey] as String?;
String? get learningReasonValue =>
this.formValueMap[LearningReasonValueKey] as String?;
+ String? get topicValue => this.formValueMap[TopicValueKey] as String?;
+
+ set answerValue(String? value) {
+ this.setData(
+ this.formValueMap..addAll({AnswerValueKey: value}),
+ );
+
+ if (_OnboardingViewTextEditingControllers.containsKey(AnswerValueKey)) {
+ _OnboardingViewTextEditingControllers[AnswerValueKey]?.text = value ?? '';
+ }
+ }
set fullNameValue(String? value) {
this.setData(
@@ -151,6 +188,17 @@ extension ValueProperties on FormStateHelper {
}
}
+ set challengeValue(String? value) {
+ this.setData(
+ this.formValueMap..addAll({ChallengeValueKey: value}),
+ );
+
+ if (_OnboardingViewTextEditingControllers.containsKey(ChallengeValueKey)) {
+ _OnboardingViewTextEditingControllers[ChallengeValueKey]?.text =
+ value ?? '';
+ }
+ }
+
set occupationValue(String? value) {
this.setData(
this.formValueMap..addAll({OccupationValueKey: value}),
@@ -174,53 +222,96 @@ extension ValueProperties on FormStateHelper {
}
}
+ set topicValue(String? value) {
+ this.setData(
+ this.formValueMap..addAll({TopicValueKey: value}),
+ );
+
+ if (_OnboardingViewTextEditingControllers.containsKey(TopicValueKey)) {
+ _OnboardingViewTextEditingControllers[TopicValueKey]?.text = value ?? '';
+ }
+ }
+
+ bool get hasAnswer =>
+ this.formValueMap.containsKey(AnswerValueKey) &&
+ (answerValue?.isNotEmpty ?? false);
bool get hasFullName =>
this.formValueMap.containsKey(FullNameValueKey) &&
(fullNameValue?.isNotEmpty ?? false);
+ bool get hasChallenge =>
+ this.formValueMap.containsKey(ChallengeValueKey) &&
+ (challengeValue?.isNotEmpty ?? false);
bool get hasOccupation =>
this.formValueMap.containsKey(OccupationValueKey) &&
(occupationValue?.isNotEmpty ?? false);
bool get hasLearningReason =>
this.formValueMap.containsKey(LearningReasonValueKey) &&
(learningReasonValue?.isNotEmpty ?? false);
+ bool get hasTopic =>
+ this.formValueMap.containsKey(TopicValueKey) &&
+ (topicValue?.isNotEmpty ?? false);
+ bool get hasAnswerValidationMessage =>
+ this.fieldsValidationMessages[AnswerValueKey]?.isNotEmpty ?? false;
bool get hasFullNameValidationMessage =>
this.fieldsValidationMessages[FullNameValueKey]?.isNotEmpty ?? false;
+ bool get hasChallengeValidationMessage =>
+ this.fieldsValidationMessages[ChallengeValueKey]?.isNotEmpty ?? false;
bool get hasOccupationValidationMessage =>
this.fieldsValidationMessages[OccupationValueKey]?.isNotEmpty ?? false;
bool get hasLearningReasonValidationMessage =>
this.fieldsValidationMessages[LearningReasonValueKey]?.isNotEmpty ??
false;
+ bool get hasTopicValidationMessage =>
+ this.fieldsValidationMessages[TopicValueKey]?.isNotEmpty ?? false;
+ String? get answerValidationMessage =>
+ this.fieldsValidationMessages[AnswerValueKey];
String? get fullNameValidationMessage =>
this.fieldsValidationMessages[FullNameValueKey];
+ String? get challengeValidationMessage =>
+ this.fieldsValidationMessages[ChallengeValueKey];
String? get occupationValidationMessage =>
this.fieldsValidationMessages[OccupationValueKey];
String? get learningReasonValidationMessage =>
this.fieldsValidationMessages[LearningReasonValueKey];
+ String? get topicValidationMessage =>
+ this.fieldsValidationMessages[TopicValueKey];
}
extension Methods on FormStateHelper {
+ setAnswerValidationMessage(String? validationMessage) =>
+ this.fieldsValidationMessages[AnswerValueKey] = validationMessage;
setFullNameValidationMessage(String? validationMessage) =>
this.fieldsValidationMessages[FullNameValueKey] = validationMessage;
+ setChallengeValidationMessage(String? validationMessage) =>
+ this.fieldsValidationMessages[ChallengeValueKey] = validationMessage;
setOccupationValidationMessage(String? validationMessage) =>
this.fieldsValidationMessages[OccupationValueKey] = validationMessage;
setLearningReasonValidationMessage(String? validationMessage) =>
this.fieldsValidationMessages[LearningReasonValueKey] = validationMessage;
+ setTopicValidationMessage(String? validationMessage) =>
+ this.fieldsValidationMessages[TopicValueKey] = validationMessage;
/// Clears text input fields on the Form
void clearForm() {
+ answerValue = '';
fullNameValue = '';
+ challengeValue = '';
occupationValue = '';
learningReasonValue = '';
+ topicValue = '';
}
/// Validates text input fields on the Form
void validateForm() {
this.setValidationMessages({
+ AnswerValueKey: getValidationMessage(AnswerValueKey),
FullNameValueKey: getValidationMessage(FullNameValueKey),
+ ChallengeValueKey: getValidationMessage(ChallengeValueKey),
OccupationValueKey: getValidationMessage(OccupationValueKey),
LearningReasonValueKey: getValidationMessage(LearningReasonValueKey),
+ TopicValueKey: getValidationMessage(TopicValueKey),
});
}
}
@@ -240,7 +331,10 @@ String? getValidationMessage(String key) {
/// Updates the fieldsValidationMessages on the FormViewModel
void updateValidationData(FormStateHelper model) =>
model.setValidationMessages({
+ AnswerValueKey: getValidationMessage(AnswerValueKey),
FullNameValueKey: getValidationMessage(FullNameValueKey),
+ ChallengeValueKey: getValidationMessage(ChallengeValueKey),
OccupationValueKey: getValidationMessage(OccupationValueKey),
LearningReasonValueKey: getValidationMessage(LearningReasonValueKey),
+ TopicValueKey: getValidationMessage(TopicValueKey),
});
diff --git a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_viewmodel.dart b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_viewmodel.dart
index f9944c0..2cf1fef 100644
--- a/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_viewmodel.dart
+++ b/StudioProjects/yimaru_app/lib/ui/views/onboarding/onboarding_viewmodel.dart
@@ -1,14 +1,19 @@
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
+import 'package:yimaru_app/app/app.router.dart';
import '../../../app/app.locator.dart';
import 'onboarding_view.form.dart';
class OnboardingViewModel extends FormViewModel {
final _navigationService = locator();
- int _currentStep = 0;
+ int _currentPage = 0;
- int get currentStep => _currentStep;
+ int get currentPage => _currentPage;
+
+ int _previousPage = 0;
+
+ int get previousPage => _previousPage;
// Full name
bool _focusFullName = false;
@@ -75,9 +80,9 @@ class OnboardingViewModel extends FormViewModel {
List