fix: Update profile detail section

This commit is contained in:
BisratHailu 2026-05-27 23:39:25 +03:00
parent 12f836d427
commit 974066b8cf
16 changed files with 135 additions and 251 deletions

View File

@ -37,6 +37,9 @@ class User {
@JsonKey(name: 'profile_completed') @JsonKey(name: 'profile_completed')
final bool? profileCompleted; final bool? profileCompleted;
@JsonKey(name: 'subscription_status')
final String? subscriptionStatus;
@JsonKey(name: 'profile_picture_url') @JsonKey(name: 'profile_picture_url')
final String? profilePicture; final String? profilePicture;
@ -55,6 +58,7 @@ class User {
this.profilePicture, this.profilePicture,
this.userInfoLoaded, this.userInfoLoaded,
this.profileCompleted, this.profileCompleted,
this.subscriptionStatus
}); });
User copyWith( User copyWith(

View File

@ -90,6 +90,8 @@ class AuthenticationService with ListenableServiceMixin {
await _secureService.setBool('userInfoLoaded', true); await _secureService.setBool('userInfoLoaded', true);
await _secureService.setBool( await _secureService.setBool(
'profileCompleted', data.profileCompleted ?? false); 'profileCompleted', data.profileCompleted ?? false);
await _secureService.setString(
'subscriptionStatus', data.subscriptionStatus ?? '');
await _secureService.setString('email', data.email ?? ''); await _secureService.setString('email', data.email ?? '');
await _secureService.setString('region', data.region ?? ''); await _secureService.setString('region', data.region ?? '');
await _secureService.setString('gender', data.gender ?? ''); await _secureService.setString('gender', data.gender ?? '');
@ -99,6 +101,7 @@ class AuthenticationService with ListenableServiceMixin {
await _secureService.setString('firstName', data.firstName ?? ''); await _secureService.setString('firstName', data.firstName ?? '');
await _secureService.setString('occupation', data.occupation ?? ''); await _secureService.setString('occupation', data.occupation ?? '');
_user = User( _user = User(
email: data.email, email: data.email,
gender: data.gender, gender: data.gender,
@ -113,6 +116,7 @@ class AuthenticationService with ListenableServiceMixin {
accessToken: _user?.accessToken, accessToken: _user?.accessToken,
refreshToken: _user?.refreshToken, refreshToken: _user?.refreshToken,
profileCompleted: data.profileCompleted, profileCompleted: data.profileCompleted,
subscriptionStatus: data.subscriptionStatus,
); );
notifyListeners(); notifyListeners();
@ -169,6 +173,7 @@ class AuthenticationService with ListenableServiceMixin {
userInfoLoaded: await _secureService.getBool('userInfoLoaded'), userInfoLoaded: await _secureService.getBool('userInfoLoaded'),
profilePicture: await _secureService.getString('profilePicture'), profilePicture: await _secureService.getString('profilePicture'),
profileCompleted: await _secureService.getBool('profileCompleted'), profileCompleted: await _secureService.getBool('profileCompleted'),
subscriptionStatus: await _secureService.getString('subscriptionStatus'),
); );
return _user; return _user;
} }

View File

@ -1,4 +1,3 @@
import 'package:http/http.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:yimaru_app/models/refresh_object.dart'; import 'package:yimaru_app/models/refresh_object.dart';
import 'package:yimaru_app/ui/common/enmus.dart'; import 'package:yimaru_app/ui/common/enmus.dart';
@ -42,7 +41,7 @@ class LearnService with ListenableServiceMixin {
List<LearnLesson> get lessons => _lessons; List<LearnLesson> get lessons => _lessons;
// Learn progress // Learn progress
List<ProgressSummary> _summaries = []; final List<ProgressSummary> _summaries = [];
List<ProgressSummary> get summaries => _summaries; List<ProgressSummary> get summaries => _summaries;

View File

@ -101,4 +101,16 @@ class OnboardingService with ListenableServiceMixin {
} }
return false; return false;
} }
// Profile detail fields
Future<void> getProfileDetailFields() async {
_countries = await _apiService.getCountries();
_occupations = await _apiService.getOccupations();
_regions = await _apiService.getEthiopiaRegions();
notifyListeners();
}
} }

View File

@ -39,6 +39,7 @@ enum StateObjects {
learnModules, learnModules,
learnCourses, learnCourses,
profileImage, profileImage,
profileDetail,
learnPrograms, learnPrograms,
courseLessons, courseLessons,
profileUpdate, profileUpdate,

View File

@ -3,7 +3,6 @@ import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/app/app.router.dart'; import 'package:yimaru_app/app/app.router.dart';
import 'package:yimaru_app/models/learn_module.dart'; import 'package:yimaru_app/models/learn_module.dart';
import 'package:yimaru_app/models/refresh_object.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart'; import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import '../../../app/app.locator.dart'; import '../../../app/app.locator.dart';

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart'; import 'package:stacked/stacked.dart';
import 'package:stacked/stacked_annotations.dart'; import 'package:stacked/stacked_annotations.dart';
import 'package:yimaru_app/ui/common/enmus.dart';
import 'package:yimaru_app/ui/views/onboarding/screens/age_group_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/age_group_form_screen.dart';
import 'package:yimaru_app/ui/views/onboarding/screens/challenge_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/challenge_form_screen.dart';
@ -13,7 +12,6 @@ import 'package:yimaru_app/ui/views/onboarding/screens/language_goal_form_screen
import 'package:yimaru_app/ui/views/onboarding/screens/learning_goal_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/learning_goal_form_screen.dart';
import 'package:yimaru_app/ui/views/onboarding/screens/occupation_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/occupation_form_screen.dart';
import 'package:yimaru_app/ui/views/onboarding/screens/topic_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/topic_form_screen.dart';
import 'package:yimaru_app/ui/views/startup/startup_view.dart';
import '../../common/validators/form_validator.dart'; import '../../common/validators/form_validator.dart';
import 'onboarding_viewmodel.dart'; import 'onboarding_viewmodel.dart';

View File

@ -4,12 +4,9 @@ import 'package:stacked_services/stacked_services.dart';
import 'package:yimaru_app/app/app.router.dart'; import 'package:yimaru_app/app/app.router.dart';
import '../../../app/app.locator.dart'; import '../../../app/app.locator.dart';
import '../../../models/field_option.dart'; import '../../../models/field_option.dart';
import '../../../services/api_service.dart';
import '../../../services/google_auth_service.dart'; import '../../../services/google_auth_service.dart';
import '../../../services/localization_service.dart'; import '../../../services/localization_service.dart';
import '../../../services/onboarding_service.dart'; import '../../../services/onboarding_service.dart';
import '../../../services/status_checker_service.dart';
import '../../common/enmus.dart';
class OnboardingViewModel extends ReactiveViewModel class OnboardingViewModel extends ReactiveViewModel
with FormStateHelper with FormStateHelper

View File

@ -5,7 +5,6 @@ import 'package:yimaru_app/ui/common/app_colors.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart'; import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/common/ui_helpers.dart'; import 'package:yimaru_app/ui/common/ui_helpers.dart';
import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart'; import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.form.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart'; import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart';
import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart'; import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart';
import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; import 'package:yimaru_app/ui/widgets/large_app_bar.dart';

View File

@ -5,7 +5,6 @@ import 'package:yimaru_app/ui/common/app_colors.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart'; import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/common/ui_helpers.dart'; import 'package:yimaru_app/ui/common/ui_helpers.dart';
import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart'; import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.form.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart'; import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart';
import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart'; import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart';
import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; import 'package:yimaru_app/ui/widgets/large_app_bar.dart';

View File

@ -5,7 +5,6 @@ import 'package:yimaru_app/ui/common/app_colors.dart';
import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart'; import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/common/ui_helpers.dart'; import 'package:yimaru_app/ui/common/ui_helpers.dart';
import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart'; import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_view.form.dart';
import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart'; import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart';
import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart'; import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart';
import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; import 'package:yimaru_app/ui/widgets/large_app_bar.dart';

View File

@ -7,10 +7,12 @@ import 'package:yimaru_app/ui/common/translations/locale_keys.g.dart';
import 'package:yimaru_app/ui/widgets/custom_form_label.dart'; import 'package:yimaru_app/ui/widgets/custom_form_label.dart';
import 'package:yimaru_app/ui/widgets/small_app_bar.dart'; import 'package:yimaru_app/ui/widgets/small_app_bar.dart';
import '../../../models/field_option.dart';
import '../../common/app_colors.dart'; import '../../common/app_colors.dart';
import '../../common/enmus.dart'; import '../../common/enmus.dart';
import '../../common/ui_helpers.dart'; import '../../common/ui_helpers.dart';
import '../../common/validators/form_validator.dart'; import '../../common/validators/form_validator.dart';
import '../../widgets/custom_dropdown.dart';
import '../../widgets/custom_elevated_button.dart'; import '../../widgets/custom_elevated_button.dart';
import '../../widgets/image_picker_option.dart'; import '../../widgets/image_picker_option.dart';
import '../../widgets/page_loading_indicator.dart'; import '../../widgets/page_loading_indicator.dart';
@ -31,19 +33,30 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
with $ProfileDetailView { with $ProfileDetailView {
const ProfileDetailView({Key? key}) : super(key: key); const ProfileDetailView({Key? key}) : super(key: key);
void _setSelectedCountry(
{FieldOption? value, required ProfileDetailViewModel viewModel}) {
viewModel.setSelectedCountry(value);
if (viewModel.selectedCountry?.label?.toLowerCase().tr() != 'ethiopia') {
regionController.clear();
viewModel.unsetRegionFocus();
}
}
Future<void> _update(ProfileDetailViewModel viewModel) async { Future<void> _update(ProfileDetailViewModel viewModel) async {
Map<String, dynamic> data = { Map<String, dynamic> data = {
'region': viewModel.dropdownRegion
? viewModel.selectedRegion
: regionController.text,
'gender': viewModel.selectedGender, 'gender': viewModel.selectedGender,
'region': viewModel.dropdownRegion
? viewModel.selectedRegion?.code
: regionController.text,
'last_name': lastNameController.text, 'last_name': lastNameController.text,
'country': viewModel.selectedCountry,
'first_name': firstNameController.text, 'first_name': firstNameController.text,
'occupation': viewModel.selectedOccupation, 'country': viewModel.selectedCountry?.code,
'occupation': viewModel.selectedOccupation?.code,
'birth_day': DateFormat('yyyy-MM-dd').format(DateTime.now()), 'birth_day': DateFormat('yyyy-MM-dd').format(DateTime.now()),
}; };
viewModel.addUserData(data); viewModel.addUserData(data);
await viewModel.updateProfile(); await viewModel.updateProfile();
@ -68,10 +81,13 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
void _checkRegion(ProfileDetailViewModel viewModel) { void _checkRegion(ProfileDetailViewModel viewModel) {
bool region = viewModel.checkRegion( bool region = viewModel.checkRegion(
region: viewModel.user?.region ?? 'Addis Ababa', region: viewModel.user?.region ?? '',
country: viewModel.user?.country ?? 'Ethiopia'); country: viewModel.user?.country ?? '');
if (region) { if (region) {
viewModel.setSelectedRegion(viewModel.user?.region ?? 'Addis Ababa'); FieldOption? option = viewModel.regions
.where((e) => (e.code ?? '') == viewModel.user?.region)
.first;
viewModel.setSelectedRegion(option);
} else { } else {
regionController.text = viewModel.user?.region ?? ''; regionController.text = viewModel.user?.region ?? '';
} }
@ -85,12 +101,17 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
_checkRegion(viewModel); _checkRegion(viewModel);
viewModel.clearUserData(); viewModel.clearUserData();
viewModel.setSelectedGender(viewModel.user?.gender ?? ''); viewModel.setSelectedGender(viewModel.user?.gender ?? '');
viewModel.setSelectedOccupation(viewModel.user?.occupation ?? ''); viewModel.setSelectedOccupation(viewModel.occupations
viewModel.setSelectedCountry(viewModel.user?.country ?? 'Ethiopia'); .where((e) => (e.code ?? '') == viewModel.user?.occupation)
.first);
viewModel.setSelectedCountry(viewModel.countries
.where((e) => (e.code ?? '') == viewModel.user?.country)
.first);
} }
@override @override
void onViewModelReady(ProfileDetailViewModel viewModel) { void onViewModelReady(ProfileDetailViewModel viewModel) async{
await viewModel.getProfileDetailFields();
_onModelReady(viewModel); _onModelReady(viewModel);
syncFormWithViewModel(viewModel); syncFormWithViewModel(viewModel);
super.onViewModelReady(viewModel); super.onViewModelReady(viewModel);
@ -113,9 +134,17 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
required ProfileDetailViewModel viewModel}) => required ProfileDetailViewModel viewModel}) =>
Scaffold( Scaffold(
backgroundColor: kcBackgroundColor, backgroundColor: kcBackgroundColor,
body: _buildScaffoldContainer(context: context, viewModel: viewModel), body: _buildScaffoldState(context: context, viewModel: viewModel),
); );
Widget _buildScaffoldState(
{required BuildContext context,
required ProfileDetailViewModel viewModel}) =>
viewModel.busy(StateObjects.profileDetail)
? const PageLoadingIndicator()
: _buildScaffoldContainer(context: context, viewModel: viewModel);
Widget _buildScaffoldContainer( {required BuildContext context, Widget _buildScaffoldContainer( {required BuildContext context,
required ProfileDetailViewModel viewModel}) => Container( required ProfileDetailViewModel viewModel}) => Container(
decoration: bgDecoration, decoration: bgDecoration,
@ -208,7 +237,7 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
verticalSpaceMedium, verticalSpaceMedium,
_buildCountryDropdownLabel(), _buildCountryDropdownLabel(),
verticalSpaceSmall, verticalSpaceSmall,
// _buildCountryDropdown(viewModel), _buildCountryDropdown(viewModel),
verticalSpaceMedium, verticalSpaceMedium,
_buildRegionFormFieldWrapper(viewModel), _buildRegionFormFieldWrapper(viewModel),
verticalSpaceMedium, verticalSpaceMedium,
@ -533,13 +562,14 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
label: LocaleKeys.country.tr(), label: LocaleKeys.country.tr(),
); );
// Widget _buildCountryDropdown(ProfileDetailViewModel viewModel) => Widget _buildCountryDropdown(ProfileDetailViewModel viewModel) =>
// CustomDropdownPicker( CustomDropdownPicker(
// hint: 'Select country', icon: _buildSearchIcon(),
// selectedItem: viewModel.selectedCountry, hint: LocaleKeys.select_country.tr(),
// items: (value, props) => viewModel.getCountries(), selectedItem: viewModel.selectedCountry,
// onChanged: (value) => viewModel.setSelectedCountry(value ?? 'Ethiopia'), items: (value, props) => viewModel.countries,
// ); onChanged: (value) =>
_setSelectedCountry(value: value, viewModel: viewModel));
Widget _buildRegionFormFieldWrapper(ProfileDetailViewModel viewModel) => Widget _buildRegionFormFieldWrapper(ProfileDetailViewModel viewModel) =>
Column( Column(
@ -571,19 +601,17 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
); );
Widget _buildRegionFormState(ProfileDetailViewModel viewModel) => Widget _buildRegionFormState(ProfileDetailViewModel viewModel) =>
// viewModel.dropdownRegion viewModel.dropdownRegion
// ? _buildRegionDropDown(viewModel) ? _buildRegionDropDown(viewModel)
// : : _buildRegionFormField(viewModel);
_buildRegionFormField(viewModel);
// Widget _buildRegionDropDown(ProfileDetailViewModel viewModel) =>
// Widget _buildRegionDropDown(ProfileDetailViewModel viewModel) => CustomDropdownPicker(
// CustomDropdownPicker( icon: _buildSearchIcon(),
// icon: _buildSearchIcon(), hint: LocaleKeys.select_region.tr(),
// hint:LocaleKeys.select_region.tr(), selectedItem: viewModel.selectedRegion,
// selectedItem: viewModel.selectedRegion, items: (value, props) => viewModel.regions,
// items: (value, props) => viewModel.getRegions(), onChanged: (value) => viewModel.setSelectedRegion(value));
// onChanged: (value) =>
// viewModel.setSelectedRegion(value ?? 'Addis Ababa'));
Widget _buildRegionFormField(ProfileDetailViewModel viewModel) => Widget _buildRegionFormField(ProfileDetailViewModel viewModel) =>
TextFormField( TextFormField(
@ -618,7 +646,7 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
[ [
_buildOccupationDropdownLabel(), _buildOccupationDropdownLabel(),
verticalSpaceSmall, verticalSpaceSmall,
// _buildOccupationDropdown(viewModel) _buildOccupationDropdown(viewModel)
]; ];
Widget _buildOccupationDropdownLabel() => CustomFormLabel( Widget _buildOccupationDropdownLabel() => CustomFormLabel(
@ -626,14 +654,14 @@ class ProfileDetailView extends StackedView<ProfileDetailViewModel>
label: LocaleKeys.occupation.tr(), label: LocaleKeys.occupation.tr(),
); );
// Widget _buildOccupationDropdown(ProfileDetailViewModel viewModel) => Widget _buildOccupationDropdown(ProfileDetailViewModel viewModel) =>
// CustomDropdownPicker( CustomDropdownPicker(
// icon: _buildSearchIcon(), icon: _buildSearchIcon(),
// hint:LocaleKeys.select_occupation.tr(), hint: LocaleKeys.select_occupation.tr(),
// selectedItem: viewModel.selectedOccupation, selectedItem: viewModel.selectedOccupation,
// items: (value, props) => viewModel.getOccupations(), items: (value, props) => viewModel.occupations,
// onChanged: (value) => viewModel.setSelectedOccupation( onChanged: (value) => viewModel.setSelectedOccupation(value));
// value ?? 'Students (High school & University)'));
Icon _buildSearchIcon() => const Icon( Icon _buildSearchIcon() => const Icon(
Icons.search, Icons.search,
color: kcPrimaryColor, color: kcPrimaryColor,

View File

@ -2,10 +2,12 @@ import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart'; import 'package:stacked_services/stacked_services.dart';
import '../../../app/app.locator.dart'; import '../../../app/app.locator.dart';
import '../../../models/field_option.dart';
import '../../../models/user.dart'; import '../../../models/user.dart';
import '../../../services/api_service.dart'; import '../../../services/api_service.dart';
import '../../../services/authentication_service.dart'; import '../../../services/authentication_service.dart';
import '../../../services/image_picker_service.dart'; import '../../../services/image_picker_service.dart';
import '../../../services/onboarding_service.dart';
import '../../../services/status_checker_service.dart'; import '../../../services/status_checker_service.dart';
import '../../common/enmus.dart'; import '../../common/enmus.dart';
import '../../common/ui_helpers.dart'; import '../../common/ui_helpers.dart';
@ -17,6 +19,8 @@ class ProfileDetailViewModel extends ReactiveViewModel
final _statusChecker = locator<StatusCheckerService>(); final _statusChecker = locator<StatusCheckerService>();
final _onboardingService = locator<OnboardingService>();
final _navigationService = locator<NavigationService>(); final _navigationService = locator<NavigationService>();
final _imagePickerService = locator<ImagePickerService>(); final _imagePickerService = locator<ImagePickerService>();
@ -58,14 +62,14 @@ class ProfileDetailViewModel extends ReactiveViewModel
bool get focusEmail => _focusEmail; bool get focusEmail => _focusEmail;
// Occupation // Occupation
String _selectedOccupation = 'Students (High school & University)'; FieldOption? _selectedOccupation;
String get selectedOccupation => _selectedOccupation; FieldOption? get selectedOccupation => _selectedOccupation;
// Country // Country
String _selectedCountry = 'Ethiopia'; FieldOption? _selectedCountry;
String get selectedCountry => _selectedCountry; FieldOption? get selectedCountry => _selectedCountry;
// Region // Region
bool _focusRegion = false; bool _focusRegion = false;
@ -76,9 +80,9 @@ class ProfileDetailViewModel extends ReactiveViewModel
bool get dropdownRegion => _dropdownRegion; bool get dropdownRegion => _dropdownRegion;
String _selectedRegion = 'Addis Ababa'; FieldOption? _selectedRegion;
String get selectedRegion => _selectedRegion; FieldOption? get selectedRegion => _selectedRegion;
// User data // User data
final Map<String, dynamic> _userData = {}; final Map<String, dynamic> _userData = {};
@ -116,182 +120,26 @@ class ProfileDetailViewModel extends ReactiveViewModel
} }
// Occupation // Occupation
List<String> getOccupations() => [ List<FieldOption> get _occupations => _onboardingService.occupations;
'Students (High school & University)',
'Job Seekers / Fresh Graduates',
'Working Professionals (Corporate/Office)',
'Government & NGO Workers',
'Entrepreneurs & Small Business Owners',
'Hospitality & Tourism Workers',
'Freelancers / Remote Workers (Digital Economy)'
];
void setSelectedOccupation(String value) { List<FieldOption> get occupations => _occupations;
void setSelectedOccupation(FieldOption? value) {
_selectedOccupation = value; _selectedOccupation = value;
rebuildUi(); rebuildUi();
} }
// Country // Country
List<String> getCountries() => [ List<FieldOption> get _countries => _onboardingService.countries;
"Afghanistan",
"Albania",
"Algeria",
"Andorra",
"Angola",
"Argentina",
"Armenia",
"Australia",
"Austria",
"Azerbaijan",
"Bahrain",
"Bangladesh",
"Belarus",
"Belgium",
"Belize",
"Benin",
"Bhutan",
"Bolivia",
"Bosnia and Herzegovina",
"Botswana",
"Brazil",
"Brunei",
"Bulgaria",
"Burkina Faso",
"Burundi",
"Cambodia",
"Cameroon",
"Canada",
"Chad",
"Chile",
"China",
"Colombia",
"Comoros",
"Congo",
"Costa Rica",
"Croatia",
"Cuba",
"Cyprus",
"Czech Republic",
"Denmark",
"Djibouti",
"Dominican Republic",
"Ecuador",
"Egypt",
"El Salvador",
"Eritrea",
"Estonia",
"Eswatini",
"Ethiopia",
"Finland",
"France",
"Gabon",
"Gambia",
"Georgia",
"Germany",
"Ghana",
"Greece",
"Guatemala",
"Guinea",
"Haiti",
"Honduras",
"Hungary",
"Iceland",
"India",
"Indonesia",
"Iran",
"Iraq",
"Ireland",
"Israel",
"Italy",
"Jamaica",
"Japan",
"Jordan",
"Kazakhstan",
"Kenya",
"Kuwait",
"Kyrgyzstan",
"Laos",
"Latvia",
"Lebanon",
"Liberia",
"Libya",
"Lithuania",
"Luxembourg",
"Madagascar",
"Malawi",
"Malaysia",
"Maldives",
"Mali",
"Malta",
"Mexico",
"Moldova",
"Monaco",
"Mongolia",
"Morocco",
"Mozambique",
"Myanmar",
"Namibia",
"Nepal",
"Netherlands",
"New Zealand",
"Nicaragua",
"Niger",
"Nigeria",
"North Korea",
"Norway",
"Oman",
"Pakistan",
"Panama",
"Paraguay",
"Peru",
"Philippines",
"Poland",
"Portugal",
"Qatar",
"Romania",
"Russia",
"Rwanda",
"Saudi Arabia",
"Senegal",
"Serbia",
"Singapore",
"Slovakia",
"Slovenia",
"Somalia",
"South Africa",
"South Korea",
"Spain",
"Sri Lanka",
"Sudan",
"Sweden",
"Switzerland",
"Syria",
"Taiwan",
"Tajikistan",
"Tanzania",
"Thailand",
"Tunisia",
"Turkey",
"Uganda",
"Ukraine",
"United Arab Emirates",
"United Kingdom",
"United States",
"Uruguay",
"Uzbekistan",
"Venezuela",
"Vietnam",
"Yemen",
"Zambia",
"Zimbabwe"
];
void setSelectedCountry(String value) { List<FieldOption> get countries => _countries;
void setSelectedCountry(FieldOption? value) {
_selectedCountry = value; _selectedCountry = value;
if (value?.label?.toLowerCase().trim() == 'ethiopia') {
if (value == 'Ethiopia') {
_dropdownRegion = true; _dropdownRegion = true;
_selectedRegion = 'Addis Ababa'; _selectedRegion = _regions
.firstWhere((e) => e.label?.toLowerCase().trim() == 'addis ababa');
} else { } else {
_dropdownRegion = false; _dropdownRegion = false;
} }
@ -300,34 +148,22 @@ class ProfileDetailViewModel extends ReactiveViewModel
} }
// Region // Region
List<String> getRegions() => [ List<FieldOption> get _regions => _onboardingService.regions;
'Addis Ababa',
'Afar', List<FieldOption> get regions => _regions;
'Amhara',
'Benishangul-Gumuz', void setSelectedRegion(FieldOption? value) {
'Central Ethiopia', _selectedRegion = value;
'Dire Dawa', rebuildUi();
'Gambela', }
'Harari',
'Oromia',
'Sidama',
'Somali',
'South Ethiopia',
'South West Ethiopia Peoples',
'Tigray',
];
bool checkRegion({required String region, required String country}) { bool checkRegion({required String region, required String country}) {
if (country == 'Ethiopia') { if (country.toLowerCase().contains('ethiopia')) {
return getRegions().contains(region); return _regions.contains(region);
} }
return false; return false;
} }
void setSelectedRegion(String value) {
_selectedRegion = value;
rebuildUi();
}
void setRegionFocus() { void setRegionFocus() {
_focusRegion = true; _focusRegion = true;
@ -419,4 +255,12 @@ class ProfileDetailViewModel extends ReactiveViewModel
await _apiService.updateProfileImage(data: data, userId: _user?.userId); await _apiService.updateProfileImage(data: data, userId: _user?.userId);
} }
} }
// Profile detail fields
Future<void> getProfileDetailFields() async =>
await runBusyFuture(_getProfileDetailFields(),busyObject: StateObjects.profileDetail);
Future<void> _getProfileDetailFields() async {
await _onboardingService.getProfileDetailFields();
}
} }

View File

@ -89,7 +89,7 @@ class StartupViewModel extends ReactiveViewModel {
response = {'data': true, 'status': ResponseStatus.success}; response = {'data': true, 'status': ResponseStatus.success};
} }
if (response['status'] == ResponseStatus.success && !response['data']) { if (response['status'] == ResponseStatus.success && !response['data']) {
await etOnboardingFields(); await getOnboardingFields();
} else if (response['status'] == ResponseStatus.success && } else if (response['status'] == ResponseStatus.success &&
response['data']) { response['data']) {
await saveProfileStatus(response['data']); await saveProfileStatus(response['data']);
@ -134,7 +134,7 @@ class StartupViewModel extends ReactiveViewModel {
// Remote api call // Remote api call
// Onboarding fields // Onboarding fields
Future<void> etOnboardingFields() async { Future<void> getOnboardingFields() async {
bool response = await _onboardingService.getOnboardingFields(); bool response = await _onboardingService.getOnboardingFields();
if (response) { if (response) {
await replaceWithOnboarding(); await replaceWithOnboarding();

View File

@ -10,7 +10,6 @@ import 'package:yimaru_app/ui/widgets/custom_linear_progress_indicator.dart';
import 'package:yimaru_app/ui/widgets/finish_practice_sheet.dart'; import 'package:yimaru_app/ui/widgets/finish_practice_sheet.dart';
import '../common/app_colors.dart'; import '../common/app_colors.dart';
import '../common/helper_functions.dart';
import '../common/ui_helpers.dart'; import '../common/ui_helpers.dart';
import 'custom_elevated_button.dart'; import 'custom_elevated_button.dart';

View File

@ -9,6 +9,7 @@ environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
http: any http: any
intl: any intl: any
dio: ^5.9.0 dio: ^5.9.0