From d4e46d5ddb833ef1ea1e7b896d3b33c9ca1cfef1 Mon Sep 17 00:00:00 2001 From: BisratHailu Date: Fri, 29 May 2026 23:13:12 +0300 Subject: [PATCH 1/2] fix(learn): Fix progress tracking issue without payment implementation --- assets/translations/am.json | 19 +- assets/translations/en.json | 7 +- lib/ui/common/enmus.dart | 5 + .../common/translations/codegen_loader.g.dart | 784 +++++++++--------- lib/ui/common/translations/locale_keys.g.dart | 12 +- lib/ui/views/arif_pay/arif_pay_viewmodel.dart | 2 +- lib/ui/views/assessment/assessment_view.dart | 9 +- .../screens/assessment_intro_screen.dart | 15 +- .../screens/assessment_result_screen.dart | 1 - .../screens/start_lesson_screen.dart | 1 - .../screens/request_reset_code_screen.dart | 1 - .../screens/reset_password_screen.dart | 1 - .../views/learn_course/learn_course_view.dart | 24 +- .../views/learn_lesson/learn_lesson_view.dart | 41 +- .../learn_lesson_detail_view.dart | 7 +- .../views/learn_module/learn_module_view.dart | 30 +- lib/ui/views/onboarding/onboarding_view.dart | 6 +- .../onboarding/onboarding_viewmodel.dart | 3 +- .../screens/age_group_form_screen.dart | 3 +- .../screens/challenge_form_screen.dart | 3 +- .../screens/country_region_form_screen.dart | 3 +- .../educational_background_form_screen.dart | 3 +- .../screens/full_name_form_screen.dart | 3 +- .../screens/gender_form_screen.dart | 3 +- .../screens/language_goal_form_screen.dart | 99 ++- .../screens/learning_goal_form_screen.dart | 102 +-- .../screens/occupation_form_screen.dart | 3 +- .../onboarding/screens/topic_form_screen.dart | 3 +- lib/ui/widgets/course_module_tile_large.dart | 2 + lib/ui/widgets/course_unit_tile.dart | 3 + lib/ui/widgets/finish_practice_sheet.dart | 20 +- lib/ui/widgets/learn_course_tile.dart | 8 +- lib/ui/widgets/learn_lesson_tile.dart | 36 +- lib/ui/widgets/learn_module_tile.dart | 7 +- pubspec.yaml | 2 +- 35 files changed, 673 insertions(+), 598 deletions(-) diff --git a/assets/translations/am.json b/assets/translations/am.json index 7c1f645..119a1c3 100644 --- a/assets/translations/am.json +++ b/assets/translations/am.json @@ -22,7 +22,7 @@ "confirm_password": "የይለፍ ቃል ያረጋግጡ", "eight_character_minimum": "ቢያንስ 8 ፊደላት", "password_match": "የይለፍ ቃሉ ተመሳስሏል", - "sign_up_agreement": "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።" , + "sign_up_agreement": "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", "terms_of_services": "የአገልግሎት ውሎች", "and": "እና", "privacy_policy": "የግላዊነት ፖሊሲ", @@ -33,9 +33,9 @@ "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", "reset_password": " የይለፍ ቃልን ይቀይሩ", - "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።" , + "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", "please_wait": "እባክዎ ይጠብቁ", - "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል" , + "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", "reset_code": " የመቀየሪያ ኮድ ", "new_password": "አዲስ የይለፍ ቃል", "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", @@ -183,13 +183,10 @@ "welcome_abroad": "እንኳን ደህና መጣህ", "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", "finish": "አጠናቅቅ", - - "finish_all_practice": "ልምምዱን ለመውሰድ በትምህርቶቹ ውስጥ ያሉትን ሁሉንም ልምምዶች ያጠናቅቁ።" - - - - - - + "finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ", + "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", + "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", + "finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", + "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ" } diff --git a/assets/translations/en.json b/assets/translations/en.json index 7ce626a..0ff6d30 100644 --- a/assets/translations/en.json +++ b/assets/translations/en.json @@ -183,5 +183,10 @@ "welcome_abroad": "Welcome aboard", "ready_to_explore": "You’re ready to explore your personalized lessons.", "finish": "Finish", - "finish_all_practice": "Finish all the practices in the lessons to take this practice" + "finish_all_practice_lesson": "Finish the previous lesson practice to take this practice", + "finish_all_practice_module": "Finish the lesson practices to take the Module Practice", + "finish_all_practice_course": "Finish the Module practices to take the Course practice", + "finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice", + "finish_all_practice_previouse_course": "Finish the previous course practice to take this" + } diff --git a/lib/ui/common/enmus.dart b/lib/ui/common/enmus.dart index 7eb039a..0674434 100644 --- a/lib/ui/common/enmus.dart +++ b/lib/ui/common/enmus.dart @@ -25,6 +25,11 @@ enum ProgressStatuses { pending, started, completed } // Duolingo types enum DuolingoAssessments { speaking, reading, writing, listening } + +// Practice reason +enum PracticeReason { course, module, lesson, previousModule, previousCourse } + + // State object enum StateObjects { none, diff --git a/lib/ui/common/translations/codegen_loader.g.dart b/lib/ui/common/translations/codegen_loader.g.dart index 1c12ca5..678196c 100644 --- a/lib/ui/common/translations/codegen_loader.g.dart +++ b/lib/ui/common/translations/codegen_loader.g.dart @@ -6,7 +6,7 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader { +class CodegenLoader extends AssetLoader{ const CodegenLoader(); @override @@ -14,403 +14,387 @@ class CodegenLoader extends AssetLoader { return Future.value(mapLocales[locale.toString()]); } - static const Map _am = { - "loading": "በመጫን ላይ", - "welcome_back": "እንኳን በደህና ተመለሱ", - "checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ", - "dont_have_account": "መለያ የለዎትም?", - "email": "ኢሜይል", - "password": "የይለፍ ቃል", - "forgot_password": "የይለፍ ቃል ረሱ?", - "cont": "ቀጥል", - "register": "ይመዝገቡ", - "login_with_google": "በጉግል ይግቡ", - "or": "ወይም", - "login_with_phone": "በስልክ ቁጥር ይግቡ", - "create_account": "አዲስ መለያ ይፍጠሩ", - "already_have_account": "መለያ አለዎት?", - "login": " ይግቡ ", - "register_with_google": "በጉግል ይመዝገቡ", - "register_with_phone": "በስልክ ቁጥር ይመዝገቡ", - "enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።", - "login_with_email": "በኢሜይል ይግቡ", - "create_password": "የይለፍ ቃል ይፍጠሩ", - "confirm_password": "የይለፍ ቃል ያረጋግጡ", - "eight_character_minimum": "ቢያንስ 8 ፊደላት", - "password_match": "የይለፍ ቃሉ ተመሳስሏል", - "sign_up_agreement": - "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", - "terms_of_services": "የአገልግሎት ውሎች", - "and": "እና", - "privacy_policy": "የግላዊነት ፖሊሲ", - "register_with_email": "በኢሜል ይመዝገቡ", - "verification_code": "የማረጋገጫ ኮድ", - "resend_code": "ኮዱን እንደገና ላክ", - "code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል", - "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", - "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", - "reset_password": " የይለፍ ቃልን ይቀይሩ", - "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", - "please_wait": "እባክዎ ይጠብቁ", - "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", - "reset_code": " የመቀየሪያ ኮድ ", - "new_password": "አዲስ የይለፍ ቃል", - "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", - "view_course": " ኮርሱን ይመልከቱ", - "continue_learning": "መማርን ይቀጥሉ", - "start_learning": "ትምህርትን ይጀምሩ", - "completed": "ተጠናቋል", - "take_practice": "ልምምድ ያድርጉ", - "your_current_level": "የአሁኑ ደረጃዎ", - "overall_progress": "አጠቃላይ እድገት", - "great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው", - "view_module": "ሞጁሉን ይመልከቱ", - "progress": "እድገት", - "keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ", - "lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ", - "practice": "ልምምድ", - "start": "ጀምር", - "in_progress": "በሂደት ላይ", - "hello": "ሰላም", - "ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ", - "learn": "ይማሩ ", - "course": "ኮርስ", - "profile": " ፕሮፋይል ", - "speaking_partner": "የንግግር ጓደኛ", - "practice_what_you_learned": "አሁን የተማሩትን እንለማመድ", - "practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ", - "start_practice": "ልምምድ ጀምር", - "almost_there": "ሊጨርሱ ተቃርበዋል", - "finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ", - "continue_practice": "ልምምዱን ይቀጥሉ", - "end_session": "ክፍለ ጊዜውን ያብቁ ", - "tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ", - "practice_speaking": "ንግግርን ይለማመዱ", - "tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ", - "reply": "እንደገና አዳምጥ", - "cancel": "ይቅር", - "you_are_speaking": "እየተናገሩ ነው", - "practice_completed": "ልምምዱ ተጠናቅቋል", - "great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው", - "practice_again": "እንደገና ይለማመዱ", - "conversation_review": "የንግግር ግምገማ", - "result": "ውጤት", - "quick_tip": "ጠቃሚ ምክር", - "retry": "እንደገና ይሞክሩ", - "completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል", - "analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው", - "view_profile": "ፕሮፋይሎን ይመልከቱ ", - "hi": "ሰላም", - "edit_profile": "መገለጫ ያስተካክሉ", - "first_name": "የመጀመሪያ ስም", - "last_name": "የአባት ስም", - "gender": "ፆታ", - "male": "ወንድ", - "female": "ሴት", - "phone_number": "የስልክ ቁጥር", - "country": "ሀገር", - "region": "ክልል", - "select_region": "ክልል ይምረጡ", - "enter_your_city": "ከተማዎን ያስገቡ", - "occupation": "የስራ መስክ", - "select_occupation": "ሙያዎን ይምረጡ", - "save_changes": "ለውጦችን ያስቀምጡ", - "my_progress": "የእኔ እድገት", - "track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ", - "account_and_privacy": "መለያ እና ግላዊነት", - "manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ", - "support": "ድጋፍ", - "get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ", - "logout": "ውጣ", - "app_settings": "የመተግበሪያ ቅንብሮች", - "legal_and_information": "ሕጋዊ እና መረጃ", - "change_language": "ቋንቋ ቀይር", - "terms_and_conditions": "ውሎች እና ሁኔታዎች", - "delete_account": "መለያ ሰርዝ", - "language_preference": "የቋንቋ ምርጫ", - "choose_your_language": "ለውጦችን አስቀምጥ", - "switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ", - "need_help": "እገዛ ይፈልጋሉ?", - "call_support": "የስልክ ድጋፍ", - "talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ", - "telegram_support": "የቴሌግራም ድጋፍ", - "chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ", - "call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ", - "tap_to_call": "ለመደወል ይንኩ", - "join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ", - "connect_with_support_team": - "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።", - "open_in_telegram": "በቴሌግራም ይክፈቱ", - "search_for": "ፈልጉት", - "current_level": "የአሁኑ ደረጃ", - "keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።", - "no_practice_available": "ምንም ልምምድ አልተገኘም!", - "begin_module_practice": "የሞጁሉን ልምምድ ጀምር", - "lets_practice_lesson": "እንለማመድ", - "lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!", - "lets_practice_module": "አሁን የተማርከውን እንለማመድ!", - "ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።", - "begin_level_practice": "የደረጃ ልምምድን ጀምር", - "lets_practice_course": "የኮርሱን ልምምድ እንለማመድ", - "lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!", - "speaking": "እየተናገረ ነው", - "you_have_finished_practice": "ልምምድህን አጠናቀቅህ", - "view_results": "ውጤቶቼን እይ", - "sample_answer": "ናሙና መልስ", - "your_answer": "መልስህ", - "sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!", - "you_have_completed": "አያይ! አጠናቀቅህ", - "yes": "አዎ", - "no": "አይ", - "want_to_quit": "ለመውጣት እርግጠኛ ነህ?", - "required_field": "ይህ መስክ ያስፈልጋል", - "enter_full_name": "ሙሉ ስምህን አስገባ", - "invalid_email": "የማይሰራ የኢሜይል ቅርጸት", - "phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት", - "phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት", - "what_should_we_call_you": "ምን ብለን እንጠራህ?", - "name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።", - "choose_your_gender": "ጾታህን ምረጥ", - "gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?", - "age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?", - "education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።", - "your_occupation": "ስራህ ምንድን ነው?", - "occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "location": "ከየት ነህ?", - "select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ", - "select_country": "አገር ምረጥ", - "learning_goal": "የመማር ዓላማህን ምረጥ", - "language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?", - "your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።", - "write_your_goal": "ዓላማህን ጻፍ…", - "challenge_you_face": "What challenge do you face most with English?", - "evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ", - "write_your_challenge": "ችግርህን ጻፍ…", - "topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?", - "favourite_topic": - "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።", - "your_interest": "ፍላጎትህን ጻፍ…", - "want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?", - "answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።", - "skip": "ዝለል", - "finish_level": "ደረጃውን አጠናቅቅ", - "likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ", - "great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።", - "lets_start_practice": "ልምምድህን እንጀምር", - "welcome_abroad": "እንኳን ደህና መጣህ", - "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", - "finish": "አጠናቅቅ", - "finish_all_practice": "ልምምዱን ለመውሰድ በትምህርቶቹ ውስጥ ያሉትን ሁሉንም ልምምዶች ያጠናቅቁ።" - }; - static const Map _en = { - "loading": "Loading", - "welcome_back": "Welcome back", - "checking_user_info": "Checking user info", - "dont_have_account": "Don't have an account?", - "email": "Email", - "password": "Password", - "forgot_password": "Forgot password?", - "cont": "Continue", - "register": "Register", - "login_with_google": "Login with Google", - "or": "Or", - "login_with_phone": "Login with phone number", - "create_account": "Create an account", - "already_have_account": "Already have an account?", - "login": "Login", - "register_with_google": "Register with Google", - "register_with_phone": "Register with phone number", - "enter_phone_number": - "Enter your phone number. We will send you a confirmation code there.", - "login_with_email": "Login with email", - "create_password": "Create password", - "confirm_password": "Confirm password", - "eight_character_minimum": "8 characters minimum", - "password_match": "password match", - "sign_up_agreement": - "By clicking ‘Sign Up’, you agree to our ‘Terms of Service’ and ‘Privacy Policy’", - "terms_of_services": "Terms of Service", - "and": "and", - "privacy_policy": "Privacy Policy", - "register_with_email": "Register with email", - "verification_code": "Verification Code", - "resend_code": "Resend Code", - "code_sent_to_phone": "Code sent to your number", - "code_sent_to_email": "Code sent to your email", - "resend_code_in": "Resend code in", - "reset_password": "Reset Password", - "enter_email_reset_code": - "Enter your email. We will send you a reset code.", - "please_wait": "Please wait", - "reset_code_sent": "Reset code sent successfully", - "reset_code": "Reset code", - "new_password": "New password", - "logged_in_successfully": "Logged in successfully", - "continue_learning": "Continue Learning", - "start_learning": "Start Learning", - "completed": "Completed", - "view_course": "View course", - "take_practice": "Take practice", - "your_current_level": "Your current level", - "overall_progress": "Overall progress", - "great_work": "Keep up the great work! You're doing amazing", - "view_module": "View module", - "progress": "Progress", - "keep_going": "Let's keep going - you're more than half there", - "lessons_in_module": "Lessons in this module", - "practice": "Practice", - "start": "Start", - "in_progress": "In Progress", - "hello": "Hello", - "ready_to_learn": "Ready to keep learning English today", - "learn": "Learn", - "course": "Course", - "profile": "Profile", - "speaking_partner": "Speaking partner", - "practice_what_you_learned": "Let's practice what you just learnt", - "practice_questions": "I will ask you a few questions and you can respond", - "start_practice": "Start practice", - "almost_there": "You're almost there", - "finish_session": "Finish the session to see your progress", - "continue_practice": "Continue practice", - "end_session": "End session", - "tap_start_to_listen": "Tap the start button to listen", - "practice_speaking": "Practice speaking", - "tap_microphone": "Tap the microphone to speak", - "reply": "Reply", - "cancel": "Cancel", - "you_are_speaking": "You're speaking", - "practice_completed": "Practice completed!", - "great_improvement": - "You sound more confident this time, great improvement", - "practice_again": "Practice again", - "conversation_review": "Conversation review", - "result": "Result", - "quick_tip": "Quick tip", - "retry": "Retry", - "completed_a1": "Yay, you've completed A1", - "analyzing_speaking": "We're now analyzing your speaking skill", - "view_profile": "View profile", - "hi": "Hi", - "edit_profile": "Edit profile", - "first_name": "First name", - "last_name": "Last name", - "gender": "Gender", - "male": "Male", - "female": "Female", - "phone_number": "Phone number", - "country": "Country", - "region": "Region", - "select_region": "Select region", - "enter_your_city": "Enter your city", - "occupation": "Occupation", - "select_occupation": "Select occupation", - "save_changes": "Save changes", - "my_progress": "My progress", - "track_your_achievement": "Track your achievements and learning streak", - "account_and_privacy": "Account & Privacy", - "manage_settings": "Manage settings and app preference", - "support": "Support", - "get_help": "Get help through phone or Telegram", - "logout": "Logout", - "app_settings": "App settings", - "legal_and_information": "Legal & Information", - "change_language": "Change language", - "terms_and_conditions": "Terms & Conditions", - "delete_account": "Delete account", - "language_preference": "Language preference", - "choose_your_language": "Choose your language", - "switch_language_anytime": "You can switch languages anytime", - "need_help": "Need help?", - "call_support": "Call support", - "talk_with_support": "Talk with our support team directly", - "telegram_support": "Telegram support", - "chat_via_telegram": "Chat instantly via Telegram", - "call_our_support": "Call our support team between 9 AM - 6 PM", - "tap_to_call": "Tap to call", - "join_telegram": "Join Yimaru Academy on Telegram", - "connect_with_support_team": - "Connect with our support team instantly on Telegram for quick assistance and community updates", - "open_in_telegram": "Open in Telegram", - "search_for": "Search for", - "current_level": "Current Level", - "keep_up_the_great_work": "Keep up the great work! You're doing amazing.", - "no_practice_available": "No practice available!", - "begin_module_practice": "Begin Module Practice", - "lets_practice_lesson": "Let’s Practice", - "lets_quickly_review": - "Let’s quickly review what you’ve learned in this module!", - "lets_practice_module": "Let's practice what you just learnt!", - "ask_you_few_actions": - "I’ll ask you a few questions, and you can respond naturally.", - "begin_level_practice": "Begin Level Practice", - "lets_practice_course": "Let’s Practice Course", - "lets_quick_review": - "Let’s quickly review what you’ve learned in this level!", - "speaking": "is speaking...", - "you_have_finished_practice": "You have finished your practice", - "view_results": "View My Results", - "sample_answer": "Sample Answer", - "your_answer": "Your Answer", - "sound_confident": - "You sound more confident this time - great improvement!", - "you_have_completed": "Yay, you’ve completed", - "yes": "Yes", - "no": "No", - "want_to_quit": "Are you sure you want to quit?", - "required_field": "The field is required", - "enter_full_name": "Enter your full name", - "invalid_email": "Invalid email format", - "phone_must_start_with": "Phone number must start with 251", - "phone_must_be": "Phone number must be 12 digits", - "what_should_we_call_you": "What should we call you?", - "name_for_personalization": - "We’ll use your name to personalize your learning journey.", - "choose_your_gender": "Choose your gender?", - "gender_for_personalization": - "We’ll personalize your learning experience based on your gender.", - "age_range": "Which age range are you in?", - "age_for_personalization": - "We’ll personalize your learning experience based on your age.", - "educational_background": "What’s your current educational level?", - "education_for_personalization": - "This helps us tailor your lessons to your experience.", - "your_occupation": "What’s your occupation?", - "occupation_for_personalization": - "We’ll personalize your learning experience based on your occupation.", - "location": "Where are you from?", - "select_country_region": "Select your country and region from the dropdown", - "select_country": "Select country", - "learning_goal": "Choose your learning goal.", - "language_goal": "What’s your main goal for improving your English?", - "your_goal": "Your goal helps us tailor your learning journey.", - "write_your_goal": "Write your goal…", - "challenge_you_face": "What challenge do you face most with English?", - "evey_one_has_strugle": "Everyone has struggles, let’s start fixing yours", - "write_your_challenge": "Write your challenge…", - "topic_interest": "Which topics interest you most?", - "favourite_topic": - "Your favorite topics help us create fun, relatable lessons.", - "your_interest": "Write your interest…", - "want_quick_assessment": - "Want a quick assessment to know your English level?", - "answer_quick_questions": - "Answer a few quick questions to help us understand your English proficiency.", - "skip": "Skip", - "finish_level": "Finish Level", - "likely_speaker": "You’re likely speaker of", - "great_job": "Great Job! Here’s your next step to keep improving.", - "lets_start_practice": "Let's start your practice", - "welcome_abroad": "Welcome aboard", - "ready_to_explore": "You’re ready to explore your personalized lessons.", - "finish": "Finish", - "finish_all_practice": - "Finish all the practices in the lessons to take this practice" - }; - static const Map> mapLocales = { - "am": _am, - "en": _en - }; + static const Map _am = { + "loading": "በመጫን ላይ", + "welcome_back": "እንኳን በደህና ተመለሱ", + "checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ", + "dont_have_account": "መለያ የለዎትም?", + "email": "ኢሜይል", + "password": "የይለፍ ቃል", + "forgot_password": "የይለፍ ቃል ረሱ?", + "cont": "ቀጥል", + "register": "ይመዝገቡ", + "login_with_google": "በጉግል ይግቡ", + "or": "ወይም", + "login_with_phone": "በስልክ ቁጥር ይግቡ", + "create_account": "አዲስ መለያ ይፍጠሩ", + "already_have_account": "መለያ አለዎት?", + "login": " ይግቡ ", + "register_with_google": "በጉግል ይመዝገቡ", + "register_with_phone": "በስልክ ቁጥር ይመዝገቡ", + "enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።", + "login_with_email": "በኢሜይል ይግቡ", + "create_password": "የይለፍ ቃል ይፍጠሩ", + "confirm_password": "የይለፍ ቃል ያረጋግጡ", + "eight_character_minimum": "ቢያንስ 8 ፊደላት", + "password_match": "የይለፍ ቃሉ ተመሳስሏል", + "sign_up_agreement": "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", + "terms_of_services": "የአገልግሎት ውሎች", + "and": "እና", + "privacy_policy": "የግላዊነት ፖሊሲ", + "register_with_email": "በኢሜል ይመዝገቡ", + "verification_code": "የማረጋገጫ ኮድ", + "resend_code": "ኮዱን እንደገና ላክ", + "code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል", + "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", + "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", + "reset_password": " የይለፍ ቃልን ይቀይሩ", + "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", + "please_wait": "እባክዎ ይጠብቁ", + "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", + "reset_code": " የመቀየሪያ ኮድ ", + "new_password": "አዲስ የይለፍ ቃል", + "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", + "view_course": " ኮርሱን ይመልከቱ", + "continue_learning": "መማርን ይቀጥሉ", + "start_learning": "ትምህርትን ይጀምሩ", + "completed": "ተጠናቋል", + "take_practice": "ልምምድ ያድርጉ", + "your_current_level": "የአሁኑ ደረጃዎ", + "overall_progress": "አጠቃላይ እድገት", + "great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው", + "view_module": "ሞጁሉን ይመልከቱ", + "progress": "እድገት", + "keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ", + "lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ", + "practice": "ልምምድ", + "start": "ጀምር", + "in_progress": "በሂደት ላይ", + "hello": "ሰላም", + "ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ", + "learn": "ይማሩ ", + "course": "ኮርስ", + "profile": " ፕሮፋይል ", + "speaking_partner": "የንግግር ጓደኛ", + "practice_what_you_learned": "አሁን የተማሩትን እንለማመድ", + "practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ", + "start_practice": "ልምምድ ጀምር", + "almost_there": "ሊጨርሱ ተቃርበዋል", + "finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ", + "continue_practice": "ልምምዱን ይቀጥሉ", + "end_session": "ክፍለ ጊዜውን ያብቁ ", + "tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ", + "practice_speaking": "ንግግርን ይለማመዱ", + "tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ", + "reply": "እንደገና አዳምጥ", + "cancel": "ይቅር", + "you_are_speaking": "እየተናገሩ ነው", + "practice_completed": "ልምምዱ ተጠናቅቋል", + "great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው", + "practice_again": "እንደገና ይለማመዱ", + "conversation_review": "የንግግር ግምገማ", + "result": "ውጤት", + "quick_tip": "ጠቃሚ ምክር", + "retry": "እንደገና ይሞክሩ", + "completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል", + "analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው", + "view_profile": "ፕሮፋይሎን ይመልከቱ ", + "hi": "ሰላም", + "edit_profile": "መገለጫ ያስተካክሉ", + "first_name": "የመጀመሪያ ስም", + "last_name": "የአባት ስም", + "gender": "ፆታ", + "male": "ወንድ", + "female": "ሴት", + "phone_number": "የስልክ ቁጥር", + "country": "ሀገር", + "region": "ክልል", + "select_region": "ክልል ይምረጡ", + "enter_your_city": "ከተማዎን ያስገቡ", + "occupation": "የስራ መስክ", + "select_occupation": "ሙያዎን ይምረጡ", + "save_changes": "ለውጦችን ያስቀምጡ", + "my_progress": "የእኔ እድገት", + "track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ", + "account_and_privacy": "መለያ እና ግላዊነት", + "manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ", + "support": "ድጋፍ", + "get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ", + "logout": "ውጣ", + "app_settings": "የመተግበሪያ ቅንብሮች", + "legal_and_information": "ሕጋዊ እና መረጃ", + "change_language": "ቋንቋ ቀይር", + "terms_and_conditions": "ውሎች እና ሁኔታዎች", + "delete_account": "መለያ ሰርዝ", + "language_preference": "የቋንቋ ምርጫ", + "choose_your_language": "ለውጦችን አስቀምጥ", + "switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ", + "need_help": "እገዛ ይፈልጋሉ?", + "call_support": "የስልክ ድጋፍ", + "talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ", + "telegram_support": "የቴሌግራም ድጋፍ", + "chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ", + "call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ", + "tap_to_call": "ለመደወል ይንኩ", + "join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ", + "connect_with_support_team": "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።", + "open_in_telegram": "በቴሌግራም ይክፈቱ", + "search_for": "ፈልጉት", + "current_level": "የአሁኑ ደረጃ", + "keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።", + "no_practice_available": "ምንም ልምምድ አልተገኘም!", + "begin_module_practice": "የሞጁሉን ልምምድ ጀምር", + "lets_practice_lesson": "እንለማመድ", + "lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!", + "lets_practice_module": "አሁን የተማርከውን እንለማመድ!", + "ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።", + "begin_level_practice": "የደረጃ ልምምድን ጀምር", + "lets_practice_course": "የኮርሱን ልምምድ እንለማመድ", + "lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!", + "speaking": "እየተናገረ ነው", + "you_have_finished_practice": "ልምምድህን አጠናቀቅህ", + "view_results": "ውጤቶቼን እይ", + "sample_answer": "ናሙና መልስ", + "your_answer": "መልስህ", + "sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!", + "you_have_completed": "አያይ! አጠናቀቅህ", + "yes": "አዎ", + "no": "አይ", + "want_to_quit": "ለመውጣት እርግጠኛ ነህ?", + "required_field": "ይህ መስክ ያስፈልጋል", + "enter_full_name": "ሙሉ ስምህን አስገባ", + "invalid_email": "የማይሰራ የኢሜይል ቅርጸት", + "phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት", + "phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት", + "what_should_we_call_you": "ምን ብለን እንጠራህ?", + "name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።", + "choose_your_gender": "ጾታህን ምረጥ", + "gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?", + "age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?", + "education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።", + "your_occupation": "ስራህ ምንድን ነው?", + "occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "location": "ከየት ነህ?", + "select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ", + "select_country": "አገር ምረጥ", + "learning_goal": "የመማር ዓላማህን ምረጥ", + "language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?", + "your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።", + "write_your_goal": "ዓላማህን ጻፍ…", + "challenge_you_face": "What challenge do you face most with English?", + "evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ", + "write_your_challenge": "ችግርህን ጻፍ…", + "topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?", + "favourite_topic": "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።", + "your_interest": "ፍላጎትህን ጻፍ…", + "want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?", + "answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።", + "skip": "ዝለል", + "finish_level": "ደረጃውን አጠናቅቅ", + "likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ", + "great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።", + "lets_start_practice": "ልምምድህን እንጀምር", + "welcome_abroad": "እንኳን ደህና መጣህ", + "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", + "finish": "አጠናቅቅ", + "finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ", + "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", + "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", + "finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", + "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ" +}; +static const Map _en = { + "loading": "Loading", + "welcome_back": "Welcome back", + "checking_user_info": "Checking user info", + "dont_have_account": "Don't have an account?", + "email": "Email", + "password": "Password", + "forgot_password": "Forgot password?", + "cont": "Continue", + "register": "Register", + "login_with_google": "Login with Google", + "or": "Or", + "login_with_phone": "Login with phone number", + "create_account": "Create an account", + "already_have_account": "Already have an account?", + "login": "Login", + "register_with_google": "Register with Google", + "register_with_phone": "Register with phone number", + "enter_phone_number": "Enter your phone number. We will send you a confirmation code there.", + "login_with_email": "Login with email", + "create_password": "Create password", + "confirm_password": "Confirm password", + "eight_character_minimum": "8 characters minimum", + "password_match": "password match", + "sign_up_agreement": "By clicking ‘Sign Up’, you agree to our ‘Terms of Service’ and ‘Privacy Policy’", + "terms_of_services": "Terms of Service", + "and": "and", + "privacy_policy": "Privacy Policy", + "register_with_email": "Register with email", + "verification_code": "Verification Code", + "resend_code": "Resend Code", + "code_sent_to_phone": "Code sent to your number", + "code_sent_to_email": "Code sent to your email", + "resend_code_in": "Resend code in", + "reset_password": "Reset Password", + "enter_email_reset_code": "Enter your email. We will send you a reset code.", + "please_wait": "Please wait", + "reset_code_sent": "Reset code sent successfully", + "reset_code": "Reset code", + "new_password": "New password", + "logged_in_successfully": "Logged in successfully", + "continue_learning": "Continue Learning", + "start_learning": "Start Learning", + "completed": "Completed", + "view_course": "View course", + "take_practice": "Take practice", + "your_current_level": "Your current level", + "overall_progress": "Overall progress", + "great_work": "Keep up the great work! You're doing amazing", + "view_module": "View module", + "progress": "Progress", + "keep_going": "Let's keep going - you're more than half there", + "lessons_in_module": "Lessons in this module", + "practice": "Practice", + "start": "Start", + "in_progress": "In Progress", + "hello": "Hello", + "ready_to_learn": "Ready to keep learning English today", + "learn": "Learn", + "course": "Course", + "profile": "Profile", + "speaking_partner": "Speaking partner", + "practice_what_you_learned": "Let's practice what you just learnt", + "practice_questions": "I will ask you a few questions and you can respond", + "start_practice": "Start practice", + "almost_there": "You're almost there", + "finish_session": "Finish the session to see your progress", + "continue_practice": "Continue practice", + "end_session": "End session", + "tap_start_to_listen": "Tap the start button to listen", + "practice_speaking": "Practice speaking", + "tap_microphone": "Tap the microphone to speak", + "reply": "Reply", + "cancel": "Cancel", + "you_are_speaking": "You're speaking", + "practice_completed": "Practice completed!", + "great_improvement": "You sound more confident this time, great improvement", + "practice_again": "Practice again", + "conversation_review": "Conversation review", + "result": "Result", + "quick_tip": "Quick tip", + "retry": "Retry", + "completed_a1": "Yay, you've completed A1", + "analyzing_speaking": "We're now analyzing your speaking skill", + "view_profile": "View profile", + "hi": "Hi", + "edit_profile": "Edit profile", + "first_name": "First name", + "last_name": "Last name", + "gender": "Gender", + "male": "Male", + "female": "Female", + "phone_number": "Phone number", + "country": "Country", + "region": "Region", + "select_region": "Select region", + "enter_your_city": "Enter your city", + "occupation": "Occupation", + "select_occupation": "Select occupation", + "save_changes": "Save changes", + "my_progress": "My progress", + "track_your_achievement": "Track your achievements and learning streak", + "account_and_privacy": "Account & Privacy", + "manage_settings": "Manage settings and app preference", + "support": "Support", + "get_help": "Get help through phone or Telegram", + "logout": "Logout", + "app_settings": "App settings", + "legal_and_information": "Legal & Information", + "change_language": "Change language", + "terms_and_conditions": "Terms & Conditions", + "delete_account": "Delete account", + "language_preference": "Language preference", + "choose_your_language": "Choose your language", + "switch_language_anytime": "You can switch languages anytime", + "need_help": "Need help?", + "call_support": "Call support", + "talk_with_support": "Talk with our support team directly", + "telegram_support": "Telegram support", + "chat_via_telegram": "Chat instantly via Telegram", + "call_our_support": "Call our support team between 9 AM - 6 PM", + "tap_to_call": "Tap to call", + "join_telegram": "Join Yimaru Academy on Telegram", + "connect_with_support_team": "Connect with our support team instantly on Telegram for quick assistance and community updates", + "open_in_telegram": "Open in Telegram", + "search_for": "Search for", + "current_level": "Current Level", + "keep_up_the_great_work": "Keep up the great work! You're doing amazing.", + "no_practice_available": "No practice available!", + "begin_module_practice": "Begin Module Practice", + "lets_practice_lesson": "Let’s Practice", + "lets_quickly_review": "Let’s quickly review what you’ve learned in this module!", + "lets_practice_module": "Let's practice what you just learnt!", + "ask_you_few_actions": "I’ll ask you a few questions, and you can respond naturally.", + "begin_level_practice": "Begin Level Practice", + "lets_practice_course": "Let’s Practice Course", + "lets_quick_review": "Let’s quickly review what you’ve learned in this level!", + "speaking": "is speaking...", + "you_have_finished_practice": "You have finished your practice", + "view_results": "View My Results", + "sample_answer": "Sample Answer", + "your_answer": "Your Answer", + "sound_confident": "You sound more confident this time - great improvement!", + "you_have_completed": "Yay, you’ve completed", + "yes": "Yes", + "no": "No", + "want_to_quit": "Are you sure you want to quit?", + "required_field": "The field is required", + "enter_full_name": "Enter your full name", + "invalid_email": "Invalid email format", + "phone_must_start_with": "Phone number must start with 251", + "phone_must_be": "Phone number must be 12 digits", + "what_should_we_call_you": "What should we call you?", + "name_for_personalization": "We’ll use your name to personalize your learning journey.", + "choose_your_gender": "Choose your gender?", + "gender_for_personalization": "We’ll personalize your learning experience based on your gender.", + "age_range": "Which age range are you in?", + "age_for_personalization": "We’ll personalize your learning experience based on your age.", + "educational_background": "What’s your current educational level?", + "education_for_personalization": "This helps us tailor your lessons to your experience.", + "your_occupation": "What’s your occupation?", + "occupation_for_personalization": "We’ll personalize your learning experience based on your occupation.", + "location": "Where are you from?", + "select_country_region": "Select your country and region from the dropdown", + "select_country": "Select country", + "learning_goal": "Choose your learning goal.", + "language_goal": "What’s your main goal for improving your English?", + "your_goal": "Your goal helps us tailor your learning journey.", + "write_your_goal": "Write your goal…", + "challenge_you_face": "What challenge do you face most with English?", + "evey_one_has_strugle": "Everyone has struggles, let’s start fixing yours", + "write_your_challenge": "Write your challenge…", + "topic_interest": "Which topics interest you most?", + "favourite_topic": "Your favorite topics help us create fun, relatable lessons.", + "your_interest": "Write your interest…", + "want_quick_assessment": "Want a quick assessment to know your English level?", + "answer_quick_questions": "Answer a few quick questions to help us understand your English proficiency.", + "skip": "Skip", + "finish_level": "Finish Level", + "likely_speaker": "You’re likely speaker of", + "great_job": "Great Job! Here’s your next step to keep improving.", + "lets_start_practice": "Let's start your practice", + "welcome_abroad": "Welcome aboard", + "ready_to_explore": "You’re ready to explore your personalized lessons.", + "finish": "Finish", + "finish_all_practice_lesson": "Finish the previous lesson practice to take this practice", + "finish_all_practice_module": "Finish the lesson practices to take the Module Practice", + "finish_all_practice_course": "Finish the Module practices to take the Course practice", + "finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice", + "finish_all_practice_previouse_course": "Finish the previous course practice to take this" +}; +static const Map> mapLocales = {"am": _am, "en": _en}; } diff --git a/lib/ui/common/translations/locale_keys.g.dart b/lib/ui/common/translations/locale_keys.g.dart index a3c563d..31c729d 100644 --- a/lib/ui/common/translations/locale_keys.g.dart +++ b/lib/ui/common/translations/locale_keys.g.dart @@ -2,7 +2,7 @@ // ignore_for_file: constant_identifier_names -abstract class LocaleKeys { +abstract class LocaleKeys { static const loading = 'loading'; static const welcome_back = 'welcome_back'; static const checking_user_info = 'checking_user_info'; @@ -161,8 +161,7 @@ abstract class LocaleKeys { static const educational_background = 'educational_background'; static const education_for_personalization = 'education_for_personalization'; static const your_occupation = 'your_occupation'; - static const occupation_for_personalization = - 'occupation_for_personalization'; + static const occupation_for_personalization = 'occupation_for_personalization'; static const location = 'location'; static const select_country_region = 'select_country_region'; static const select_country = 'select_country'; @@ -186,5 +185,10 @@ abstract class LocaleKeys { static const welcome_abroad = 'welcome_abroad'; static const ready_to_explore = 'ready_to_explore'; static const finish = 'finish'; - static const finish_all_practice = 'finish_all_practice'; + static const finish_all_practice_lesson = 'finish_all_practice_lesson'; + static const finish_all_practice_module = 'finish_all_practice_module'; + static const finish_all_practice_course = 'finish_all_practice_course'; + static const finish_all_practice_previouse_module = 'finish_all_practice_previouse_module'; + static const finish_all_practice_previouse_course = 'finish_all_practice_previouse_course'; + } diff --git a/lib/ui/views/arif_pay/arif_pay_viewmodel.dart b/lib/ui/views/arif_pay/arif_pay_viewmodel.dart index e616ddf..9aa4457 100644 --- a/lib/ui/views/arif_pay/arif_pay_viewmodel.dart +++ b/lib/ui/views/arif_pay/arif_pay_viewmodel.dart @@ -53,8 +53,8 @@ class ArifPayViewModel extends ReactiveViewModel { if (await _statusChecker.checkConnection()) { Map data = { 'plan_id': 1, + 'provider': 'CHAPA', 'phone': '251$phone', - 'provider': 'ARIFPAY', 'email': 'test@gmail.com', }; diff --git a/lib/ui/views/assessment/assessment_view.dart b/lib/ui/views/assessment/assessment_view.dart index d5210b8..ff9be72 100644 --- a/lib/ui/views/assessment/assessment_view.dart +++ b/lib/ui/views/assessment/assessment_view.dart @@ -52,9 +52,9 @@ class AssessmentView extends StackedView { ]; Widget _buildAssessmentIntroWrapper(AssessmentViewModel viewModel) => - viewModel.busy(StateObjects.assessments) || viewModel.assessments.isEmpty + viewModel.busy(StateObjects.assessments) ? _buildPageLoadingIndicator(viewModel) - : _buildAssessmentIntro(); + : _buildAssessmentIntro(viewModel); Widget _buildPageLoadingIndicator(AssessmentViewModel viewModel) => AssessmentLoadingScreen( @@ -64,7 +64,10 @@ class AssessmentView extends StackedView { onPop: viewModel.assessments.isEmpty ? viewModel.pop : null, ); - Widget _buildAssessmentIntro() => const AssessmentIntroScreen(); + Widget _buildAssessmentIntro(AssessmentViewModel viewModel) => + AssessmentIntroScreen( + hasAssessments: viewModel.assessments.isNotEmpty, + ); Widget _buildAssessment() => const AssessmentQuestionsScreen(); diff --git a/lib/ui/views/assessment/screens/assessment_intro_screen.dart b/lib/ui/views/assessment/screens/assessment_intro_screen.dart index 8315824..b4f1ab0 100644 --- a/lib/ui/views/assessment/screens/assessment_intro_screen.dart +++ b/lib/ui/views/assessment/screens/assessment_intro_screen.dart @@ -10,7 +10,9 @@ import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; import '../assessment_viewmodel.dart'; class AssessmentIntroScreen extends ViewModelWidget { - const AssessmentIntroScreen({super.key}); + final bool hasAssessments; + + const AssessmentIntroScreen({super.key, required this.hasAssessments}); Future _next(AssessmentViewModel viewModel) async => viewModel.setFirstAssessment(); @@ -29,11 +31,8 @@ class AssessmentIntroScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(AssessmentViewModel viewModel) => [ - _buildAppBar(viewModel), - verticalSpaceMedium, - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(AssessmentViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(AssessmentViewModel viewModel) => Expanded(child: _buildBodyWrapper(viewModel)); @@ -59,7 +58,7 @@ class AssessmentIntroScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(AssessmentViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), @@ -91,7 +90,7 @@ class AssessmentIntroScreen extends ViewModelWidget { ); List _buildLowerColumnChildren(AssessmentViewModel viewModel) => [ - _buildContinueButton(viewModel), + if (hasAssessments) _buildContinueButton(viewModel), verticalSpaceSmall, _buildSkipButtonWrapper(viewModel) ]; diff --git a/lib/ui/views/assessment/screens/assessment_result_screen.dart b/lib/ui/views/assessment/screens/assessment_result_screen.dart index 51fa739..b9bea31 100644 --- a/lib/ui/views/assessment/screens/assessment_result_screen.dart +++ b/lib/ui/views/assessment/screens/assessment_result_screen.dart @@ -29,7 +29,6 @@ class AssessmentResultScreen extends ViewModelWidget { List _buildScaffoldChildren(AssessmentViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; diff --git a/lib/ui/views/assessment/screens/start_lesson_screen.dart b/lib/ui/views/assessment/screens/start_lesson_screen.dart index b43ba38..ddf08c6 100644 --- a/lib/ui/views/assessment/screens/start_lesson_screen.dart +++ b/lib/ui/views/assessment/screens/start_lesson_screen.dart @@ -46,7 +46,6 @@ class StartLessonScreen extends ViewModelWidget { List _buildScaffoldChildren(AssessmentViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; diff --git a/lib/ui/views/forget_password/screens/request_reset_code_screen.dart b/lib/ui/views/forget_password/screens/request_reset_code_screen.dart index 936c0e9..d3bb1ae 100644 --- a/lib/ui/views/forget_password/screens/request_reset_code_screen.dart +++ b/lib/ui/views/forget_password/screens/request_reset_code_screen.dart @@ -88,7 +88,6 @@ class RequestCodeScreen extends ViewModelWidget { required ForgetPasswordViewModel viewModel}) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(context: context, viewModel: viewModel) ]; diff --git a/lib/ui/views/forget_password/screens/reset_password_screen.dart b/lib/ui/views/forget_password/screens/reset_password_screen.dart index 0ffcfaf..9eba173 100644 --- a/lib/ui/views/forget_password/screens/reset_password_screen.dart +++ b/lib/ui/views/forget_password/screens/reset_password_screen.dart @@ -88,7 +88,6 @@ class ResetPasswordScreen extends ViewModelWidget { List _buildScaffoldChildren(ForgetPasswordViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; diff --git a/lib/ui/views/learn_course/learn_course_view.dart b/lib/ui/views/learn_course/learn_course_view.dart index 4d97831..076dc27 100644 --- a/lib/ui/views/learn_course/learn_course_view.dart +++ b/lib/ui/views/learn_course/learn_course_view.dart @@ -24,17 +24,28 @@ class LearnCourseView extends StackedView { await viewModel.navigateToLearnPractice( id: course.id ?? 0, level: course.name ?? ''); } else { - await _showSheet(context: context, viewModel: viewModel); + if (course.access?.isAccessible ?? false) { + await _showSheet( + context: context, + viewModel: viewModel, + practice: PracticeReason.course); + } else { + await _showSheet( + context: context, + viewModel: viewModel, + practice: PracticeReason.previousCourse); + } } } Future _showSheet( {required BuildContext context, + required PracticeReason practice, required LearnCourseViewModel viewModel}) async => await showModalBottomSheet( context: context, backgroundColor: kcTransparent, - builder: (_) => _buildSheet(viewModel), + builder: (_) => _buildSheet(viewModel: viewModel, practice: practice), ); @override @@ -156,6 +167,11 @@ class LearnCourseView extends StackedView { onPracticeTap: onPracticeTap, ); - Widget _buildSheet(LearnCourseViewModel viewModel) => - FinishPracticeSheet(onTap: viewModel.pop); + Widget _buildSheet( + {required PracticeReason practice, + required LearnCourseViewModel viewModel}) => + FinishPracticeSheet( + practice: practice, + onTap: viewModel.pop, + ); } diff --git a/lib/ui/views/learn_lesson/learn_lesson_view.dart b/lib/ui/views/learn_lesson/learn_lesson_view.dart index 7307f3e..1abb676 100644 --- a/lib/ui/views/learn_lesson/learn_lesson_view.dart +++ b/lib/ui/views/learn_lesson/learn_lesson_view.dart @@ -31,15 +31,23 @@ class LearnLessonView extends StackedView { } else { await _showSheet(context: context, viewModel: viewModel); } - - /* if (index > 1) { +/* + if (index > 1) { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { - await viewModel.navigateToLearnPractice(lesson.id ?? 0); + if (lesson.access?.isAccessible ?? false) { + await viewModel.navigateToLearnPractice(lesson.id ?? 0); + } else { + await _showSheet(context: context, viewModel: viewModel); + } } else { await viewModel.navigateToLearnSubscription(); } } else { - await viewModel.navigateToLearnPractice(lesson.id ?? 0); + if (lesson.access?.isAccessible ?? false) { + await viewModel.navigateToLearnPractice(lesson.id ?? 0); + } else { + await _showSheet(context: context, viewModel: viewModel); + } }*/ } @@ -162,7 +170,7 @@ class LearnLessonView extends StackedView { verticalSpaceLarge, _buildHeader(), verticalSpaceMedium, - _buildListViewBuilder(context: context,viewModel: viewModel), + _buildListViewBuilder(context: context, viewModel: viewModel), ]; Widget _buildTitle() => Text( @@ -197,24 +205,28 @@ class LearnLessonView extends StackedView { style: style18DG700, ); - Widget _buildListViewBuilder( {required BuildContext context, - required LearnLessonViewModel viewModel}) => + Widget _buildListViewBuilder( + {required BuildContext context, + required LearnLessonViewModel viewModel}) => viewModel.busy(StateObjects.learnLessons) ? _buildProgressIndicator() - : _buildListView(context: context,viewModel: viewModel); + : _buildListView(context: context, viewModel: viewModel); Widget _buildProgressIndicator() => const Center( child: CustomCircularProgressIndicator(color: kcPrimaryColor), ); - Widget _buildListView( {required BuildContext context, -required LearnLessonViewModel viewModel}) => ListView.builder( + Widget _buildListView( + {required BuildContext context, + required LearnLessonViewModel viewModel}) => + ListView.builder( shrinkWrap: true, itemCount: viewModel.lessons.length, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) => _buildTile( index: index, lesson: viewModel.lessons[index], + last: index == viewModel.lessons.length - 1 , onPracticeTap: () async => await _onPractice( index: index, context: context, @@ -231,18 +243,23 @@ required LearnLessonViewModel viewModel}) => ListView.builder( ); Widget _buildTile({ + required bool last, required int index, required LearnLesson lesson, required GestureTapCallback? onLessonTap, required GestureTapCallback? onPracticeTap, }) => LearnLessonTile( + last: last, index: index, + lesson: lesson, onLessonTap: onLessonTap, onPracticeTap: onPracticeTap, ); - Widget _buildSheet(LearnLessonViewModel viewModel) => - FinishPracticeSheet(onTap: viewModel.pop); + Widget _buildSheet(LearnLessonViewModel viewModel) => FinishPracticeSheet( + onTap: viewModel.pop, + practice: PracticeReason.lesson, + ); } diff --git a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart index 5f502de..5f9dcea 100644 --- a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart +++ b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart @@ -33,13 +33,18 @@ class LearnLessonDetailView extends StackedView { required LearnLessonDetailViewModel viewModel}) async { await viewModel.pause(); await viewModel.navigateToLearnPractice(lesson.id ?? 0); - /*if (index > 1) { + + + /* if (index > 1) { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { + await viewModel.pause(); await viewModel.navigateToLearnPractice(lesson.id ?? 0); } else { + await viewModel.pause(); await viewModel.navigateToLearnSubscription(); } } else { + await viewModel.pause(); await viewModel.navigateToLearnPractice(lesson.id ?? 0); }*/ } diff --git a/lib/ui/views/learn_module/learn_module_view.dart b/lib/ui/views/learn_module/learn_module_view.dart index e9a4e18..3bdc3ed 100644 --- a/lib/ui/views/learn_module/learn_module_view.dart +++ b/lib/ui/views/learn_module/learn_module_view.dart @@ -17,27 +17,42 @@ import 'learn_module_viewmodel.dart'; class LearnModuleView extends StackedView { final LearnCourse course; + const LearnModuleView({Key? key, required this.course}) : super(key: key); Future _onPractice( {required BuildContext context, required LearnModule module, required LearnModuleViewModel viewModel}) async { - if (module.access?.completedCount == module.access?.totalCount) { + if (module.access?.completedCount == module.access?.totalCount ) { await viewModel.navigateToLearnPractice( id: module.id ?? 0, module: module.name ?? ''); } else { - await _showSheet(context: context, viewModel: viewModel); + if (module.access?.isAccessible ?? false) { + print('Accessible'); + await _showSheet( + context: context, + viewModel: viewModel, + practice: PracticeReason.module); + } else { + print('Inaccessible'); + + await _showSheet( + context: context, + viewModel: viewModel, + practice: PracticeReason.previousModule); + } } } Future _showSheet( {required BuildContext context, + required PracticeReason practice, required LearnModuleViewModel viewModel}) async => await showModalBottomSheet( context: context, backgroundColor: kcTransparent, - builder: (_) => _buildSheet(viewModel), + builder: (_) => _buildSheet(viewModel: viewModel, practice: practice), ); @override @@ -201,6 +216,11 @@ class LearnModuleView extends StackedView { onModuleTap: onModuleTap, onPracticeTap: onPracticeTap); - Widget _buildSheet(LearnModuleViewModel viewModel) => - FinishPracticeSheet(onTap: viewModel.pop); + Widget _buildSheet( + {required PracticeReason practice, + required LearnModuleViewModel viewModel}) => + FinishPracticeSheet( + practice: practice, + onTap: viewModel.pop, + ); } diff --git a/lib/ui/views/onboarding/onboarding_view.dart b/lib/ui/views/onboarding/onboarding_view.dart index 4226d4c..436671a 100644 --- a/lib/ui/views/onboarding/onboarding_view.dart +++ b/lib/ui/views/onboarding/onboarding_view.dart @@ -8,8 +8,8 @@ import 'package:yimaru_app/ui/views/onboarding/screens/country_region_form_scree import 'package:yimaru_app/ui/views/onboarding/screens/educational_background_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/full_name_form_screen.dart'; import 'package:yimaru_app/ui/views/onboarding/screens/gender_form_screen.dart'; -import 'package:yimaru_app/ui/views/onboarding/screens/language_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/language_goal_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'; @@ -129,9 +129,9 @@ class OnboardingView extends StackedView Widget _buildCountryRegionForm() => CountryRegionFormScreen(regionController: regionController); - Widget _buildLearningGoalForm() => const LearningGoalFormScreen(); + Widget _buildLearningGoalForm() => const LanguageGoalFormScreens(); - Widget _buildLanguageGoalForm() => const LanguageGoalFormScreen(); + Widget _buildLanguageGoalForm() => const LearningGoalFormScreen(); Widget _buildChallengeForm() => const ChallengeFormScreen(); diff --git a/lib/ui/views/onboarding/onboarding_viewmodel.dart b/lib/ui/views/onboarding/onboarding_viewmodel.dart index d57e5f4..ef06bb9 100644 --- a/lib/ui/views/onboarding/onboarding_viewmodel.dart +++ b/lib/ui/views/onboarding/onboarding_viewmodel.dart @@ -243,8 +243,7 @@ class OnboardingViewModel extends ReactiveViewModel bool isSelectedLearningGoal(FieldOption value) => _selectedLearningGoal == value; - // Learning reason - + // Language goal void setSelectedLanguageGoal(FieldOption value) { _selectedLanguageGoal = value; diff --git a/lib/ui/views/onboarding/screens/age_group_form_screen.dart b/lib/ui/views/onboarding/screens/age_group_form_screen.dart index 6a6e351..1fc2f9e 100644 --- a/lib/ui/views/onboarding/screens/age_group_form_screen.dart +++ b/lib/ui/views/onboarding/screens/age_group_form_screen.dart @@ -43,7 +43,6 @@ class AgeGroupFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -76,7 +75,7 @@ class AgeGroupFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/challenge_form_screen.dart b/lib/ui/views/onboarding/screens/challenge_form_screen.dart index 0da8457..0b111c2 100644 --- a/lib/ui/views/onboarding/screens/challenge_form_screen.dart +++ b/lib/ui/views/onboarding/screens/challenge_form_screen.dart @@ -44,7 +44,6 @@ class ChallengeFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -77,7 +76,7 @@ class ChallengeFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/country_region_form_screen.dart b/lib/ui/views/onboarding/screens/country_region_form_screen.dart index 64f00ff..c49639d 100644 --- a/lib/ui/views/onboarding/screens/country_region_form_screen.dart +++ b/lib/ui/views/onboarding/screens/country_region_form_screen.dart @@ -60,7 +60,6 @@ class CountryRegionFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -93,7 +92,7 @@ class CountryRegionFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/educational_background_form_screen.dart b/lib/ui/views/onboarding/screens/educational_background_form_screen.dart index b01743c..849e3f3 100644 --- a/lib/ui/views/onboarding/screens/educational_background_form_screen.dart +++ b/lib/ui/views/onboarding/screens/educational_background_form_screen.dart @@ -45,7 +45,6 @@ class EducationalBackgroundFormScreen List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -78,7 +77,7 @@ class EducationalBackgroundFormScreen ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/full_name_form_screen.dart b/lib/ui/views/onboarding/screens/full_name_form_screen.dart index 7a03fda..d522bf6 100644 --- a/lib/ui/views/onboarding/screens/full_name_form_screen.dart +++ b/lib/ui/views/onboarding/screens/full_name_form_screen.dart @@ -42,7 +42,6 @@ class FullNameFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -75,7 +74,7 @@ class FullNameFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/gender_form_screen.dart b/lib/ui/views/onboarding/screens/gender_form_screen.dart index 3aaafb8..7898e3a 100644 --- a/lib/ui/views/onboarding/screens/gender_form_screen.dart +++ b/lib/ui/views/onboarding/screens/gender_form_screen.dart @@ -42,7 +42,6 @@ class GenderFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -70,7 +69,7 @@ class GenderFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/language_goal_form_screen.dart b/lib/ui/views/onboarding/screens/language_goal_form_screen.dart index 767cdf5..8360ee6 100644 --- a/lib/ui/views/onboarding/screens/language_goal_form_screen.dart +++ b/lib/ui/views/onboarding/screens/language_goal_form_screen.dart @@ -1,16 +1,43 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; +import 'package:iconsax/iconsax.dart'; import 'package:stacked/stacked.dart'; 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/ui_helpers.dart'; import 'package:yimaru_app/ui/widgets/custom_elevated_button.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_large_radio_button.dart'; import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; -class LanguageGoalFormScreen extends ViewModelWidget { - const LanguageGoalFormScreen({super.key}); +class LanguageGoalFormScreens extends ViewModelWidget { + const LanguageGoalFormScreens({super.key}); + + IconData getIcon(int index) { + switch (index) { + case 0: + return Iconsax.book; + case 1: + return Iconsax.microphone; + case 2: + return Iconsax.bag; + } + return Icons.book; + } + + + + String getSubtitle(int index) { + switch (index) { + case 0: + return 'I know some English, but i want to learn to speak it'; + case 1: + return 'I already speak English, but I want more practice.'; + case 2: + return 'I want courses for IELTS, TOEFL, Duolingo, or work'; + } + return ''; + } void _pop(OnboardingViewModel viewModel) { viewModel.resetLanguageGoalFormScreen(); @@ -22,6 +49,7 @@ class LanguageGoalFormScreen extends ViewModelWidget { Map data = { 'language_goal': viewModel.selectedLanguageGoal?.code, + }; viewModel.addUserData(data); @@ -44,7 +72,6 @@ class LanguageGoalFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -77,13 +104,10 @@ class LanguageGoalFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ + verticalSpaceLarge, + _buildTitle(viewModel), verticalSpaceMedium, - _buildTitle(), - verticalSpaceSmall, - _buildSubtitle(), - verticalSpaceMedium, - _buildReasons(viewModel), - verticalSpaceMedium, + _buildLanguageGoals(viewModel) ]; Widget _buildAppBar(OnboardingViewModel viewModel) => LargeAppBar( @@ -96,23 +120,27 @@ class LanguageGoalFormScreen extends ViewModelWidget { : viewModel.selectedLanguage['code'], ); - Widget _buildTitle() => Text( - LocaleKeys.language_goal.tr(), - style: style25DG600, + Widget _buildTitle(OnboardingViewModel viewModel) => Text.rich( + TextSpan( + text: + '${LocaleKeys.hello.tr()} ${viewModel.userData['first_name']},', + style: style18P600.copyWith(fontSize: 22), + children: [ + TextSpan( + text: ' ${LocaleKeys.language_goal.tr()}', + style: style16DG600.copyWith(fontSize: 22), + ) + ]), ); - Widget _buildSubtitle() => Text( - LocaleKeys.your_goal.tr(), - style: style14MG400, - ); - - Widget _buildReasons(OnboardingViewModel viewModel) => ListView.builder( + Widget _buildLanguageGoals(OnboardingViewModel viewModel) => ListView.builder( shrinkWrap: true, - padding: EdgeInsets.zero, - itemCount: viewModel.languageGoals.length, + itemCount: viewModel.languageGoals.length, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) => _buildLanguageGoal( - title: viewModel.languageGoals[index].label ?? '', + icon: getIcon(index), + subtitle: getSubtitle(index), + title:viewModel.languageGoals[index].label ?? '', selected: viewModel.isSelectedLanguageGoal(viewModel.languageGoals[index]), onTap: () => @@ -123,10 +151,14 @@ class LanguageGoalFormScreen extends ViewModelWidget { Widget _buildLanguageGoal( {required String title, required bool selected, + required IconData icon, + required String subtitle, required GestureTapCallback onTap}) => - CustomSmallRadioButton( + CustomLargeRadioButton( + icon: icon, title: title, onTap: onTap, + subtitle: subtitle, selected: selected, ); @@ -137,14 +169,15 @@ class LanguageGoalFormScreen extends ViewModelWidget { Widget _buildContinueButton(OnboardingViewModel viewModel) => CustomElevatedButton( - height: 55, - borderRadius: 12, - foregroundColor: kcWhite, - text: LocaleKeys.cont.tr(), - onTap: viewModel.selectedLanguageGoal != null - ? () => _next(viewModel) - : null, - backgroundColor: viewModel.selectedLanguageGoal != null - ? kcPrimaryColor - : kcPrimaryColor.withOpacity(0.1)); + height: 55, + borderRadius: 12, + foregroundColor: kcWhite, + text: LocaleKeys.cont.tr(), + onTap: viewModel.selectedLanguageGoal != null + ? () => _next(viewModel) + : null, + backgroundColor: viewModel.selectedLanguageGoal != null + ? kcPrimaryColor + : kcPrimaryColor.withOpacity(0.1), + ); } diff --git a/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart b/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart index 6bbd51a..361ebe7 100644 --- a/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart +++ b/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart @@ -1,54 +1,17 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; -import 'package:iconsax/iconsax.dart'; import 'package:stacked/stacked.dart'; 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/ui_helpers.dart'; import 'package:yimaru_app/ui/widgets/custom_elevated_button.dart'; import 'package:yimaru_app/ui/views/onboarding/onboarding_viewmodel.dart'; -import 'package:yimaru_app/ui/widgets/custom_large_radio_button.dart'; +import 'package:yimaru_app/ui/widgets/custom_small_radio_button.dart'; import 'package:yimaru_app/ui/widgets/large_app_bar.dart'; class LearningGoalFormScreen extends ViewModelWidget { const LearningGoalFormScreen({super.key}); - IconData getIcon(int index) { - switch (index) { - case 0: - return Iconsax.book; - case 1: - return Iconsax.microphone; - case 2: - return Iconsax.bag; - } - return Icons.book; - } - - String getTitles(int index) { - switch (index) { - case 0: - return 'Learn to Speak English'; - case 1: - return 'Practice Speaking English'; - case 2: - return 'Skill-based Courses'; - } - return ''; - } - - String getSubtitle(int index) { - switch (index) { - case 0: - return 'I know some English, but i want to learn to speak it'; - case 1: - return 'I already speak English, but I want more practice.'; - case 2: - return 'I want courses for IELTS, TOEFL, Duolingo, or work'; - } - return ''; - } - void _pop(OnboardingViewModel viewModel) { viewModel.resetLearningGoalFormScreen(); viewModel.goBack(); @@ -81,7 +44,6 @@ class LearningGoalFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -114,10 +76,13 @@ class LearningGoalFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ + verticalSpaceLarge, + _buildTitle(), + verticalSpaceSmall, + _buildSubtitle(), verticalSpaceMedium, - _buildTitle(viewModel), + _buildGoals(viewModel), verticalSpaceMedium, - _buildLearningGoals(viewModel) ]; Widget _buildAppBar(OnboardingViewModel viewModel) => LargeAppBar( @@ -130,27 +95,23 @@ class LearningGoalFormScreen extends ViewModelWidget { : viewModel.selectedLanguage['code'], ); - Widget _buildTitle(OnboardingViewModel viewModel) => Text.rich( - TextSpan( - text: - '${LocaleKeys.hello.tr()} ${viewModel.userData['first_name']},', - style: style18P600.copyWith(fontSize: 22), - children: [ - TextSpan( - text: ' ${LocaleKeys.learning_goal.tr()}', - style: style16DG600.copyWith(fontSize: 22), - ) - ]), + Widget _buildTitle() => Text( + LocaleKeys.learning_goal.tr(), + style: style25DG600, ); - Widget _buildLearningGoals(OnboardingViewModel viewModel) => ListView.builder( + Widget _buildSubtitle() => Text( + LocaleKeys.your_goal.tr(), + style: style14MG400, + ); + + Widget _buildGoals(OnboardingViewModel viewModel) => ListView.builder( shrinkWrap: true, - itemCount: 3, // viewModel.learningGoals.length, + padding: EdgeInsets.zero, + itemCount: viewModel.learningGoals.length, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) => _buildLearningGoal( - icon: getIcon(index), - title: getTitles(index), - subtitle: getSubtitle(index), + title: viewModel.learningGoals[index].label ?? '', selected: viewModel.isSelectedLearningGoal(viewModel.learningGoals[index]), onTap: () => @@ -161,14 +122,10 @@ class LearningGoalFormScreen extends ViewModelWidget { Widget _buildLearningGoal( {required String title, required bool selected, - required IconData icon, - required String subtitle, required GestureTapCallback onTap}) => - CustomLargeRadioButton( - icon: icon, + CustomSmallRadioButton( title: title, onTap: onTap, - subtitle: subtitle, selected: selected, ); @@ -179,15 +136,14 @@ class LearningGoalFormScreen extends ViewModelWidget { Widget _buildContinueButton(OnboardingViewModel viewModel) => CustomElevatedButton( - height: 55, - borderRadius: 12, - foregroundColor: kcWhite, - text: LocaleKeys.cont.tr(), - onTap: viewModel.selectedLearningGoal != null - ? () => _next(viewModel) - : null, - backgroundColor: viewModel.selectedLearningGoal != null - ? kcPrimaryColor - : kcPrimaryColor.withOpacity(0.1), - ); + height: 55, + borderRadius: 12, + foregroundColor: kcWhite, + text: LocaleKeys.cont.tr(), + onTap: viewModel.selectedLearningGoal != null + ? () => _next(viewModel) + : null, + backgroundColor: viewModel.selectedLearningGoal != null + ? kcPrimaryColor + : kcPrimaryColor.withOpacity(0.1)); } diff --git a/lib/ui/views/onboarding/screens/occupation_form_screen.dart b/lib/ui/views/onboarding/screens/occupation_form_screen.dart index 731d8cc..dae2b6b 100644 --- a/lib/ui/views/onboarding/screens/occupation_form_screen.dart +++ b/lib/ui/views/onboarding/screens/occupation_form_screen.dart @@ -45,7 +45,6 @@ class OccupationFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -78,7 +77,7 @@ class OccupationFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/views/onboarding/screens/topic_form_screen.dart b/lib/ui/views/onboarding/screens/topic_form_screen.dart index 9d46a25..1be06ff 100644 --- a/lib/ui/views/onboarding/screens/topic_form_screen.dart +++ b/lib/ui/views/onboarding/screens/topic_form_screen.dart @@ -47,7 +47,6 @@ class TopicFormScreen extends ViewModelWidget { List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ _buildAppBar(viewModel), - verticalSpaceMedium, _buildExpandedBody(viewModel) ]; @@ -90,7 +89,7 @@ class TopicFormScreen extends ViewModelWidget { ); List _buildUpperColumnChildren(OnboardingViewModel viewModel) => [ - verticalSpaceMedium, + verticalSpaceLarge, _buildTitle(), verticalSpaceSmall, _buildSubtitle(), diff --git a/lib/ui/widgets/course_module_tile_large.dart b/lib/ui/widgets/course_module_tile_large.dart index a8c0c2f..dda641d 100644 --- a/lib/ui/widgets/course_module_tile_large.dart +++ b/lib/ui/widgets/course_module_tile_large.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:stacked/stacked.dart'; import 'package:yimaru_app/models/course_lesson.dart'; import 'package:yimaru_app/models/course_module.dart'; +import 'package:yimaru_app/ui/common/enmus.dart'; import 'package:yimaru_app/ui/views/course_module/course_module_viewmodel.dart'; import 'package:yimaru_app/ui/widgets/course_lesson_tile.dart'; import 'package:yimaru_app/ui/widgets/custom_linear_progress_indicator.dart'; @@ -182,6 +183,7 @@ class CourseModuleTileLarge extends ViewModelWidget { Widget _buildSheet(CourseModuleViewModel viewModel) => FinishPracticeSheet( onTap: viewModel.pop, + practice: PracticeReason.lesson, ); Widget _buildCourseModules(CourseModuleViewModel viewModel) => diff --git a/lib/ui/widgets/course_unit_tile.dart b/lib/ui/widgets/course_unit_tile.dart index 70877d0..a084d7e 100644 --- a/lib/ui/widgets/course_unit_tile.dart +++ b/lib/ui/widgets/course_unit_tile.dart @@ -8,6 +8,7 @@ import 'package:yimaru_app/ui/widgets/finish_practice_sheet.dart'; import '../../models/course_catalog.dart'; import '../common/app_colors.dart'; +import '../common/enmus.dart'; import '../common/ui_helpers.dart'; import '../views/course_unit/course_unit_viewmodel.dart'; import 'custom_circular_progress_indicator.dart'; @@ -228,6 +229,7 @@ class CourseUnitTile extends ViewModelWidget { Widget _buildSheet(CourseUnitViewModel viewModel) => FinishPracticeSheet( onTap: viewModel.pop, + practice: PracticeReason.course, ); Widget _buildCourseModulesState(CourseUnitViewModel viewModel) => @@ -240,6 +242,7 @@ class CourseUnitTile extends ViewModelWidget { width: double.maxFinite, child: _buildProgressIndicator(), ); + Widget _buildProgressIndicator() => const Center( child: CustomCircularProgressIndicator(color: kcPrimaryColor), ); diff --git a/lib/ui/widgets/finish_practice_sheet.dart b/lib/ui/widgets/finish_practice_sheet.dart index 075f9a8..678d8a6 100644 --- a/lib/ui/widgets/finish_practice_sheet.dart +++ b/lib/ui/widgets/finish_practice_sheet.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:yimaru_app/ui/common/app_colors.dart'; +import 'package:yimaru_app/ui/common/enmus.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/widgets/custom_bottom_sheet.dart'; @@ -9,9 +10,24 @@ import 'package:yimaru_app/ui/widgets/custom_bottom_sheet.dart'; import 'custom_elevated_button.dart'; class FinishPracticeSheet extends StatelessWidget { + final PracticeReason practice; final GestureTapCallback? onTap; - const FinishPracticeSheet({super.key, this.onTap}); + const FinishPracticeSheet({super.key, this.onTap, required this.practice}); + + String getWarning() { + if (practice == PracticeReason.lesson) { + return LocaleKeys.finish_all_practice_lesson.tr(); + } else if (practice == PracticeReason.module) { + return LocaleKeys.finish_all_practice_module.tr(); + } else if (practice == PracticeReason.previousModule) { + return LocaleKeys.finish_all_practice_previouse_module.tr(); + } else if (practice == PracticeReason.previousCourse) { + return LocaleKeys.finish_all_practice_previouse_course.tr(); + } else { + return LocaleKeys.finish_all_practice_course.tr(); + } + } @override Widget build(BuildContext context) => _buildSheetWrapper(); @@ -44,7 +60,7 @@ class FinishPracticeSheet extends StatelessWidget { ); Widget _buildMessage() => Text( - LocaleKeys.finish_all_practice.tr(), + getWarning(), style: style16DG600, textAlign: TextAlign.center, ); diff --git a/lib/ui/widgets/learn_course_tile.dart b/lib/ui/widgets/learn_course_tile.dart index 39f8397..0fb0cad 100644 --- a/lib/ui/widgets/learn_course_tile.dart +++ b/lib/ui/widgets/learn_course_tile.dart @@ -24,7 +24,13 @@ class LearnCourseTile extends ViewModelWidget { @override Widget build(BuildContext context, LearnCourseViewModel viewModel) => - _buildExpansionTileCard(viewModel); + _buildExpansionTileCardWrapper(viewModel); + + + Widget _buildExpansionTileCardWrapper(LearnCourseViewModel viewModel)=> GestureDetector( + onTap: !(course.access?.isAccessible ?? false) ? onPracticeTap:null, + child: _buildExpansionTileCard(viewModel), + ); Widget _buildExpansionTileCard(LearnCourseViewModel viewModel) => Container( margin: const EdgeInsets.only(bottom: 15), diff --git a/lib/ui/widgets/learn_lesson_tile.dart b/lib/ui/widgets/learn_lesson_tile.dart index 92f21bc..891c420 100644 --- a/lib/ui/widgets/learn_lesson_tile.dart +++ b/lib/ui/widgets/learn_lesson_tile.dart @@ -16,6 +16,7 @@ import 'custom_linear_progress_indicator.dart'; class LearnLessonTile extends ViewModelWidget { final int index; + final bool last; final LearnLesson lesson; final GestureTapCallback? onLessonTap; final GestureTapCallback? onPracticeTap; @@ -24,6 +25,7 @@ class LearnLessonTile extends ViewModelWidget { {super.key, this.onLessonTap, this.onPracticeTap, + required this.last, required this.index, required this.lesson}); @@ -31,10 +33,12 @@ class LearnLessonTile extends ViewModelWidget { Widget build(BuildContext context, LearnLessonViewModel viewModel) => _buildContainerWrapper(viewModel); - Widget _buildContainerWrapper(LearnLessonViewModel viewModel)=> GestureDetector( - onTap: !(lesson.access?.isAccessible ?? false) ? onPracticeTap:null, - child: _buildContainer(viewModel), - ); + Widget _buildContainerWrapper(LearnLessonViewModel viewModel) => + GestureDetector( + onTap: !(lesson.access?.isAccessible ?? false) ? onPracticeTap : null, + child: _buildContainer(viewModel), + ); + Widget _buildContainer(LearnLessonViewModel viewModel) => Container( width: double.maxFinite, margin: const EdgeInsets.only(bottom: 15), @@ -70,12 +74,14 @@ class LearnLessonTile extends ViewModelWidget { controlAffinity: ListTileControlAffinity.trailing, expandedCrossAxisAlignment: CrossAxisAlignment.start, tilePadding: const EdgeInsets.fromLTRB(15, 15, 15, 15), - backgroundColor: (lesson.access?.isCompleted ?? false) - ? kcGreen.withOpacity(0.1) - : kcPrimaryColor.withOpacity(0.1), childrenPadding: const EdgeInsets.fromLTRB(15, 0, 15, 15), initiallyExpanded: (lesson.access?.isAccessible ?? false) && !(lesson.access?.isCompleted ?? false), + backgroundColor: last && (lesson.access?.isAccessible ?? false) + ? kcGreen.withOpacity(0.1) + : (lesson.access?.isCompleted ?? false) + ? kcGreen.withOpacity(0.1) + : kcPrimaryColor.withOpacity(0.1), collapsedBackgroundColor: (lesson.access?.isCompleted ?? false) ? kcGreen.withOpacity(0.1) : kcPrimaryColor.withOpacity(0.1), @@ -92,9 +98,11 @@ class LearnLessonTile extends ViewModelWidget { style: style16DG600, ); - Widget _buildIconState() => (lesson.access?.isCompleted ?? false) + Widget _buildIconState() => last && (lesson.access?.isAccessible ?? false) ? _buildCompleteIcon() - : _buildPendingIcon(); + : (lesson.access?.isCompleted ?? false) + ? _buildCompleteIcon() + : _buildPendingIcon(); Widget _buildCompleteIcon() => const Icon( Icons.check, @@ -128,13 +136,17 @@ class LearnLessonTile extends ViewModelWidget { Widget _buildProgress() => CustomLinearProgressIndicator( activeColor: kcPrimaryColor, backgroundColor: kcVeryLightGrey, - progress: (lesson.access?.progressPercent ?? 0) / 100, + progress: last && (lesson.access?.isAccessible ?? false) + ? 1 + : (lesson.access?.progressPercent ?? 0) / 100, ); Widget _buildProgressText() => Text( - (lesson.access?.isCompleted ?? false) + last && (lesson.access?.isAccessible ?? false) ? LocaleKeys.completed.tr() - : LocaleKeys.in_progress.tr(), + : (lesson.access?.isCompleted ?? false) + ? LocaleKeys.completed.tr() + : LocaleKeys.in_progress.tr(), style: style14P600, ); diff --git a/lib/ui/widgets/learn_module_tile.dart b/lib/ui/widgets/learn_module_tile.dart index f7f9f3a..4fd08ff 100644 --- a/lib/ui/widgets/learn_module_tile.dart +++ b/lib/ui/widgets/learn_module_tile.dart @@ -23,8 +23,13 @@ class LearnModuleTile extends ViewModelWidget { @override Widget build(BuildContext context, LearnModuleViewModel viewModel) => - _buildExpansionTileCard(context: context, viewModel: viewModel); + _buildExpansionTileCardWrapper(context: context, viewModel: viewModel); + Widget _buildExpansionTileCardWrapper( {required BuildContext context, + required LearnModuleViewModel viewModel})=> GestureDetector( + onTap: !(module.access?.isAccessible ?? false) ? onPracticeTap:null, + child: _buildExpansionTileCard(context: context,viewModel: viewModel), + ); Widget _buildExpansionTileCard( {required BuildContext context, required LearnModuleViewModel viewModel}) => diff --git a/pubspec.yaml b/pubspec.yaml index 6703bc3..fb1600d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: yimaru_app -version: 0.1.28+30 +version: 0.1.29+31 publish_to: 'none' description: A new Flutter project. From b1e048e6376873fd682e1415f1bd5a6c08179e16 Mon Sep 17 00:00:00 2001 From: BisratHailu Date: Sat, 30 May 2026 00:02:11 +0300 Subject: [PATCH 2/2] feat(Payment): Add chapa as payment gateway for learn subscription --- lib/app/app.dart | 4 +- lib/app/app.router.dart | 208 ++--- lib/ui/common/app_constants.dart | 4 +- lib/ui/common/enmus.dart | 2 - .../common/translations/codegen_loader.g.dart | 797 +++++++++--------- lib/ui/common/translations/locale_keys.g.dart | 12 +- .../screens/assessment_result_screen.dart | 6 +- .../screens/start_lesson_screen.dart | 6 +- .../screens/reset_password_screen.dart | 6 +- .../views/learn_lesson/learn_lesson_view.dart | 8 +- .../learn_lesson/learn_lesson_viewmodel.dart | 11 +- .../learn_lesson_detail_view.dart | 5 +- .../views/learn_module/learn_module_view.dart | 2 +- .../learn_subscription_viewmodel.dart | 24 +- .../learn_subscription_form_screen.dart | 5 +- .../screens/age_group_form_screen.dart | 6 +- .../screens/challenge_form_screen.dart | 6 +- .../screens/country_region_form_screen.dart | 6 +- .../educational_background_form_screen.dart | 6 +- .../screens/full_name_form_screen.dart | 6 +- .../screens/gender_form_screen.dart | 6 +- .../screens/language_goal_form_screen.dart | 13 +- .../screens/learning_goal_form_screen.dart | 6 +- .../screens/occupation_form_screen.dart | 6 +- .../onboarding/screens/topic_form_screen.dart | 6 +- .../payment_view.dart} | 40 +- .../payment_viewmodel.dart} | 17 +- lib/ui/widgets/course_module_tile_large.dart | 2 +- lib/ui/widgets/learn_course_tile.dart | 10 +- lib/ui/widgets/learn_module_tile.dart | 12 +- pubspec.yaml | 2 +- ..._test.dart => payment_viewmodel_test.dart} | 2 +- 32 files changed, 638 insertions(+), 614 deletions(-) rename lib/ui/views/{arif_pay/arif_pay_view.dart => payment/payment_view.dart} (51%) rename lib/ui/views/{arif_pay/arif_pay_viewmodel.dart => payment/payment_viewmodel.dart} (80%) rename test/viewmodels/{arif_pay_viewmodel_test.dart => payment_viewmodel_test.dart} (85%) diff --git a/lib/app/app.dart b/lib/app/app.dart index 1838082..b50252d 100644 --- a/lib/app/app.dart +++ b/lib/app/app.dart @@ -49,7 +49,6 @@ import 'package:yimaru_app/services/vimeo_service.dart'; import 'package:yimaru_app/services/url_launcher_service.dart'; import 'package:yimaru_app/services/phone_caller_service.dart'; import 'package:yimaru_app/ui/views/learn_subscription/learn_subscription_view.dart'; -import 'package:yimaru_app/ui/views/arif_pay/arif_pay_view.dart'; import 'package:yimaru_app/services/learn_service.dart'; import 'package:yimaru_app/ui/views/course_catalog/course_catalog_view.dart'; import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart'; @@ -58,6 +57,7 @@ import 'package:yimaru_app/ui/views/landing/landing_view.dart'; import 'package:yimaru_app/ui/views/course_module/course_module_view.dart'; import 'package:yimaru_app/services/onboarding_service.dart'; import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart'; +import 'package:yimaru_app/ui/views/payment/payment_view.dart'; // @stacked-import @StackedApp( @@ -91,12 +91,12 @@ import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart'; MaterialRoute(page: LearnProgramView), MaterialRoute(page: AssessmentView), MaterialRoute(page: LearnSubscriptionView), - MaterialRoute(page: ArifPayView), MaterialRoute(page: CourseCatalogView), MaterialRoute(page: CourseUnitView), MaterialRoute(page: LandingView), MaterialRoute(page: CourseModuleView), MaterialRoute(page: LearnCourseView), + MaterialRoute(page: PaymentView), // @stacked-route ], dependencies: [ diff --git a/lib/app/app.router.dart b/lib/app/app.router.dart index 90e8e84..7fcdcb3 100644 --- a/lib/app/app.router.dart +++ b/lib/app/app.router.dart @@ -9,7 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/material.dart' as _i37; import 'package:stacked/stacked.dart' as _i1; -import 'package:stacked_services/stacked_services.dart' as _i46; +import 'package:stacked_services/stacked_services.dart' as _i47; import 'package:yimaru_app/models/course.dart' as _i42; import 'package:yimaru_app/models/course_catalog.dart' as _i44; import 'package:yimaru_app/models/course_lesson.dart' as _i43; @@ -17,33 +17,33 @@ import 'package:yimaru_app/models/course_module.dart' as _i45; import 'package:yimaru_app/models/learn_course.dart' as _i38; import 'package:yimaru_app/models/learn_lesson.dart' as _i40; import 'package:yimaru_app/models/learn_module.dart' as _i39; +import 'package:yimaru_app/models/learn_subscription.dart' as _i46; import 'package:yimaru_app/ui/common/enmus.dart' as _i41; import 'package:yimaru_app/ui/views/account_privacy/account_privacy_view.dart' as _i9; -import 'package:yimaru_app/ui/views/arif_pay/arif_pay_view.dart' as _i31; import 'package:yimaru_app/ui/views/assessment/assessment_view.dart' as _i29; import 'package:yimaru_app/ui/views/call_support/call_support_view.dart' as _i12; import 'package:yimaru_app/ui/views/course/course_view.dart' as _i27; import 'package:yimaru_app/ui/views/course_catalog/course_catalog_view.dart' - as _i32; + as _i31; import 'package:yimaru_app/ui/views/course_lesson_detail/course_lesson_detail_view.dart' as _i25; import 'package:yimaru_app/ui/views/course_module/course_module_view.dart' - as _i35; + as _i34; import 'package:yimaru_app/ui/views/course_payment/course_payment_view.dart' as _i23; -import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart' as _i33; +import 'package:yimaru_app/ui/views/course_unit/course_unit_view.dart' as _i32; import 'package:yimaru_app/ui/views/downloads/downloads_view.dart' as _i7; import 'package:yimaru_app/ui/views/duolingo/duolingo_view.dart' as _i26; import 'package:yimaru_app/ui/views/failure/failure_view.dart' as _i24; import 'package:yimaru_app/ui/views/forget_password/forget_password_view.dart' as _i20; import 'package:yimaru_app/ui/views/home/home_view.dart' as _i2; -import 'package:yimaru_app/ui/views/landing/landing_view.dart' as _i34; +import 'package:yimaru_app/ui/views/landing/landing_view.dart' as _i33; import 'package:yimaru_app/ui/views/language/language_view.dart' as _i13; import 'package:yimaru_app/ui/views/learn_course/learn_course_view.dart' - as _i36; + as _i35; import 'package:yimaru_app/ui/views/learn_lesson/learn_lesson_view.dart' as _i19; import 'package:yimaru_app/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart' @@ -58,6 +58,7 @@ import 'package:yimaru_app/ui/views/learn_subscription/learn_subscription_view.d as _i30; import 'package:yimaru_app/ui/views/login/login_view.dart' as _i17; import 'package:yimaru_app/ui/views/onboarding/onboarding_view.dart' as _i3; +import 'package:yimaru_app/ui/views/payment/payment_view.dart' as _i36; import 'package:yimaru_app/ui/views/privacy_policy/privacy_policy_view.dart' as _i14; import 'package:yimaru_app/ui/views/profile/profile_view.dart' as _i5; @@ -131,8 +132,6 @@ class Routes { static const learnSubscriptionView = '/learn-subscription-view'; - static const arifPayView = '/arif-pay-view'; - static const courseCatalogView = '/course-catalog-view'; static const courseUnitView = '/course-unit-view'; @@ -143,6 +142,8 @@ class Routes { static const learnCourseView = '/learn-course-view'; + static const paymentView = '/payment-view'; + static const all = { homeView, onboardingView, @@ -173,12 +174,12 @@ class Routes { learnProgramView, assessmentView, learnSubscriptionView, - arifPayView, courseCatalogView, courseUnitView, landingView, courseModuleView, learnCourseView, + paymentView, }; } @@ -300,29 +301,29 @@ class StackedRouter extends _i1.RouterBase { Routes.learnSubscriptionView, page: _i30.LearnSubscriptionView, ), - _i1.RouteDef( - Routes.arifPayView, - page: _i31.ArifPayView, - ), _i1.RouteDef( Routes.courseCatalogView, - page: _i32.CourseCatalogView, + page: _i31.CourseCatalogView, ), _i1.RouteDef( Routes.courseUnitView, - page: _i33.CourseUnitView, + page: _i32.CourseUnitView, ), _i1.RouteDef( Routes.landingView, - page: _i34.LandingView, + page: _i33.LandingView, ), _i1.RouteDef( Routes.courseModuleView, - page: _i35.CourseModuleView, + page: _i34.CourseModuleView, ), _i1.RouteDef( Routes.learnCourseView, - page: _i36.LearnCourseView, + page: _i35.LearnCourseView, + ), + _i1.RouteDef( + Routes.paymentView, + page: _i36.PaymentView, ), ]; @@ -590,52 +591,52 @@ class StackedRouter extends _i1.RouterBase { settings: data, ); }, - _i31.ArifPayView: (data) { - final args = data.getArgs(nullOk: false); - return _i37.MaterialPageRoute( - builder: (context) => - _i31.ArifPayView(key: args.key, phone: args.phone), - settings: data, - ); - }, - _i32.CourseCatalogView: (data) { + _i31.CourseCatalogView: (data) { final args = data.getArgs( orElse: () => const CourseCatalogViewArguments(), ); return _i37.MaterialPageRoute( - builder: (context) => _i32.CourseCatalogView(key: args.key), + builder: (context) => _i31.CourseCatalogView(key: args.key), settings: data, ); }, - _i33.CourseUnitView: (data) { + _i32.CourseUnitView: (data) { final args = data.getArgs(nullOk: false); return _i37.MaterialPageRoute( builder: (context) => - _i33.CourseUnitView(key: args.key, catalog: args.catalog), + _i32.CourseUnitView(key: args.key, catalog: args.catalog), settings: data, ); }, - _i34.LandingView: (data) { + _i33.LandingView: (data) { final args = data.getArgs( orElse: () => const LandingViewArguments(), ); return _i37.MaterialPageRoute( - builder: (context) => _i34.LandingView(key: args.key), + builder: (context) => _i33.LandingView(key: args.key), settings: data, ); }, - _i35.CourseModuleView: (data) { + _i34.CourseModuleView: (data) { final args = data.getArgs(nullOk: false); return _i37.MaterialPageRoute( - builder: (context) => _i35.CourseModuleView( + builder: (context) => _i34.CourseModuleView( key: args.key, module: args.module, catalog: args.catalog), settings: data, ); }, - _i36.LearnCourseView: (data) { + _i35.LearnCourseView: (data) { final args = data.getArgs(nullOk: false); return _i37.MaterialPageRoute( - builder: (context) => _i36.LearnCourseView(key: args.key, id: args.id), + builder: (context) => _i35.LearnCourseView(key: args.key, id: args.id), + settings: data, + ); + }, + _i36.PaymentView: (data) { + final args = data.getArgs(nullOk: false); + return _i37.MaterialPageRoute( + builder: (context) => _i36.PaymentView( + key: args.key, phone: args.phone, subscription: args.subscription), settings: data, ); }, @@ -1378,33 +1379,6 @@ class LearnSubscriptionViewArguments { } } -class ArifPayViewArguments { - const ArifPayViewArguments({ - this.key, - required this.phone, - }); - - final _i37.Key? key; - - final String phone; - - @override - String toString() { - return '{"key": "$key", "phone": "$phone"}'; - } - - @override - bool operator ==(covariant ArifPayViewArguments other) { - if (identical(this, other)) return true; - return other.key == key && other.phone == phone; - } - - @override - int get hashCode { - return key.hashCode ^ phone.hashCode; - } -} - class CourseCatalogViewArguments { const CourseCatalogViewArguments({this.key}); @@ -1535,7 +1509,39 @@ class LearnCourseViewArguments { } } -extension NavigatorStateExtension on _i46.NavigationService { +class PaymentViewArguments { + const PaymentViewArguments({ + this.key, + required this.phone, + required this.subscription, + }); + + final _i37.Key? key; + + final String phone; + + final _i46.LearnSubscription subscription; + + @override + String toString() { + return '{"key": "$key", "phone": "$phone", "subscription": "$subscription"}'; + } + + @override + bool operator ==(covariant PaymentViewArguments other) { + if (identical(this, other)) return true; + return other.key == key && + other.phone == phone && + other.subscription == subscription; + } + + @override + int get hashCode { + return key.hashCode ^ phone.hashCode ^ subscription.hashCode; + } +} + +extension NavigatorStateExtension on _i47.NavigationService { Future navigateToHomeView({ _i37.Key? key, int? routerId, @@ -2030,23 +2036,6 @@ extension NavigatorStateExtension on _i46.NavigationService { transition: transition); } - Future navigateToArifPayView({ - _i37.Key? key, - required String phone, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return navigateTo(Routes.arifPayView, - arguments: ArifPayViewArguments(key: key, phone: phone), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - Future navigateToCourseCatalogView({ _i37.Key? key, int? routerId, @@ -2132,6 +2121,25 @@ extension NavigatorStateExtension on _i46.NavigationService { transition: transition); } + Future navigateToPaymentView({ + _i37.Key? key, + required String phone, + required _i46.LearnSubscription subscription, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return navigateTo(Routes.paymentView, + arguments: PaymentViewArguments( + key: key, phone: phone, subscription: subscription), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } + Future replaceWithHomeView({ _i37.Key? key, int? routerId, @@ -2626,23 +2634,6 @@ extension NavigatorStateExtension on _i46.NavigationService { transition: transition); } - Future replaceWithArifPayView({ - _i37.Key? key, - required String phone, - int? routerId, - bool preventDuplicates = true, - Map? parameters, - Widget Function(BuildContext, Animation, Animation, Widget)? - transition, - }) async { - return replaceWith(Routes.arifPayView, - arguments: ArifPayViewArguments(key: key, phone: phone), - id: routerId, - preventDuplicates: preventDuplicates, - parameters: parameters, - transition: transition); - } - Future replaceWithCourseCatalogView({ _i37.Key? key, int? routerId, @@ -2727,4 +2718,23 @@ extension NavigatorStateExtension on _i46.NavigationService { parameters: parameters, transition: transition); } + + Future replaceWithPaymentView({ + _i37.Key? key, + required String phone, + required _i46.LearnSubscription subscription, + int? routerId, + bool preventDuplicates = true, + Map? parameters, + Widget Function(BuildContext, Animation, Animation, Widget)? + transition, + }) async { + return replaceWith(Routes.paymentView, + arguments: PaymentViewArguments( + key: key, phone: phone, subscription: subscription), + id: routerId, + preventDuplicates: preventDuplicates, + parameters: parameters, + transition: transition); + } } diff --git a/lib/ui/common/app_constants.dart b/lib/ui/common/app_constants.dart index d376bd3..d03bd02 100644 --- a/lib/ui/common/app_constants.dart +++ b/lib/ui/common/app_constants.dart @@ -122,7 +122,7 @@ String kTelegramSupport = '@yimaruacademy2026'; String kTelegramSupportLink = 'https://t.me/yimaruacademy2026'; -String kErrorUrl = 'https://yimaru.net/api/v1/payments/arifpay/error'; +String kErrorUrl = 'https://yimaru.net/api/v1/payments/chapa/error'; String kSuccessUrl = - 'https://api.yimaruacademy.com/api/v1/payments/arifpay/success'; + 'https://api.yimaruacademy.com/api/v1/payments/chapa/success'; diff --git a/lib/ui/common/enmus.dart b/lib/ui/common/enmus.dart index 0674434..0edfb44 100644 --- a/lib/ui/common/enmus.dart +++ b/lib/ui/common/enmus.dart @@ -25,11 +25,9 @@ enum ProgressStatuses { pending, started, completed } // Duolingo types enum DuolingoAssessments { speaking, reading, writing, listening } - // Practice reason enum PracticeReason { course, module, lesson, previousModule, previousCourse } - // State object enum StateObjects { none, diff --git a/lib/ui/common/translations/codegen_loader.g.dart b/lib/ui/common/translations/codegen_loader.g.dart index 678196c..a1254ed 100644 --- a/lib/ui/common/translations/codegen_loader.g.dart +++ b/lib/ui/common/translations/codegen_loader.g.dart @@ -6,7 +6,7 @@ import 'dart:ui'; import 'package:easy_localization/easy_localization.dart' show AssetLoader; -class CodegenLoader extends AssetLoader{ +class CodegenLoader extends AssetLoader { const CodegenLoader(); @override @@ -14,387 +14,416 @@ class CodegenLoader extends AssetLoader{ return Future.value(mapLocales[locale.toString()]); } - static const Map _am = { - "loading": "በመጫን ላይ", - "welcome_back": "እንኳን በደህና ተመለሱ", - "checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ", - "dont_have_account": "መለያ የለዎትም?", - "email": "ኢሜይል", - "password": "የይለፍ ቃል", - "forgot_password": "የይለፍ ቃል ረሱ?", - "cont": "ቀጥል", - "register": "ይመዝገቡ", - "login_with_google": "በጉግል ይግቡ", - "or": "ወይም", - "login_with_phone": "በስልክ ቁጥር ይግቡ", - "create_account": "አዲስ መለያ ይፍጠሩ", - "already_have_account": "መለያ አለዎት?", - "login": " ይግቡ ", - "register_with_google": "በጉግል ይመዝገቡ", - "register_with_phone": "በስልክ ቁጥር ይመዝገቡ", - "enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።", - "login_with_email": "በኢሜይል ይግቡ", - "create_password": "የይለፍ ቃል ይፍጠሩ", - "confirm_password": "የይለፍ ቃል ያረጋግጡ", - "eight_character_minimum": "ቢያንስ 8 ፊደላት", - "password_match": "የይለፍ ቃሉ ተመሳስሏል", - "sign_up_agreement": "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", - "terms_of_services": "የአገልግሎት ውሎች", - "and": "እና", - "privacy_policy": "የግላዊነት ፖሊሲ", - "register_with_email": "በኢሜል ይመዝገቡ", - "verification_code": "የማረጋገጫ ኮድ", - "resend_code": "ኮዱን እንደገና ላክ", - "code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል", - "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", - "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", - "reset_password": " የይለፍ ቃልን ይቀይሩ", - "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", - "please_wait": "እባክዎ ይጠብቁ", - "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", - "reset_code": " የመቀየሪያ ኮድ ", - "new_password": "አዲስ የይለፍ ቃል", - "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", - "view_course": " ኮርሱን ይመልከቱ", - "continue_learning": "መማርን ይቀጥሉ", - "start_learning": "ትምህርትን ይጀምሩ", - "completed": "ተጠናቋል", - "take_practice": "ልምምድ ያድርጉ", - "your_current_level": "የአሁኑ ደረጃዎ", - "overall_progress": "አጠቃላይ እድገት", - "great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው", - "view_module": "ሞጁሉን ይመልከቱ", - "progress": "እድገት", - "keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ", - "lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ", - "practice": "ልምምድ", - "start": "ጀምር", - "in_progress": "በሂደት ላይ", - "hello": "ሰላም", - "ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ", - "learn": "ይማሩ ", - "course": "ኮርስ", - "profile": " ፕሮፋይል ", - "speaking_partner": "የንግግር ጓደኛ", - "practice_what_you_learned": "አሁን የተማሩትን እንለማመድ", - "practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ", - "start_practice": "ልምምድ ጀምር", - "almost_there": "ሊጨርሱ ተቃርበዋል", - "finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ", - "continue_practice": "ልምምዱን ይቀጥሉ", - "end_session": "ክፍለ ጊዜውን ያብቁ ", - "tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ", - "practice_speaking": "ንግግርን ይለማመዱ", - "tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ", - "reply": "እንደገና አዳምጥ", - "cancel": "ይቅር", - "you_are_speaking": "እየተናገሩ ነው", - "practice_completed": "ልምምዱ ተጠናቅቋል", - "great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው", - "practice_again": "እንደገና ይለማመዱ", - "conversation_review": "የንግግር ግምገማ", - "result": "ውጤት", - "quick_tip": "ጠቃሚ ምክር", - "retry": "እንደገና ይሞክሩ", - "completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል", - "analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው", - "view_profile": "ፕሮፋይሎን ይመልከቱ ", - "hi": "ሰላም", - "edit_profile": "መገለጫ ያስተካክሉ", - "first_name": "የመጀመሪያ ስም", - "last_name": "የአባት ስም", - "gender": "ፆታ", - "male": "ወንድ", - "female": "ሴት", - "phone_number": "የስልክ ቁጥር", - "country": "ሀገር", - "region": "ክልል", - "select_region": "ክልል ይምረጡ", - "enter_your_city": "ከተማዎን ያስገቡ", - "occupation": "የስራ መስክ", - "select_occupation": "ሙያዎን ይምረጡ", - "save_changes": "ለውጦችን ያስቀምጡ", - "my_progress": "የእኔ እድገት", - "track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ", - "account_and_privacy": "መለያ እና ግላዊነት", - "manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ", - "support": "ድጋፍ", - "get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ", - "logout": "ውጣ", - "app_settings": "የመተግበሪያ ቅንብሮች", - "legal_and_information": "ሕጋዊ እና መረጃ", - "change_language": "ቋንቋ ቀይር", - "terms_and_conditions": "ውሎች እና ሁኔታዎች", - "delete_account": "መለያ ሰርዝ", - "language_preference": "የቋንቋ ምርጫ", - "choose_your_language": "ለውጦችን አስቀምጥ", - "switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ", - "need_help": "እገዛ ይፈልጋሉ?", - "call_support": "የስልክ ድጋፍ", - "talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ", - "telegram_support": "የቴሌግራም ድጋፍ", - "chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ", - "call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ", - "tap_to_call": "ለመደወል ይንኩ", - "join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ", - "connect_with_support_team": "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።", - "open_in_telegram": "በቴሌግራም ይክፈቱ", - "search_for": "ፈልጉት", - "current_level": "የአሁኑ ደረጃ", - "keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።", - "no_practice_available": "ምንም ልምምድ አልተገኘም!", - "begin_module_practice": "የሞጁሉን ልምምድ ጀምር", - "lets_practice_lesson": "እንለማመድ", - "lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!", - "lets_practice_module": "አሁን የተማርከውን እንለማመድ!", - "ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።", - "begin_level_practice": "የደረጃ ልምምድን ጀምር", - "lets_practice_course": "የኮርሱን ልምምድ እንለማመድ", - "lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!", - "speaking": "እየተናገረ ነው", - "you_have_finished_practice": "ልምምድህን አጠናቀቅህ", - "view_results": "ውጤቶቼን እይ", - "sample_answer": "ናሙና መልስ", - "your_answer": "መልስህ", - "sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!", - "you_have_completed": "አያይ! አጠናቀቅህ", - "yes": "አዎ", - "no": "አይ", - "want_to_quit": "ለመውጣት እርግጠኛ ነህ?", - "required_field": "ይህ መስክ ያስፈልጋል", - "enter_full_name": "ሙሉ ስምህን አስገባ", - "invalid_email": "የማይሰራ የኢሜይል ቅርጸት", - "phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት", - "phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት", - "what_should_we_call_you": "ምን ብለን እንጠራህ?", - "name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።", - "choose_your_gender": "ጾታህን ምረጥ", - "gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?", - "age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?", - "education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።", - "your_occupation": "ስራህ ምንድን ነው?", - "occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", - "location": "ከየት ነህ?", - "select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ", - "select_country": "አገር ምረጥ", - "learning_goal": "የመማር ዓላማህን ምረጥ", - "language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?", - "your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።", - "write_your_goal": "ዓላማህን ጻፍ…", - "challenge_you_face": "What challenge do you face most with English?", - "evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ", - "write_your_challenge": "ችግርህን ጻፍ…", - "topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?", - "favourite_topic": "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።", - "your_interest": "ፍላጎትህን ጻፍ…", - "want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?", - "answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።", - "skip": "ዝለል", - "finish_level": "ደረጃውን አጠናቅቅ", - "likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ", - "great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።", - "lets_start_practice": "ልምምድህን እንጀምር", - "welcome_abroad": "እንኳን ደህና መጣህ", - "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", - "finish": "አጠናቅቅ", - "finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ", - "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", - "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", - "finish_all_practice_previouse_module": "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", - "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ" -}; -static const Map _en = { - "loading": "Loading", - "welcome_back": "Welcome back", - "checking_user_info": "Checking user info", - "dont_have_account": "Don't have an account?", - "email": "Email", - "password": "Password", - "forgot_password": "Forgot password?", - "cont": "Continue", - "register": "Register", - "login_with_google": "Login with Google", - "or": "Or", - "login_with_phone": "Login with phone number", - "create_account": "Create an account", - "already_have_account": "Already have an account?", - "login": "Login", - "register_with_google": "Register with Google", - "register_with_phone": "Register with phone number", - "enter_phone_number": "Enter your phone number. We will send you a confirmation code there.", - "login_with_email": "Login with email", - "create_password": "Create password", - "confirm_password": "Confirm password", - "eight_character_minimum": "8 characters minimum", - "password_match": "password match", - "sign_up_agreement": "By clicking ‘Sign Up’, you agree to our ‘Terms of Service’ and ‘Privacy Policy’", - "terms_of_services": "Terms of Service", - "and": "and", - "privacy_policy": "Privacy Policy", - "register_with_email": "Register with email", - "verification_code": "Verification Code", - "resend_code": "Resend Code", - "code_sent_to_phone": "Code sent to your number", - "code_sent_to_email": "Code sent to your email", - "resend_code_in": "Resend code in", - "reset_password": "Reset Password", - "enter_email_reset_code": "Enter your email. We will send you a reset code.", - "please_wait": "Please wait", - "reset_code_sent": "Reset code sent successfully", - "reset_code": "Reset code", - "new_password": "New password", - "logged_in_successfully": "Logged in successfully", - "continue_learning": "Continue Learning", - "start_learning": "Start Learning", - "completed": "Completed", - "view_course": "View course", - "take_practice": "Take practice", - "your_current_level": "Your current level", - "overall_progress": "Overall progress", - "great_work": "Keep up the great work! You're doing amazing", - "view_module": "View module", - "progress": "Progress", - "keep_going": "Let's keep going - you're more than half there", - "lessons_in_module": "Lessons in this module", - "practice": "Practice", - "start": "Start", - "in_progress": "In Progress", - "hello": "Hello", - "ready_to_learn": "Ready to keep learning English today", - "learn": "Learn", - "course": "Course", - "profile": "Profile", - "speaking_partner": "Speaking partner", - "practice_what_you_learned": "Let's practice what you just learnt", - "practice_questions": "I will ask you a few questions and you can respond", - "start_practice": "Start practice", - "almost_there": "You're almost there", - "finish_session": "Finish the session to see your progress", - "continue_practice": "Continue practice", - "end_session": "End session", - "tap_start_to_listen": "Tap the start button to listen", - "practice_speaking": "Practice speaking", - "tap_microphone": "Tap the microphone to speak", - "reply": "Reply", - "cancel": "Cancel", - "you_are_speaking": "You're speaking", - "practice_completed": "Practice completed!", - "great_improvement": "You sound more confident this time, great improvement", - "practice_again": "Practice again", - "conversation_review": "Conversation review", - "result": "Result", - "quick_tip": "Quick tip", - "retry": "Retry", - "completed_a1": "Yay, you've completed A1", - "analyzing_speaking": "We're now analyzing your speaking skill", - "view_profile": "View profile", - "hi": "Hi", - "edit_profile": "Edit profile", - "first_name": "First name", - "last_name": "Last name", - "gender": "Gender", - "male": "Male", - "female": "Female", - "phone_number": "Phone number", - "country": "Country", - "region": "Region", - "select_region": "Select region", - "enter_your_city": "Enter your city", - "occupation": "Occupation", - "select_occupation": "Select occupation", - "save_changes": "Save changes", - "my_progress": "My progress", - "track_your_achievement": "Track your achievements and learning streak", - "account_and_privacy": "Account & Privacy", - "manage_settings": "Manage settings and app preference", - "support": "Support", - "get_help": "Get help through phone or Telegram", - "logout": "Logout", - "app_settings": "App settings", - "legal_and_information": "Legal & Information", - "change_language": "Change language", - "terms_and_conditions": "Terms & Conditions", - "delete_account": "Delete account", - "language_preference": "Language preference", - "choose_your_language": "Choose your language", - "switch_language_anytime": "You can switch languages anytime", - "need_help": "Need help?", - "call_support": "Call support", - "talk_with_support": "Talk with our support team directly", - "telegram_support": "Telegram support", - "chat_via_telegram": "Chat instantly via Telegram", - "call_our_support": "Call our support team between 9 AM - 6 PM", - "tap_to_call": "Tap to call", - "join_telegram": "Join Yimaru Academy on Telegram", - "connect_with_support_team": "Connect with our support team instantly on Telegram for quick assistance and community updates", - "open_in_telegram": "Open in Telegram", - "search_for": "Search for", - "current_level": "Current Level", - "keep_up_the_great_work": "Keep up the great work! You're doing amazing.", - "no_practice_available": "No practice available!", - "begin_module_practice": "Begin Module Practice", - "lets_practice_lesson": "Let’s Practice", - "lets_quickly_review": "Let’s quickly review what you’ve learned in this module!", - "lets_practice_module": "Let's practice what you just learnt!", - "ask_you_few_actions": "I’ll ask you a few questions, and you can respond naturally.", - "begin_level_practice": "Begin Level Practice", - "lets_practice_course": "Let’s Practice Course", - "lets_quick_review": "Let’s quickly review what you’ve learned in this level!", - "speaking": "is speaking...", - "you_have_finished_practice": "You have finished your practice", - "view_results": "View My Results", - "sample_answer": "Sample Answer", - "your_answer": "Your Answer", - "sound_confident": "You sound more confident this time - great improvement!", - "you_have_completed": "Yay, you’ve completed", - "yes": "Yes", - "no": "No", - "want_to_quit": "Are you sure you want to quit?", - "required_field": "The field is required", - "enter_full_name": "Enter your full name", - "invalid_email": "Invalid email format", - "phone_must_start_with": "Phone number must start with 251", - "phone_must_be": "Phone number must be 12 digits", - "what_should_we_call_you": "What should we call you?", - "name_for_personalization": "We’ll use your name to personalize your learning journey.", - "choose_your_gender": "Choose your gender?", - "gender_for_personalization": "We’ll personalize your learning experience based on your gender.", - "age_range": "Which age range are you in?", - "age_for_personalization": "We’ll personalize your learning experience based on your age.", - "educational_background": "What’s your current educational level?", - "education_for_personalization": "This helps us tailor your lessons to your experience.", - "your_occupation": "What’s your occupation?", - "occupation_for_personalization": "We’ll personalize your learning experience based on your occupation.", - "location": "Where are you from?", - "select_country_region": "Select your country and region from the dropdown", - "select_country": "Select country", - "learning_goal": "Choose your learning goal.", - "language_goal": "What’s your main goal for improving your English?", - "your_goal": "Your goal helps us tailor your learning journey.", - "write_your_goal": "Write your goal…", - "challenge_you_face": "What challenge do you face most with English?", - "evey_one_has_strugle": "Everyone has struggles, let’s start fixing yours", - "write_your_challenge": "Write your challenge…", - "topic_interest": "Which topics interest you most?", - "favourite_topic": "Your favorite topics help us create fun, relatable lessons.", - "your_interest": "Write your interest…", - "want_quick_assessment": "Want a quick assessment to know your English level?", - "answer_quick_questions": "Answer a few quick questions to help us understand your English proficiency.", - "skip": "Skip", - "finish_level": "Finish Level", - "likely_speaker": "You’re likely speaker of", - "great_job": "Great Job! Here’s your next step to keep improving.", - "lets_start_practice": "Let's start your practice", - "welcome_abroad": "Welcome aboard", - "ready_to_explore": "You’re ready to explore your personalized lessons.", - "finish": "Finish", - "finish_all_practice_lesson": "Finish the previous lesson practice to take this practice", - "finish_all_practice_module": "Finish the lesson practices to take the Module Practice", - "finish_all_practice_course": "Finish the Module practices to take the Course practice", - "finish_all_practice_previouse_module": "Finish the previous Module practice to take this practice", - "finish_all_practice_previouse_course": "Finish the previous course practice to take this" -}; -static const Map> mapLocales = {"am": _am, "en": _en}; + static const Map _am = { + "loading": "በመጫን ላይ", + "welcome_back": "እንኳን በደህና ተመለሱ", + "checking_user_info": "የተጠቃሚ መረጃን በማረጋገጥ ላይ", + "dont_have_account": "መለያ የለዎትም?", + "email": "ኢሜይል", + "password": "የይለፍ ቃል", + "forgot_password": "የይለፍ ቃል ረሱ?", + "cont": "ቀጥል", + "register": "ይመዝገቡ", + "login_with_google": "በጉግል ይግቡ", + "or": "ወይም", + "login_with_phone": "በስልክ ቁጥር ይግቡ", + "create_account": "አዲስ መለያ ይፍጠሩ", + "already_have_account": "መለያ አለዎት?", + "login": " ይግቡ ", + "register_with_google": "በጉግል ይመዝገቡ", + "register_with_phone": "በስልክ ቁጥር ይመዝገቡ", + "enter_phone_number": "የስልክ ቁጥርዎን ያስገቡ። የማረጋገጫ ኮድ እንልክልዎታለን።", + "login_with_email": "በኢሜይል ይግቡ", + "create_password": "የይለፍ ቃል ይፍጠሩ", + "confirm_password": "የይለፍ ቃል ያረጋግጡ", + "eight_character_minimum": "ቢያንስ 8 ፊደላት", + "password_match": "የይለፍ ቃሉ ተመሳስሏል", + "sign_up_agreement": + "‘ይመዝገቡ’ የሚለውን ሲጫኑ በ‘አገልግሎት ውሎች’ እና ‘በግላዊነት ፖሊሲ’ ይስማማሉ።", + "terms_of_services": "የአገልግሎት ውሎች", + "and": "እና", + "privacy_policy": "የግላዊነት ፖሊሲ", + "register_with_email": "በኢሜል ይመዝገቡ", + "verification_code": "የማረጋገጫ ኮድ", + "resend_code": "ኮዱን እንደገና ላክ", + "code_sent_to_phone": "ኮዱ ወደ ስልክ ቁጥርዎ ተልኳል", + "code_sent_to_email": "ኮዱ ወደ ኢሜል ተልኳል", + "resend_code_in": "ኮዱን እንደገና ለመላክ የቀረው ጊዜ", + "reset_password": " የይለፍ ቃልን ይቀይሩ", + "enter_email_reset_code": "ኢሜይልዎን ያስገቡ። የይለፍ ቃል መለወጫ ኮድ እንልክልዎታለን።", + "please_wait": "እባክዎ ይጠብቁ", + "reset_code_sent": "የመቀየሪያ ኮድ በተሳካ ሁኔታ ተልኳል", + "reset_code": " የመቀየሪያ ኮድ ", + "new_password": "አዲስ የይለፍ ቃል", + "logged_in_successfully": "በተሳካ ሁኔታ ገብተዋል", + "view_course": " ኮርሱን ይመልከቱ", + "continue_learning": "መማርን ይቀጥሉ", + "start_learning": "ትምህርትን ይጀምሩ", + "completed": "ተጠናቋል", + "take_practice": "ልምምድ ያድርጉ", + "your_current_level": "የአሁኑ ደረጃዎ", + "overall_progress": "አጠቃላይ እድገት", + "great_work": "በርቱ! በጣም ጥሩ እየሰሩ ነው", + "view_module": "ሞጁሉን ይመልከቱ", + "progress": "እድገት", + "keep_going": "ይቀጥሉ - ከግማሽ በላይ ጨርሰዋል ", + "lessons_in_module": "በዚህ ሞጁል ውስጥ ያሉ ትምህርቶች ", + "practice": "ልምምድ", + "start": "ጀምር", + "in_progress": "በሂደት ላይ", + "hello": "ሰላም", + "ready_to_learn": " ዛሬ እንግሊዝኛ ለመማር ተዘጋጅተዋል? ", + "learn": "ይማሩ ", + "course": "ኮርስ", + "profile": " ፕሮፋይል ", + "speaking_partner": "የንግግር ጓደኛ", + "practice_what_you_learned": "አሁን የተማሩትን እንለማመድ", + "practice_questions": "ጥቂት ጥያቄዎችን እጠይቃለሁ እና መልስ መስጠት ይችላሉ", + "start_practice": "ልምምድ ጀምር", + "almost_there": "ሊጨርሱ ተቃርበዋል", + "finish_session": "እድገትዎን ለማየት ክፍለ ጊዜውን ያጠናቅቁ", + "continue_practice": "ልምምዱን ይቀጥሉ", + "end_session": "ክፍለ ጊዜውን ያብቁ ", + "tap_start_to_listen": "ለማዳመጥ የጀምር ቁልፉን ይጫኑ", + "practice_speaking": "ንግግርን ይለማመዱ", + "tap_microphone": "ለመናገር ማይክሮፎኑን ይጫኑ", + "reply": "እንደገና አዳምጥ", + "cancel": "ይቅር", + "you_are_speaking": "እየተናገሩ ነው", + "practice_completed": "ልምምዱ ተጠናቅቋል", + "great_improvement": "በዚህኛው በራስ መተማመንዎ ጨምሯል፤ ትልቅ መሻሻል ነው", + "practice_again": "እንደገና ይለማመዱ", + "conversation_review": "የንግግር ግምገማ", + "result": "ውጤት", + "quick_tip": "ጠቃሚ ምክር", + "retry": "እንደገና ይሞክሩ", + "completed_a1": "እንኳን ደስ አለዎት! A1 ደረጃን አጠናቅቀዋል", + "analyzing_speaking": "የንግግር ችሎታዎን እየገመገምን ነው", + "view_profile": "ፕሮፋይሎን ይመልከቱ ", + "hi": "ሰላም", + "edit_profile": "መገለጫ ያስተካክሉ", + "first_name": "የመጀመሪያ ስም", + "last_name": "የአባት ስም", + "gender": "ፆታ", + "male": "ወንድ", + "female": "ሴት", + "phone_number": "የስልክ ቁጥር", + "country": "ሀገር", + "region": "ክልል", + "select_region": "ክልል ይምረጡ", + "enter_your_city": "ከተማዎን ያስገቡ", + "occupation": "የስራ መስክ", + "select_occupation": "ሙያዎን ይምረጡ", + "save_changes": "ለውጦችን ያስቀምጡ", + "my_progress": "የእኔ እድገት", + "track_your_achievement": "ስኬቶችዎን እና ተከታታይ የትምህርት ጉዞዎን ይከታተሉ", + "account_and_privacy": "መለያ እና ግላዊነት", + "manage_settings": "ቅንብሮችን እና የመተግበሪያ ምርጫዎችን ያስተዳድሩ", + "support": "ድጋፍ", + "get_help": "በስልክ ወይም በቴሌግራም እገዛ ያግኙ", + "logout": "ውጣ", + "app_settings": "የመተግበሪያ ቅንብሮች", + "legal_and_information": "ሕጋዊ እና መረጃ", + "change_language": "ቋንቋ ቀይር", + "terms_and_conditions": "ውሎች እና ሁኔታዎች", + "delete_account": "መለያ ሰርዝ", + "language_preference": "የቋንቋ ምርጫ", + "choose_your_language": "ለውጦችን አስቀምጥ", + "switch_language_anytime": "ቋንቋዎችን በማንኛውም ጊዜ መቀየር ይችላሉ", + "need_help": "እገዛ ይፈልጋሉ?", + "call_support": "የስልክ ድጋፍ", + "talk_with_support": "በቀጥታ ከድጋፍ ቡድናችን ጋር ይነጋገሩ", + "telegram_support": "የቴሌግራም ድጋፍ", + "chat_via_telegram": "በቴሌግራም በፍጥነት ይወያዩ", + "call_our_support": "ከ3 ጠዋት እስከ 12 ማታ ድረስ የድጋፍ ቡድናችንን ይደውሉ", + "tap_to_call": "ለመደወል ይንኩ", + "join_telegram": "በቴሌግራም የይማሩ አካዳሚን ይቀላቀሉ", + "connect_with_support_team": + "ለፈጣን እርዳታ እና የማህበረሰብ ዝማኔዎች፣ በቴሌግራም ከድጋፍ ቡድናችን ጋር ወዲያውኑ ይገናኙ።", + "open_in_telegram": "በቴሌግራም ይክፈቱ", + "search_for": "ፈልጉት", + "current_level": "የአሁኑ ደረጃ", + "keep_up_the_great_work": "በጣም ጥሩ እየሰራህ ነው! ቀጥልበት፣ አስደናቂ ነህ።", + "no_practice_available": "ምንም ልምምድ አልተገኘም!", + "begin_module_practice": "የሞጁሉን ልምምድ ጀምር", + "lets_practice_lesson": "እንለማመድ", + "lets_quickly_review": "በዚህ ሞጁል ውስጥ የተማርከውን በፍጥነት እንከልስ!", + "lets_practice_module": "አሁን የተማርከውን እንለማመድ!", + "ask_you_few_actions": "ጥቂት ጥያቄዎችን እጠይቅሃለሁ፣ አንተም በተፈጥሮ መልስ ልትሰጥ ትችላለህ።", + "begin_level_practice": "የደረጃ ልምምድን ጀምር", + "lets_practice_course": "የኮርሱን ልምምድ እንለማመድ", + "lets_quick_review": "በዚህ ደረጃ የተማርከውን በፍጥነት እንከልስ!", + "speaking": "እየተናገረ ነው", + "you_have_finished_practice": "ልምምድህን አጠናቀቅህ", + "view_results": "ውጤቶቼን እይ", + "sample_answer": "ናሙና መልስ", + "your_answer": "መልስህ", + "sound_confident": "በዚህ ጊዜ የበለጠ እምነት ያለህ ይመስላል — በጣም ጥሩ መሻሻል ነው!", + "you_have_completed": "አያይ! አጠናቀቅህ", + "yes": "አዎ", + "no": "አይ", + "want_to_quit": "ለመውጣት እርግጠኛ ነህ?", + "required_field": "ይህ መስክ ያስፈልጋል", + "enter_full_name": "ሙሉ ስምህን አስገባ", + "invalid_email": "የማይሰራ የኢሜይል ቅርጸት", + "phone_must_start_with": "የስልክ ቁጥር በ251 መጀመር አለበት", + "phone_must_be": "የስልክ ቁጥር 12 አሃዞች መሆን አለበት", + "what_should_we_call_you": "ምን ብለን እንጠራህ?", + "name_for_personalization": "በመማር ጉዞህ ውስጥ ለግል ለማድረግ ስምህን እንጠቀማለን።", + "choose_your_gender": "ጾታህን ምረጥ", + "gender_for_personalization": "በጾታህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "age_range": "በየትኛው የእድሜ ክልል ውስጥ ነህ?", + "age_for_personalization": "በእድሜህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "educational_background": "አሁን ያለህ የትምህርት ደረጃ ምንድን ነው?", + "education_for_personalization": "ይህ ትምህርቶችን ከልምድህ ጋር እንዲስማሙ ለማድረግ ይረዳናል።", + "your_occupation": "ስራህ ምንድን ነው?", + "occupation_for_personalization": "በስራህ መሰረት የመማር ተሞክሮህን እናበጅለታለን።", + "location": "ከየት ነህ?", + "select_country_region": "አገርህን እና ክልልህን ከተቆልቋይ ዝርዝሩ ምረጥ", + "select_country": "አገር ምረጥ", + "learning_goal": "የመማር ዓላማህን ምረጥ", + "language_goal": "እንግሊዝኛህን ለማሻሻል ዋና ዓላማህ ምንድን ነው?", + "your_goal": "ዓላማህ የመማር ጉዞህን እንዲስማማ ለማድረግ ይረዳናል።", + "write_your_goal": "ዓላማህን ጻፍ…", + "challenge_you_face": "What challenge do you face most with English?", + "evey_one_has_strugle": "ሁሉም ሰው ችግሮች አሉት፣ የአንተን እንጀምር እንፍታ", + "write_your_challenge": "ችግርህን ጻፍ…", + "topic_interest": "በጣም የሚስቡህ ርዕሶች የትኞቹ ናቸው?", + "favourite_topic": + "የምትወዳቸው ርዕሶች አስደሳች እና ከሕይወትህ ጋር የተዛመዱ ትምህርቶችን ለመፍጠር ይረዱናል።", + "your_interest": "ፍላጎትህን ጻፍ…", + "want_quick_assessment": "የእንግሊዝኛ ደረጃህን ለማወቅ ፈጣን ግምገማ ትፈልጋለህ?", + "answer_quick_questions": "የእንግሊዝኛ ችሎታህን ለመረዳት ጥቂት ፈጣን ጥያቄዎችን መልስ።", + "skip": "ዝለል", + "finish_level": "ደረጃውን አጠናቅቅ", + "likely_speaker": "አንተ ምናልባት ተናጋሪ ነህ", + "great_job": "በጣም ጥሩ ስራ! ለመሻሻል ቀጣዩ ደረጃህ ይኸው ነው።", + "lets_start_practice": "ልምምድህን እንጀምር", + "welcome_abroad": "እንኳን ደህና መጣህ", + "ready_to_explore": "የግል ትምህርቶችህን ለማሰስ ዝግጁ ነህ።", + "finish": "አጠናቅቅ", + "finish_all_practice_lesson": "ይህን ልምምድ ለመውሰድ የቀድሞውን የትምህርት ልምምድ ያጠናቅቁ", + "finish_all_practice_module": "የሞጁሉን ልምምድ ለመውሰድ የትምህርት ልምምዶችን ያጠናቅቁ", + "finish_all_practice_course": "የኮርሱን ልምምድ ለመውሰድ የሞጁል ልምምዶችን ያጠናቅቁ", + "finish_all_practice_previouse_module": + "ይህን ልምምድ ለመውሰድ የቀድሞውን የሞጁል ልምምድ ያጠናቅቁ", + "finish_all_practice_previouse_course": "ይህን ለመውሰድ የቀድሞውን የኮርስ ልምምድ ያጠናቅቁ" + }; + static const Map _en = { + "loading": "Loading", + "welcome_back": "Welcome back", + "checking_user_info": "Checking user info", + "dont_have_account": "Don't have an account?", + "email": "Email", + "password": "Password", + "forgot_password": "Forgot password?", + "cont": "Continue", + "register": "Register", + "login_with_google": "Login with Google", + "or": "Or", + "login_with_phone": "Login with phone number", + "create_account": "Create an account", + "already_have_account": "Already have an account?", + "login": "Login", + "register_with_google": "Register with Google", + "register_with_phone": "Register with phone number", + "enter_phone_number": + "Enter your phone number. We will send you a confirmation code there.", + "login_with_email": "Login with email", + "create_password": "Create password", + "confirm_password": "Confirm password", + "eight_character_minimum": "8 characters minimum", + "password_match": "password match", + "sign_up_agreement": + "By clicking ‘Sign Up’, you agree to our ‘Terms of Service’ and ‘Privacy Policy’", + "terms_of_services": "Terms of Service", + "and": "and", + "privacy_policy": "Privacy Policy", + "register_with_email": "Register with email", + "verification_code": "Verification Code", + "resend_code": "Resend Code", + "code_sent_to_phone": "Code sent to your number", + "code_sent_to_email": "Code sent to your email", + "resend_code_in": "Resend code in", + "reset_password": "Reset Password", + "enter_email_reset_code": + "Enter your email. We will send you a reset code.", + "please_wait": "Please wait", + "reset_code_sent": "Reset code sent successfully", + "reset_code": "Reset code", + "new_password": "New password", + "logged_in_successfully": "Logged in successfully", + "continue_learning": "Continue Learning", + "start_learning": "Start Learning", + "completed": "Completed", + "view_course": "View course", + "take_practice": "Take practice", + "your_current_level": "Your current level", + "overall_progress": "Overall progress", + "great_work": "Keep up the great work! You're doing amazing", + "view_module": "View module", + "progress": "Progress", + "keep_going": "Let's keep going - you're more than half there", + "lessons_in_module": "Lessons in this module", + "practice": "Practice", + "start": "Start", + "in_progress": "In Progress", + "hello": "Hello", + "ready_to_learn": "Ready to keep learning English today", + "learn": "Learn", + "course": "Course", + "profile": "Profile", + "speaking_partner": "Speaking partner", + "practice_what_you_learned": "Let's practice what you just learnt", + "practice_questions": "I will ask you a few questions and you can respond", + "start_practice": "Start practice", + "almost_there": "You're almost there", + "finish_session": "Finish the session to see your progress", + "continue_practice": "Continue practice", + "end_session": "End session", + "tap_start_to_listen": "Tap the start button to listen", + "practice_speaking": "Practice speaking", + "tap_microphone": "Tap the microphone to speak", + "reply": "Reply", + "cancel": "Cancel", + "you_are_speaking": "You're speaking", + "practice_completed": "Practice completed!", + "great_improvement": + "You sound more confident this time, great improvement", + "practice_again": "Practice again", + "conversation_review": "Conversation review", + "result": "Result", + "quick_tip": "Quick tip", + "retry": "Retry", + "completed_a1": "Yay, you've completed A1", + "analyzing_speaking": "We're now analyzing your speaking skill", + "view_profile": "View profile", + "hi": "Hi", + "edit_profile": "Edit profile", + "first_name": "First name", + "last_name": "Last name", + "gender": "Gender", + "male": "Male", + "female": "Female", + "phone_number": "Phone number", + "country": "Country", + "region": "Region", + "select_region": "Select region", + "enter_your_city": "Enter your city", + "occupation": "Occupation", + "select_occupation": "Select occupation", + "save_changes": "Save changes", + "my_progress": "My progress", + "track_your_achievement": "Track your achievements and learning streak", + "account_and_privacy": "Account & Privacy", + "manage_settings": "Manage settings and app preference", + "support": "Support", + "get_help": "Get help through phone or Telegram", + "logout": "Logout", + "app_settings": "App settings", + "legal_and_information": "Legal & Information", + "change_language": "Change language", + "terms_and_conditions": "Terms & Conditions", + "delete_account": "Delete account", + "language_preference": "Language preference", + "choose_your_language": "Choose your language", + "switch_language_anytime": "You can switch languages anytime", + "need_help": "Need help?", + "call_support": "Call support", + "talk_with_support": "Talk with our support team directly", + "telegram_support": "Telegram support", + "chat_via_telegram": "Chat instantly via Telegram", + "call_our_support": "Call our support team between 9 AM - 6 PM", + "tap_to_call": "Tap to call", + "join_telegram": "Join Yimaru Academy on Telegram", + "connect_with_support_team": + "Connect with our support team instantly on Telegram for quick assistance and community updates", + "open_in_telegram": "Open in Telegram", + "search_for": "Search for", + "current_level": "Current Level", + "keep_up_the_great_work": "Keep up the great work! You're doing amazing.", + "no_practice_available": "No practice available!", + "begin_module_practice": "Begin Module Practice", + "lets_practice_lesson": "Let’s Practice", + "lets_quickly_review": + "Let’s quickly review what you’ve learned in this module!", + "lets_practice_module": "Let's practice what you just learnt!", + "ask_you_few_actions": + "I’ll ask you a few questions, and you can respond naturally.", + "begin_level_practice": "Begin Level Practice", + "lets_practice_course": "Let’s Practice Course", + "lets_quick_review": + "Let’s quickly review what you’ve learned in this level!", + "speaking": "is speaking...", + "you_have_finished_practice": "You have finished your practice", + "view_results": "View My Results", + "sample_answer": "Sample Answer", + "your_answer": "Your Answer", + "sound_confident": + "You sound more confident this time - great improvement!", + "you_have_completed": "Yay, you’ve completed", + "yes": "Yes", + "no": "No", + "want_to_quit": "Are you sure you want to quit?", + "required_field": "The field is required", + "enter_full_name": "Enter your full name", + "invalid_email": "Invalid email format", + "phone_must_start_with": "Phone number must start with 251", + "phone_must_be": "Phone number must be 12 digits", + "what_should_we_call_you": "What should we call you?", + "name_for_personalization": + "We’ll use your name to personalize your learning journey.", + "choose_your_gender": "Choose your gender?", + "gender_for_personalization": + "We’ll personalize your learning experience based on your gender.", + "age_range": "Which age range are you in?", + "age_for_personalization": + "We’ll personalize your learning experience based on your age.", + "educational_background": "What’s your current educational level?", + "education_for_personalization": + "This helps us tailor your lessons to your experience.", + "your_occupation": "What’s your occupation?", + "occupation_for_personalization": + "We’ll personalize your learning experience based on your occupation.", + "location": "Where are you from?", + "select_country_region": "Select your country and region from the dropdown", + "select_country": "Select country", + "learning_goal": "Choose your learning goal.", + "language_goal": "What’s your main goal for improving your English?", + "your_goal": "Your goal helps us tailor your learning journey.", + "write_your_goal": "Write your goal…", + "challenge_you_face": "What challenge do you face most with English?", + "evey_one_has_strugle": "Everyone has struggles, let’s start fixing yours", + "write_your_challenge": "Write your challenge…", + "topic_interest": "Which topics interest you most?", + "favourite_topic": + "Your favorite topics help us create fun, relatable lessons.", + "your_interest": "Write your interest…", + "want_quick_assessment": + "Want a quick assessment to know your English level?", + "answer_quick_questions": + "Answer a few quick questions to help us understand your English proficiency.", + "skip": "Skip", + "finish_level": "Finish Level", + "likely_speaker": "You’re likely speaker of", + "great_job": "Great Job! Here’s your next step to keep improving.", + "lets_start_practice": "Let's start your practice", + "welcome_abroad": "Welcome aboard", + "ready_to_explore": "You’re ready to explore your personalized lessons.", + "finish": "Finish", + "finish_all_practice_lesson": + "Finish the previous lesson practice to take this practice", + "finish_all_practice_module": + "Finish the lesson practices to take the Module Practice", + "finish_all_practice_course": + "Finish the Module practices to take the Course practice", + "finish_all_practice_previouse_module": + "Finish the previous Module practice to take this practice", + "finish_all_practice_previouse_course": + "Finish the previous course practice to take this" + }; + static const Map> mapLocales = { + "am": _am, + "en": _en + }; } diff --git a/lib/ui/common/translations/locale_keys.g.dart b/lib/ui/common/translations/locale_keys.g.dart index 31c729d..9db9a77 100644 --- a/lib/ui/common/translations/locale_keys.g.dart +++ b/lib/ui/common/translations/locale_keys.g.dart @@ -2,7 +2,7 @@ // ignore_for_file: constant_identifier_names -abstract class LocaleKeys { +abstract class LocaleKeys { static const loading = 'loading'; static const welcome_back = 'welcome_back'; static const checking_user_info = 'checking_user_info'; @@ -161,7 +161,8 @@ abstract class LocaleKeys { static const educational_background = 'educational_background'; static const education_for_personalization = 'education_for_personalization'; static const your_occupation = 'your_occupation'; - static const occupation_for_personalization = 'occupation_for_personalization'; + static const occupation_for_personalization = + 'occupation_for_personalization'; static const location = 'location'; static const select_country_region = 'select_country_region'; static const select_country = 'select_country'; @@ -188,7 +189,8 @@ abstract class LocaleKeys { static const finish_all_practice_lesson = 'finish_all_practice_lesson'; static const finish_all_practice_module = 'finish_all_practice_module'; static const finish_all_practice_course = 'finish_all_practice_course'; - static const finish_all_practice_previouse_module = 'finish_all_practice_previouse_module'; - static const finish_all_practice_previouse_course = 'finish_all_practice_previouse_course'; - + static const finish_all_practice_previouse_module = + 'finish_all_practice_previouse_module'; + static const finish_all_practice_previouse_course = + 'finish_all_practice_previouse_course'; } diff --git a/lib/ui/views/assessment/screens/assessment_result_screen.dart b/lib/ui/views/assessment/screens/assessment_result_screen.dart index b9bea31..b12f32f 100644 --- a/lib/ui/views/assessment/screens/assessment_result_screen.dart +++ b/lib/ui/views/assessment/screens/assessment_result_screen.dart @@ -27,10 +27,8 @@ class AssessmentResultScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(AssessmentViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(AssessmentViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildAppBar(AssessmentViewModel viewModel) => LargeAppBar( showBackButton: true, diff --git a/lib/ui/views/assessment/screens/start_lesson_screen.dart b/lib/ui/views/assessment/screens/start_lesson_screen.dart index ddf08c6..c5a4969 100644 --- a/lib/ui/views/assessment/screens/start_lesson_screen.dart +++ b/lib/ui/views/assessment/screens/start_lesson_screen.dart @@ -44,10 +44,8 @@ class StartLessonScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(AssessmentViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(AssessmentViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildAppBar(AssessmentViewModel viewModel) => LargeAppBar( showBackButton: true, diff --git a/lib/ui/views/forget_password/screens/reset_password_screen.dart b/lib/ui/views/forget_password/screens/reset_password_screen.dart index 9eba173..6ed75b7 100644 --- a/lib/ui/views/forget_password/screens/reset_password_screen.dart +++ b/lib/ui/views/forget_password/screens/reset_password_screen.dart @@ -86,10 +86,8 @@ class ResetPasswordScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(ForgetPasswordViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(ForgetPasswordViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildAppBar(ForgetPasswordViewModel viewModel) => LargeAppBar( showBackButton: true, diff --git a/lib/ui/views/learn_lesson/learn_lesson_view.dart b/lib/ui/views/learn_lesson/learn_lesson_view.dart index 1abb676..25d3c8f 100644 --- a/lib/ui/views/learn_lesson/learn_lesson_view.dart +++ b/lib/ui/views/learn_lesson/learn_lesson_view.dart @@ -26,13 +26,12 @@ class LearnLessonView extends StackedView { required LearnLesson lesson, required BuildContext context, required LearnLessonViewModel viewModel}) async { - if (lesson.access?.isAccessible ?? false) { + if (lesson.access?.isAccessible ?? false) { await viewModel.navigateToLearnPractice(lesson.id ?? 0); } else { await _showSheet(context: context, viewModel: viewModel); } -/* - if (index > 1) { +/* if (index > 1) { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { if (lesson.access?.isAccessible ?? false) { await viewModel.navigateToLearnPractice(lesson.id ?? 0); @@ -226,7 +225,7 @@ class LearnLessonView extends StackedView { itemBuilder: (context, index) => _buildTile( index: index, lesson: viewModel.lessons[index], - last: index == viewModel.lessons.length - 1 , + last: index == viewModel.lessons.length - 1, onPracticeTap: () async => await _onPractice( index: index, context: context, @@ -252,7 +251,6 @@ class LearnLessonView extends StackedView { LearnLessonTile( last: last, index: index, - lesson: lesson, onLessonTap: onLessonTap, onPracticeTap: onPracticeTap, diff --git a/lib/ui/views/learn_lesson/learn_lesson_viewmodel.dart b/lib/ui/views/learn_lesson/learn_lesson_viewmodel.dart index 326a1e4..8340801 100644 --- a/lib/ui/views/learn_lesson/learn_lesson_viewmodel.dart +++ b/lib/ui/views/learn_lesson/learn_lesson_viewmodel.dart @@ -59,14 +59,15 @@ class LearnLessonViewModel extends ReactiveViewModel { await _navigationService.navigateToLearnSubscriptionView(); Future navigateToLearnLessonDetail( - { - required int index, - required bool hasPractice, + {required int index, + required bool hasPractice, required LearnLesson lesson, required LearnModule module}) async => await _navigationService.navigateToLearnLessonDetailView( - index: index, - lesson: lesson, module: module, hasPractice: hasPractice); + index: index, + lesson: lesson, + module: module, + hasPractice: hasPractice); // Remote api call diff --git a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart index 5f9dcea..f2708ae 100644 --- a/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart +++ b/lib/ui/views/learn_lesson_detail/learn_lesson_detail_view.dart @@ -31,11 +31,10 @@ class LearnLessonDetailView extends StackedView { Future _onPractice( {required LearnLesson lesson, required LearnLessonDetailViewModel viewModel}) async { - await viewModel.pause(); + await viewModel.pause(); await viewModel.navigateToLearnPractice(lesson.id ?? 0); - - /* if (index > 1) { +/* if (index > 1) { if (viewModel.user?.subscriptionStatus?.toLowerCase() == 'subscribed') { await viewModel.pause(); await viewModel.navigateToLearnPractice(lesson.id ?? 0); diff --git a/lib/ui/views/learn_module/learn_module_view.dart b/lib/ui/views/learn_module/learn_module_view.dart index 3bdc3ed..3a5d599 100644 --- a/lib/ui/views/learn_module/learn_module_view.dart +++ b/lib/ui/views/learn_module/learn_module_view.dart @@ -24,7 +24,7 @@ class LearnModuleView extends StackedView { {required BuildContext context, required LearnModule module, required LearnModuleViewModel viewModel}) async { - if (module.access?.completedCount == module.access?.totalCount ) { + if (module.access?.completedCount == module.access?.totalCount) { await viewModel.navigateToLearnPractice( id: module.id ?? 0, module: module.name ?? ''); } else { diff --git a/lib/ui/views/learn_subscription/learn_subscription_viewmodel.dart b/lib/ui/views/learn_subscription/learn_subscription_viewmodel.dart index dbd6e96..a581729 100644 --- a/lib/ui/views/learn_subscription/learn_subscription_viewmodel.dart +++ b/lib/ui/views/learn_subscription/learn_subscription_viewmodel.dart @@ -31,6 +31,10 @@ class LearnSubscriptionViewModel extends FormViewModel { int get selectedIndex => _selectedIndex; + LearnSubscription? _selectedSubscription; + + LearnSubscription? get selectedSubscription => _selectedSubscription; + List _subscriptions = []; List get subscriptions => _subscriptions; @@ -40,6 +44,13 @@ class LearnSubscriptionViewModel extends FormViewModel { _focusPhoneNumber = true; rebuildUi(); } + //Learn subscriptions + + void setSelectedPricing(int index) { + _selectedIndex = index; + _selectedSubscription = _subscriptions[index]; + rebuildUi(); + } // In-app navigation @@ -60,16 +71,11 @@ class LearnSubscriptionViewModel extends FormViewModel { // Navigation void pop() => _navigationService.back(); - Future navigateToArifPay(String phone) async { + Future navigateToArifPay( + {required String phone, required LearnSubscription? subscription}) async { pop(); - await _navigationService.navigateToArifPayView(phone: phone); - } - - //Learn subscriptions - - void setSelectedPricing(int index) { - _selectedIndex = index; - rebuildUi(); + await _navigationService.navigateToPaymentView( + phone: phone, subscription: subscription ?? _subscriptions[0]); } // Remote api call diff --git a/lib/ui/views/learn_subscription/screens/learn_subscription_form_screen.dart b/lib/ui/views/learn_subscription/screens/learn_subscription_form_screen.dart index 3894f7f..af04586 100644 --- a/lib/ui/views/learn_subscription/screens/learn_subscription_form_screen.dart +++ b/lib/ui/views/learn_subscription/screens/learn_subscription_form_screen.dart @@ -178,8 +178,9 @@ class LearnSubscriptionFormScreen ? kcPrimaryColor : kcPrimaryColor.withOpacity(0.1), onTap: phoneNumberController.text.isNotEmpty - ? () async => - await viewModel.navigateToArifPay(phoneNumberController.text) + ? () async => await viewModel.navigateToArifPay( + phone: phoneNumberController.text, + subscription: viewModel.selectedSubscription) : null, ); diff --git a/lib/ui/views/onboarding/screens/age_group_form_screen.dart b/lib/ui/views/onboarding/screens/age_group_form_screen.dart index 1fc2f9e..f7b25b1 100644 --- a/lib/ui/views/onboarding/screens/age_group_form_screen.dart +++ b/lib/ui/views/onboarding/screens/age_group_form_screen.dart @@ -41,10 +41,8 @@ class AgeGroupFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildColumnScroller(viewModel)); diff --git a/lib/ui/views/onboarding/screens/challenge_form_screen.dart b/lib/ui/views/onboarding/screens/challenge_form_screen.dart index 0b111c2..246c6d4 100644 --- a/lib/ui/views/onboarding/screens/challenge_form_screen.dart +++ b/lib/ui/views/onboarding/screens/challenge_form_screen.dart @@ -42,10 +42,8 @@ class ChallengeFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyScroller(viewModel)); diff --git a/lib/ui/views/onboarding/screens/country_region_form_screen.dart b/lib/ui/views/onboarding/screens/country_region_form_screen.dart index c49639d..8970cf0 100644 --- a/lib/ui/views/onboarding/screens/country_region_form_screen.dart +++ b/lib/ui/views/onboarding/screens/country_region_form_screen.dart @@ -58,10 +58,8 @@ class CountryRegionFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyWrapper(viewModel)); diff --git a/lib/ui/views/onboarding/screens/educational_background_form_screen.dart b/lib/ui/views/onboarding/screens/educational_background_form_screen.dart index 849e3f3..f4ce8a7 100644 --- a/lib/ui/views/onboarding/screens/educational_background_form_screen.dart +++ b/lib/ui/views/onboarding/screens/educational_background_form_screen.dart @@ -43,10 +43,8 @@ class EducationalBackgroundFormScreen children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildColumnScroller(viewModel)); diff --git a/lib/ui/views/onboarding/screens/full_name_form_screen.dart b/lib/ui/views/onboarding/screens/full_name_form_screen.dart index d522bf6..1da32ff 100644 --- a/lib/ui/views/onboarding/screens/full_name_form_screen.dart +++ b/lib/ui/views/onboarding/screens/full_name_form_screen.dart @@ -40,10 +40,8 @@ class FullNameFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyWrapper(viewModel)); diff --git a/lib/ui/views/onboarding/screens/gender_form_screen.dart b/lib/ui/views/onboarding/screens/gender_form_screen.dart index 7898e3a..b6f0e48 100644 --- a/lib/ui/views/onboarding/screens/gender_form_screen.dart +++ b/lib/ui/views/onboarding/screens/gender_form_screen.dart @@ -40,10 +40,8 @@ class GenderFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyWrapper(viewModel)); diff --git a/lib/ui/views/onboarding/screens/language_goal_form_screen.dart b/lib/ui/views/onboarding/screens/language_goal_form_screen.dart index 8360ee6..fb9d5c3 100644 --- a/lib/ui/views/onboarding/screens/language_goal_form_screen.dart +++ b/lib/ui/views/onboarding/screens/language_goal_form_screen.dart @@ -25,8 +25,6 @@ class LanguageGoalFormScreens extends ViewModelWidget { return Icons.book; } - - String getSubtitle(int index) { switch (index) { case 0: @@ -49,7 +47,6 @@ class LanguageGoalFormScreens extends ViewModelWidget { Map data = { 'language_goal': viewModel.selectedLanguageGoal?.code, - }; viewModel.addUserData(data); @@ -70,10 +67,8 @@ class LanguageGoalFormScreens extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyScroller(viewModel)); @@ -135,12 +130,12 @@ class LanguageGoalFormScreens extends ViewModelWidget { Widget _buildLanguageGoals(OnboardingViewModel viewModel) => ListView.builder( shrinkWrap: true, - itemCount: viewModel.languageGoals.length, + itemCount: viewModel.languageGoals.length, physics: const NeverScrollableScrollPhysics(), itemBuilder: (context, index) => _buildLanguageGoal( icon: getIcon(index), subtitle: getSubtitle(index), - title:viewModel.languageGoals[index].label ?? '', + title: viewModel.languageGoals[index].label ?? '', selected: viewModel.isSelectedLanguageGoal(viewModel.languageGoals[index]), onTap: () => diff --git a/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart b/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart index 361ebe7..e480ff2 100644 --- a/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart +++ b/lib/ui/views/onboarding/screens/learning_goal_form_screen.dart @@ -42,10 +42,8 @@ class LearningGoalFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyScroller(viewModel)); diff --git a/lib/ui/views/onboarding/screens/occupation_form_screen.dart b/lib/ui/views/onboarding/screens/occupation_form_screen.dart index dae2b6b..513d0a9 100644 --- a/lib/ui/views/onboarding/screens/occupation_form_screen.dart +++ b/lib/ui/views/onboarding/screens/occupation_form_screen.dart @@ -43,10 +43,8 @@ class OccupationFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildExpandedBody(OnboardingViewModel viewModel) => Expanded(child: _buildBodyWrapper(viewModel)); diff --git a/lib/ui/views/onboarding/screens/topic_form_screen.dart b/lib/ui/views/onboarding/screens/topic_form_screen.dart index 1be06ff..354d3e8 100644 --- a/lib/ui/views/onboarding/screens/topic_form_screen.dart +++ b/lib/ui/views/onboarding/screens/topic_form_screen.dart @@ -45,10 +45,8 @@ class TopicFormScreen extends ViewModelWidget { children: _buildScaffoldChildren(viewModel), ); - List _buildScaffoldChildren(OnboardingViewModel viewModel) => [ - _buildAppBar(viewModel), - _buildExpandedBody(viewModel) - ]; + List _buildScaffoldChildren(OnboardingViewModel viewModel) => + [_buildAppBar(viewModel), _buildExpandedBody(viewModel)]; Widget _buildAppBar(OnboardingViewModel viewModel) => LargeAppBar( showBackButton: true, diff --git a/lib/ui/views/arif_pay/arif_pay_view.dart b/lib/ui/views/payment/payment_view.dart similarity index 51% rename from lib/ui/views/arif_pay/arif_pay_view.dart rename to lib/ui/views/payment/payment_view.dart index baaa5d5..f6754c9 100644 --- a/lib/ui/views/arif_pay/arif_pay_view.dart +++ b/lib/ui/views/payment/payment_view.dart @@ -1,55 +1,61 @@ import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:stacked/stacked.dart'; -import 'package:yimaru_app/ui/common/app_constants.dart'; -import 'package:yimaru_app/ui/common/enmus.dart'; -import 'package:yimaru_app/ui/common/ui_helpers.dart'; -import 'package:yimaru_app/ui/widgets/page_loading_indicator.dart'; -import 'arif_pay_viewmodel.dart'; +import '../../../models/learn_subscription.dart'; +import '../../common/app_constants.dart'; +import '../../common/enmus.dart'; +import '../../common/ui_helpers.dart'; +import '../../widgets/page_loading_indicator.dart'; +import 'payment_viewmodel.dart'; -class ArifPayView extends StackedView { +class PaymentView extends StackedView { final String phone; + final LearnSubscription subscription; - const ArifPayView({Key? key, required this.phone}) : super(key: key); + const PaymentView({Key? key, required this.phone, required this.subscription}) + : super(key: key); - void _error(ArifPayViewModel viewModel) => viewModel.pop(); + void _error(PaymentViewModel viewModel) => viewModel.pop(); - Future _success(ArifPayViewModel viewModel) async { + Future _success(PaymentViewModel viewModel) async { await viewModel.updatePaymentStatus(); await viewModel.replaceWithHome(); } @override - void onViewModelReady(ArifPayViewModel viewModel) async { - await viewModel.createLearnSubscriptionRequest(phone); + void onViewModelReady(PaymentViewModel viewModel) async { + await viewModel.createLearnSubscriptionRequest(phone: phone,subscription: subscription); super.onViewModelReady(viewModel); } @override - ArifPayViewModel viewModelBuilder(BuildContext context) => ArifPayViewModel(); + PaymentViewModel viewModelBuilder( + BuildContext context, + ) => + PaymentViewModel(); @override Widget builder( BuildContext context, - ArifPayViewModel viewModel, + PaymentViewModel viewModel, Widget? child, ) => _buildScaffoldWrapper(viewModel); - Widget _buildScaffoldWrapper(ArifPayViewModel viewModel) => + Widget _buildScaffoldWrapper(PaymentViewModel viewModel) => Scaffold(body: _buildScaffoldState(viewModel)); - Widget _buildScaffoldState(ArifPayViewModel viewModel) => + Widget _buildScaffoldState(PaymentViewModel viewModel) => viewModel.busy(StateObjects.learnSubscription) ? const PageLoadingIndicator() : _buildScaffold(viewModel); - Widget _buildScaffold(ArifPayViewModel viewModel) => + Widget _buildScaffold(PaymentViewModel viewModel) => SafeArea(child: _buildBody(viewModel)); - Widget _buildBody(ArifPayViewModel viewModel) => InAppWebView( + Widget _buildBody(PaymentViewModel viewModel) => InAppWebView( initialUrlRequest: URLRequest(url: WebUri(viewModel.request?.paymentUrl ?? '')), onUpdateVisitedHistory: (controller, url, androidIsReload) async { diff --git a/lib/ui/views/arif_pay/arif_pay_viewmodel.dart b/lib/ui/views/payment/payment_viewmodel.dart similarity index 80% rename from lib/ui/views/arif_pay/arif_pay_viewmodel.dart rename to lib/ui/views/payment/payment_viewmodel.dart index 9aa4457..71896ed 100644 --- a/lib/ui/views/arif_pay/arif_pay_viewmodel.dart +++ b/lib/ui/views/payment/payment_viewmodel.dart @@ -1,17 +1,17 @@ import 'package:stacked/stacked.dart'; import 'package:stacked_services/stacked_services.dart'; -import 'package:yimaru_app/ui/common/enmus.dart'; import '../../../app/app.locator.dart'; import '../../../app/app.router.dart'; +import '../../../models/learn_subscription.dart'; import '../../../models/learn_subscription_request.dart'; import '../../../models/user.dart'; import '../../../services/api_service.dart'; import '../../../services/authentication_service.dart'; import '../../../services/status_checker_service.dart'; -import '../../common/ui_helpers.dart'; +import '../../common/enmus.dart'; -class ArifPayViewModel extends ReactiveViewModel { +class PaymentViewModel extends ReactiveViewModel { // Dependency injection final _apiService = locator(); @@ -30,6 +30,7 @@ class ArifPayViewModel extends ReactiveViewModel { User? get _user => _authenticationService.user; User? get user => _user; + // Learn subscription request LearnSubscriptionRequest? _request; @@ -44,18 +45,18 @@ class ArifPayViewModel extends ReactiveViewModel { // Remote api call // Learn subscription - Future createLearnSubscriptionRequest(String phone) async => - await runBusyFuture(_createLearnSubscriptionRequest(phone), + Future createLearnSubscriptionRequest({required String phone,required LearnSubscription subscription}) async => + await runBusyFuture(_createLearnSubscriptionRequest(phone: phone,subscription: subscription), busyObject: StateObjects.learnSubscription); - Future _createLearnSubscriptionRequest(String phone) async { - print('MY SUMMARIES : PAYMENT'); + Future _createLearnSubscriptionRequest({required String phone,required LearnSubscription subscription}) async { if (await _statusChecker.checkConnection()) { Map data = { - 'plan_id': 1, 'provider': 'CHAPA', 'phone': '251$phone', 'email': 'test@gmail.com', + 'plan_id': subscription.id, + }; Map response = diff --git a/lib/ui/widgets/course_module_tile_large.dart b/lib/ui/widgets/course_module_tile_large.dart index dda641d..78ad57b 100644 --- a/lib/ui/widgets/course_module_tile_large.dart +++ b/lib/ui/widgets/course_module_tile_large.dart @@ -183,7 +183,7 @@ class CourseModuleTileLarge extends ViewModelWidget { Widget _buildSheet(CourseModuleViewModel viewModel) => FinishPracticeSheet( onTap: viewModel.pop, - practice: PracticeReason.lesson, + practice: PracticeReason.lesson, ); Widget _buildCourseModules(CourseModuleViewModel viewModel) => diff --git a/lib/ui/widgets/learn_course_tile.dart b/lib/ui/widgets/learn_course_tile.dart index 0fb0cad..dab8d41 100644 --- a/lib/ui/widgets/learn_course_tile.dart +++ b/lib/ui/widgets/learn_course_tile.dart @@ -26,11 +26,11 @@ class LearnCourseTile extends ViewModelWidget { Widget build(BuildContext context, LearnCourseViewModel viewModel) => _buildExpansionTileCardWrapper(viewModel); - - Widget _buildExpansionTileCardWrapper(LearnCourseViewModel viewModel)=> GestureDetector( - onTap: !(course.access?.isAccessible ?? false) ? onPracticeTap:null, - child: _buildExpansionTileCard(viewModel), - ); + Widget _buildExpansionTileCardWrapper(LearnCourseViewModel viewModel) => + GestureDetector( + onTap: !(course.access?.isAccessible ?? false) ? onPracticeTap : null, + child: _buildExpansionTileCard(viewModel), + ); Widget _buildExpansionTileCard(LearnCourseViewModel viewModel) => Container( margin: const EdgeInsets.only(bottom: 15), diff --git a/lib/ui/widgets/learn_module_tile.dart b/lib/ui/widgets/learn_module_tile.dart index 4fd08ff..24b6dd7 100644 --- a/lib/ui/widgets/learn_module_tile.dart +++ b/lib/ui/widgets/learn_module_tile.dart @@ -25,11 +25,13 @@ class LearnModuleTile extends ViewModelWidget { Widget build(BuildContext context, LearnModuleViewModel viewModel) => _buildExpansionTileCardWrapper(context: context, viewModel: viewModel); - Widget _buildExpansionTileCardWrapper( {required BuildContext context, - required LearnModuleViewModel viewModel})=> GestureDetector( - onTap: !(module.access?.isAccessible ?? false) ? onPracticeTap:null, - child: _buildExpansionTileCard(context: context,viewModel: viewModel), - ); + Widget _buildExpansionTileCardWrapper( + {required BuildContext context, + required LearnModuleViewModel viewModel}) => + GestureDetector( + onTap: !(module.access?.isAccessible ?? false) ? onPracticeTap : null, + child: _buildExpansionTileCard(context: context, viewModel: viewModel), + ); Widget _buildExpansionTileCard( {required BuildContext context, required LearnModuleViewModel viewModel}) => diff --git a/pubspec.yaml b/pubspec.yaml index fb1600d..d56ad63 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: yimaru_app -version: 0.1.29+31 +version: 0.1.30+32 publish_to: 'none' description: A new Flutter project. diff --git a/test/viewmodels/arif_pay_viewmodel_test.dart b/test/viewmodels/payment_viewmodel_test.dart similarity index 85% rename from test/viewmodels/arif_pay_viewmodel_test.dart rename to test/viewmodels/payment_viewmodel_test.dart index e0d875e..7753ade 100644 --- a/test/viewmodels/arif_pay_viewmodel_test.dart +++ b/test/viewmodels/payment_viewmodel_test.dart @@ -4,7 +4,7 @@ import 'package:yimaru_app/app/app.locator.dart'; import '../helpers/test_helpers.dart'; void main() { - group('ArifPayViewModel Tests -', () { + group('PaymentViewModel Tests -', () { setUp(() => registerServices()); tearDown(() => locator.reset()); });