From 6f2c0e2efea68fc26e7c21acfae130f0894a2e65 Mon Sep 17 00:00:00 2001 From: ken-morel Date: Sat, 12 Jul 2025 00:08:34 +0100 Subject: [PATCH 1/5] Extracted translation strings --- lib/l10n/app_en.arb | 44 +++-- lib/l10n/app_fr.arb | 44 +++-- lib/l10n/app_localizations.dart | 216 +++++++++++++++-------- lib/l10n/app_localizations_en.dart | 99 +++++++---- lib/l10n/app_localizations_fr.dart | 101 +++++++---- lib/pages/dashboard/blank/dashboard.dart | 9 +- lib/pages/dashboard/dashboard.dart | 8 +- lib/pages/home.dart | 2 +- lib/pages/school/explore.dart | 8 +- lib/pages/sign/signup/terms.dart | 8 +- 10 files changed, 347 insertions(+), 192 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index ac377ac..764f4ef 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,36 +1,46 @@ { - "sloganShort": "Empowering connections, empowering futures", - "emailAddress": "Email address", - "optionalInformations": "Optional information", - "reenterPassword": "Reenter password", + "acceptContinue": "Accept & Continue", "accountCreatedSuccesfuly": "Account created succesfuly", - "waitingMessages": "We're getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...", - "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Please review and accept our terms and conditions to continue.", - "signupAssistant_phoneNumberError": "Phone number should be 9 digits long (without country code)", "loadingTerms": "Loading terms of service", - "homeLoadingMessages": "Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...", "passwordsDoNotMatch": "Password do not match", + "noSchoolFound": "No school found", + "nothingHere": "Nothing here", + "errorLoadingYourDashboard": "Error loading your dashboard", + "fullName": "Full name", + "welcomeToIS": "Welcome to IS", + "wasNotTranslated": "Was not translated", + "sloganShort": "Empowering connections, empowering futures", + "optionalInformations": "Optional information", + "waitingMessages": "We're getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...", "openDashboard": "Open dashboard", - "username": "Username", + "editPreferences": "Edit Preferences", "addEmailaoPhoneNumber": "Add email and/or phone number", - "loginInformations": "Login information", "usernameDesc": "A short public name visible by others", "usernameMustHaveBetween4And20Characters": "Username must have between 3 and 20 characters", "helloWorldOfThings": "hello world of things", "password": "Password", + "connectAccount": "Connect account", + "continueGt": "Continue >", + "emailAddress": "Email address", + "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Please review and accept our terms and conditions to continue.", + "signupAssistant_phoneNumberError": "Phone number should be 9 digits long (without country code)", + "homeLoadingMessages": "Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...", + "browseSchools": "Browse Schools", "thisUsernameIsAlreadyTaken": "This username is already taken", - "fullName": "Full name", "creatingYourAccount": "Creating you account", - "welcomeToIS": "Welcome to IS", - "welcomeConnectOrCreateAccount": "Connect an existing account or create a new one to embark on your journey with us", - "connectAccount": "Connect account", "welcomeExcl": "Welcome!", + "errorLoadingTerms": "Error loading terms of service", + "areWeGoing": "Are we going?", + "editProfile": "Edit Profile", + "reenterPassword": "Reenter password", + "username": "Username", + "loginInformations": "Login information", + "exploreSchools": "Explore Schools", + "iHaveReadAndAgreeToTheTermsAndConditions": "I have read and agree to the terms and conditions.", + "welcomeConnectOrCreateAccount": "Connect an existing account or create a new one to embark on your journey with us", "phoneNumber": "Phone number", "termsAndConditions": "Terms and Conditions", - "continueGt": "Continue >", "passwordShouldHaveAtleast8Characters": "Password should have atleast 8 characters length", "createAccount": "Create an account", - "errorLoadingTerms": "Error loading terms of service", - "wasNotTranslated": "Was not translated", "retry": "Retry" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 7f4f638..aa40e40 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1,36 +1,46 @@ { - "sloganShort": "Construire des liens puissants, bâtir des avenirs prometteurs", - "emailAddress": "Addresse email", - "optionalInformations": "Informations optionelles", - "reenterPassword": "Re-entrez votre mot de passe", + "acceptContinue": "Accept & Continue", "accountCreatedSuccesfuly": "Compte cree avec succes", - "waitingMessages": "Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d'attente...", - "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "#Please review and accept our terms and conditions to continue.", - "signupAssistant_phoneNumberError": "Le numero devrais faire 9 chiffres de long (Sans code iso)", "loadingTerms": "#Loading terms of service", - "homeLoadingMessages": "Verification des details d'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...", "passwordsDoNotMatch": "Les mot-de-passe ne coincident pas", + "noSchoolFound": "No school found", + "nothingHere": "Nothing here", + "errorLoadingYourDashboard": "Error loading your dashboard", + "fullName": "Nom complet", + "welcomeToIS": "Bienvenue sur IS", + "wasNotTranslated": "#Was not translated", + "sloganShort": "Construire des liens puissants, bâtir des avenirs prometteurs", + "optionalInformations": "Informations optionelles", + "waitingMessages": "Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d'attente...", "openDashboard": "Ouvrir le tableaux de bord", - "username": "Nom d'utilisateur", + "editPreferences": "Edit Preferences", "addEmailaoPhoneNumber": "Renseigner une addresse email et/ou numero de telephone", - "loginInformations": "Informations de connection", "usernameDesc": "Un surnom court, et visible des autres", "usernameMustHaveBetween4And20Characters": "Le nom d'utilisateur doit faire entre 3 et 20 characteres de long", "helloWorldOfThings": "hello world of things", "password": "Mot de passe", + "connectAccount": "Connectez votre compte", + "continueGt": "Continuer >", + "emailAddress": "Addresse email", + "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "#Please review and accept our terms and conditions to continue.", + "signupAssistant_phoneNumberError": "Le numero devrais faire 9 chiffres de long (Sans code iso)", + "homeLoadingMessages": "Verification des details d'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...", + "browseSchools": "Browse Schools", "thisUsernameIsAlreadyTaken": "Ce nom d'utilisateur est deja prit", - "fullName": "Nom complet", "creatingYourAccount": "Nous creons votre compte", - "welcomeToIS": "Bienvenue sur IS", - "welcomeConnectOrCreateAccount": "Connectez un compte existant ou creez en un nouveau pour utiliser IS", - "connectAccount": "Connectez votre compte", "welcomeExcl": "Bienvenue!", + "errorLoadingTerms": "#Error loading terms of service", + "areWeGoing": "Are we going?", + "editProfile": "Edit Profile", + "reenterPassword": "Re-entrez votre mot de passe", + "username": "Nom d'utilisateur", + "loginInformations": "Informations de connection", + "exploreSchools": "Explore Schools", + "iHaveReadAndAgreeToTheTermsAndConditions": "I have read and agree to the terms and conditions.", + "welcomeConnectOrCreateAccount": "Connectez un compte existant ou creez en un nouveau pour utiliser IS", "phoneNumber": "Numero de telephone", "termsAndConditions": "#Terms and Conditions", - "continueGt": "Continuer >", "passwordShouldHaveAtleast8Characters": "Le mot-de-passe doit faire au moins 8 characteres de long", "createAccount": "Creez un compte", - "errorLoadingTerms": "#Error loading terms of service", - "wasNotTranslated": "#Was not translated", "retry": "Reessayer" } diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index a720699..ed59231 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -98,71 +98,83 @@ abstract class AppLocalizations { Locale('fr'), ]; - /// No description provided for @sloganShort. + /// No description provided for @acceptContinue. /// /// In en, this message translates to: - /// **'Empowering connections, empowering futures'** - String get sloganShort; + /// **'Accept & Continue'** + String get acceptContinue; - /// No description provided for @emailAddress. + /// No description provided for @accountCreatedSuccesfuly. /// /// In en, this message translates to: - /// **'Email address'** - String get emailAddress; + /// **'Account created succesfuly'** + String get accountCreatedSuccesfuly; - /// No description provided for @optionalInformations. + /// No description provided for @loadingTerms. /// /// In en, this message translates to: - /// **'Optional information'** - String get optionalInformations; + /// **'Loading terms of service'** + String get loadingTerms; - /// No description provided for @reenterPassword. + /// No description provided for @passwordsDoNotMatch. /// /// In en, this message translates to: - /// **'Reenter password'** - String get reenterPassword; + /// **'Password do not match'** + String get passwordsDoNotMatch; - /// No description provided for @accountCreatedSuccesfuly. + /// No description provided for @noSchoolFound. /// /// In en, this message translates to: - /// **'Account created succesfuly'** - String get accountCreatedSuccesfuly; + /// **'No school found'** + String get noSchoolFound; - /// No description provided for @waitingMessages. + /// No description provided for @nothingHere. /// /// In en, this message translates to: - /// **'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'** - String get waitingMessages; + /// **'Nothing here'** + String get nothingHere; - /// No description provided for @pleaseReviewAndAcceptOurTermsAndConditionsToContinue. + /// No description provided for @errorLoadingYourDashboard. /// /// In en, this message translates to: - /// **'Please review and accept our terms and conditions to continue.'** - String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue; + /// **'Error loading your dashboard'** + String get errorLoadingYourDashboard; - /// No description provided for @signupAssistant_phoneNumberError. + /// No description provided for @fullName. /// /// In en, this message translates to: - /// **'Phone number should be 9 digits long (without country code)'** - String get signupAssistant_phoneNumberError; + /// **'Full name'** + String get fullName; - /// No description provided for @loadingTerms. + /// No description provided for @welcomeToIS. /// /// In en, this message translates to: - /// **'Loading terms of service'** - String get loadingTerms; + /// **'Welcome to IS'** + String get welcomeToIS; - /// No description provided for @homeLoadingMessages. + /// No description provided for @wasNotTranslated. /// /// In en, this message translates to: - /// **'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'** - String get homeLoadingMessages; + /// **'Was not translated'** + String get wasNotTranslated; - /// No description provided for @passwordsDoNotMatch. + /// No description provided for @sloganShort. /// /// In en, this message translates to: - /// **'Password do not match'** - String get passwordsDoNotMatch; + /// **'Empowering connections, empowering futures'** + String get sloganShort; + + /// No description provided for @optionalInformations. + /// + /// In en, this message translates to: + /// **'Optional information'** + String get optionalInformations; + + /// No description provided for @waitingMessages. + /// + /// In en, this message translates to: + /// **'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'** + String get waitingMessages; /// No description provided for @openDashboard. /// @@ -170,11 +182,11 @@ abstract class AppLocalizations { /// **'Open dashboard'** String get openDashboard; - /// No description provided for @username. + /// No description provided for @editPreferences. /// /// In en, this message translates to: - /// **'Username'** - String get username; + /// **'Edit Preferences'** + String get editPreferences; /// No description provided for @addEmailaoPhoneNumber. /// @@ -182,12 +194,6 @@ abstract class AppLocalizations { /// **'Add email and/or phone number'** String get addEmailaoPhoneNumber; - /// No description provided for @loginInformations. - /// - /// In en, this message translates to: - /// **'Login information'** - String get loginInformations; - /// No description provided for @usernameDesc. /// /// In en, this message translates to: @@ -212,41 +218,59 @@ abstract class AppLocalizations { /// **'Password'** String get password; - /// No description provided for @thisUsernameIsAlreadyTaken. + /// No description provided for @connectAccount. /// /// In en, this message translates to: - /// **'This username is already taken'** - String get thisUsernameIsAlreadyTaken; + /// **'Connect account'** + String get connectAccount; - /// No description provided for @fullName. + /// No description provided for @continueGt. /// /// In en, this message translates to: - /// **'Full name'** - String get fullName; + /// **'Continue >'** + String get continueGt; - /// No description provided for @creatingYourAccount. + /// No description provided for @emailAddress. /// /// In en, this message translates to: - /// **'Creating you account'** - String get creatingYourAccount; + /// **'Email address'** + String get emailAddress; - /// No description provided for @welcomeToIS. + /// No description provided for @pleaseReviewAndAcceptOurTermsAndConditionsToContinue. /// /// In en, this message translates to: - /// **'Welcome to IS'** - String get welcomeToIS; + /// **'Please review and accept our terms and conditions to continue.'** + String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue; - /// No description provided for @welcomeConnectOrCreateAccount. + /// No description provided for @signupAssistant_phoneNumberError. /// /// In en, this message translates to: - /// **'Connect an existing account or create a new one to embark on your journey with us'** - String get welcomeConnectOrCreateAccount; + /// **'Phone number should be 9 digits long (without country code)'** + String get signupAssistant_phoneNumberError; - /// No description provided for @connectAccount. + /// No description provided for @homeLoadingMessages. /// /// In en, this message translates to: - /// **'Connect account'** - String get connectAccount; + /// **'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'** + String get homeLoadingMessages; + + /// No description provided for @browseSchools. + /// + /// In en, this message translates to: + /// **'Browse Schools'** + String get browseSchools; + + /// No description provided for @thisUsernameIsAlreadyTaken. + /// + /// In en, this message translates to: + /// **'This username is already taken'** + String get thisUsernameIsAlreadyTaken; + + /// No description provided for @creatingYourAccount. + /// + /// In en, this message translates to: + /// **'Creating you account'** + String get creatingYourAccount; /// No description provided for @welcomeExcl. /// @@ -254,6 +278,60 @@ abstract class AppLocalizations { /// **'Welcome!'** String get welcomeExcl; + /// No description provided for @errorLoadingTerms. + /// + /// In en, this message translates to: + /// **'Error loading terms of service'** + String get errorLoadingTerms; + + /// No description provided for @areWeGoing. + /// + /// In en, this message translates to: + /// **'Are we going?'** + String get areWeGoing; + + /// No description provided for @editProfile. + /// + /// In en, this message translates to: + /// **'Edit Profile'** + String get editProfile; + + /// No description provided for @reenterPassword. + /// + /// In en, this message translates to: + /// **'Reenter password'** + String get reenterPassword; + + /// No description provided for @username. + /// + /// In en, this message translates to: + /// **'Username'** + String get username; + + /// No description provided for @loginInformations. + /// + /// In en, this message translates to: + /// **'Login information'** + String get loginInformations; + + /// No description provided for @exploreSchools. + /// + /// In en, this message translates to: + /// **'Explore Schools'** + String get exploreSchools; + + /// No description provided for @iHaveReadAndAgreeToTheTermsAndConditions. + /// + /// In en, this message translates to: + /// **'I have read and agree to the terms and conditions.'** + String get iHaveReadAndAgreeToTheTermsAndConditions; + + /// No description provided for @welcomeConnectOrCreateAccount. + /// + /// In en, this message translates to: + /// **'Connect an existing account or create a new one to embark on your journey with us'** + String get welcomeConnectOrCreateAccount; + /// No description provided for @phoneNumber. /// /// In en, this message translates to: @@ -266,12 +344,6 @@ abstract class AppLocalizations { /// **'Terms and Conditions'** String get termsAndConditions; - /// No description provided for @continueGt. - /// - /// In en, this message translates to: - /// **'Continue >'** - String get continueGt; - /// No description provided for @passwordShouldHaveAtleast8Characters. /// /// In en, this message translates to: @@ -284,18 +356,6 @@ abstract class AppLocalizations { /// **'Create an account'** String get createAccount; - /// No description provided for @errorLoadingTerms. - /// - /// In en, this message translates to: - /// **'Error loading terms of service'** - String get errorLoadingTerms; - - /// No description provided for @wasNotTranslated. - /// - /// In en, this message translates to: - /// **'Was not translated'** - String get wasNotTranslated; - /// No description provided for @retry. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 4da7529..692ca82 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -9,53 +9,53 @@ class AppLocalizationsEn extends AppLocalizations { AppLocalizationsEn([String locale = 'en']) : super(locale); @override - String get sloganShort => 'Empowering connections, empowering futures'; + String get acceptContinue => 'Accept & Continue'; @override - String get emailAddress => 'Email address'; + String get accountCreatedSuccesfuly => 'Account created succesfuly'; @override - String get optionalInformations => 'Optional information'; + String get loadingTerms => 'Loading terms of service'; @override - String get reenterPassword => 'Reenter password'; + String get passwordsDoNotMatch => 'Password do not match'; @override - String get accountCreatedSuccesfuly => 'Account created succesfuly'; + String get noSchoolFound => 'No school found'; @override - String get waitingMessages => - 'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'; + String get nothingHere => 'Nothing here'; @override - String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => - 'Please review and accept our terms and conditions to continue.'; + String get errorLoadingYourDashboard => 'Error loading your dashboard'; @override - String get signupAssistant_phoneNumberError => - 'Phone number should be 9 digits long (without country code)'; + String get fullName => 'Full name'; @override - String get loadingTerms => 'Loading terms of service'; + String get welcomeToIS => 'Welcome to IS'; @override - String get homeLoadingMessages => - 'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'; + String get wasNotTranslated => 'Was not translated'; @override - String get passwordsDoNotMatch => 'Password do not match'; + String get sloganShort => 'Empowering connections, empowering futures'; @override - String get openDashboard => 'Open dashboard'; + String get optionalInformations => 'Optional information'; @override - String get username => 'Username'; + String get waitingMessages => + 'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'; @override - String get addEmailaoPhoneNumber => 'Add email and/or phone number'; + String get openDashboard => 'Open dashboard'; @override - String get loginInformations => 'Login information'; + String get editPreferences => 'Edit Preferences'; + + @override + String get addEmailaoPhoneNumber => 'Add email and/or phone number'; @override String get usernameDesc => 'A short public name visible by others'; @@ -71,48 +71,79 @@ class AppLocalizationsEn extends AppLocalizations { String get password => 'Password'; @override - String get thisUsernameIsAlreadyTaken => 'This username is already taken'; + String get connectAccount => 'Connect account'; @override - String get fullName => 'Full name'; + String get continueGt => 'Continue >'; @override - String get creatingYourAccount => 'Creating you account'; + String get emailAddress => 'Email address'; @override - String get welcomeToIS => 'Welcome to IS'; + String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => + 'Please review and accept our terms and conditions to continue.'; @override - String get welcomeConnectOrCreateAccount => - 'Connect an existing account or create a new one to embark on your journey with us'; + String get signupAssistant_phoneNumberError => + 'Phone number should be 9 digits long (without country code)'; @override - String get connectAccount => 'Connect account'; + String get homeLoadingMessages => + 'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'; + + @override + String get browseSchools => 'Browse Schools'; + + @override + String get thisUsernameIsAlreadyTaken => 'This username is already taken'; + + @override + String get creatingYourAccount => 'Creating you account'; @override String get welcomeExcl => 'Welcome!'; @override - String get phoneNumber => 'Phone number'; + String get errorLoadingTerms => 'Error loading terms of service'; @override - String get termsAndConditions => 'Terms and Conditions'; + String get areWeGoing => 'Are we going?'; @override - String get continueGt => 'Continue >'; + String get editProfile => 'Edit Profile'; @override - String get passwordShouldHaveAtleast8Characters => - 'Password should have atleast 8 characters length'; + String get reenterPassword => 'Reenter password'; @override - String get createAccount => 'Create an account'; + String get username => 'Username'; @override - String get errorLoadingTerms => 'Error loading terms of service'; + String get loginInformations => 'Login information'; @override - String get wasNotTranslated => 'Was not translated'; + String get exploreSchools => 'Explore Schools'; + + @override + String get iHaveReadAndAgreeToTheTermsAndConditions => + 'I have read and agree to the terms and conditions.'; + + @override + String get welcomeConnectOrCreateAccount => + 'Connect an existing account or create a new one to embark on your journey with us'; + + @override + String get phoneNumber => 'Phone number'; + + @override + String get termsAndConditions => 'Terms and Conditions'; + + @override + String get passwordShouldHaveAtleast8Characters => + 'Password should have atleast 8 characters length'; + + @override + String get createAccount => 'Create an account'; @override String get retry => 'Retry'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index dbe78c4..a1e889e 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -9,56 +9,56 @@ class AppLocalizationsFr extends AppLocalizations { AppLocalizationsFr([String locale = 'fr']) : super(locale); @override - String get sloganShort => - 'Construire des liens puissants, bâtir des avenirs prometteurs'; + String get acceptContinue => 'Accept & Continue'; @override - String get emailAddress => 'Addresse email'; + String get accountCreatedSuccesfuly => 'Compte cree avec succes'; @override - String get optionalInformations => 'Informations optionelles'; + String get loadingTerms => '#Loading terms of service'; @override - String get reenterPassword => 'Re-entrez votre mot de passe'; + String get passwordsDoNotMatch => 'Les mot-de-passe ne coincident pas'; @override - String get accountCreatedSuccesfuly => 'Compte cree avec succes'; + String get noSchoolFound => 'No school found'; @override - String get waitingMessages => - 'Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d\'attente...'; + String get nothingHere => 'Nothing here'; @override - String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => - '#Please review and accept our terms and conditions to continue.'; + String get errorLoadingYourDashboard => 'Error loading your dashboard'; @override - String get signupAssistant_phoneNumberError => - 'Le numero devrais faire 9 chiffres de long (Sans code iso)'; + String get fullName => 'Nom complet'; @override - String get loadingTerms => '#Loading terms of service'; + String get welcomeToIS => 'Bienvenue sur IS'; @override - String get homeLoadingMessages => - 'Verification des details d\'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...'; + String get wasNotTranslated => '#Was not translated'; @override - String get passwordsDoNotMatch => 'Les mot-de-passe ne coincident pas'; + String get sloganShort => + 'Construire des liens puissants, bâtir des avenirs prometteurs'; + + @override + String get optionalInformations => 'Informations optionelles'; + + @override + String get waitingMessages => + 'Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d\'attente...'; @override String get openDashboard => 'Ouvrir le tableaux de bord'; @override - String get username => 'Nom d\'utilisateur'; + String get editPreferences => 'Edit Preferences'; @override String get addEmailaoPhoneNumber => 'Renseigner une addresse email et/ou numero de telephone'; - @override - String get loginInformations => 'Informations de connection'; - @override String get usernameDesc => 'Un surnom court, et visible des autres'; @@ -72,50 +72,81 @@ class AppLocalizationsFr extends AppLocalizations { @override String get password => 'Mot de passe'; + @override + String get connectAccount => 'Connectez votre compte'; + + @override + String get continueGt => 'Continuer >'; + + @override + String get emailAddress => 'Addresse email'; + + @override + String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => + '#Please review and accept our terms and conditions to continue.'; + + @override + String get signupAssistant_phoneNumberError => + 'Le numero devrais faire 9 chiffres de long (Sans code iso)'; + + @override + String get homeLoadingMessages => + 'Verification des details d\'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...'; + + @override + String get browseSchools => 'Browse Schools'; + @override String get thisUsernameIsAlreadyTaken => 'Ce nom d\'utilisateur est deja prit'; @override - String get fullName => 'Nom complet'; + String get creatingYourAccount => 'Nous creons votre compte'; @override - String get creatingYourAccount => 'Nous creons votre compte'; + String get welcomeExcl => 'Bienvenue!'; @override - String get welcomeToIS => 'Bienvenue sur IS'; + String get errorLoadingTerms => '#Error loading terms of service'; @override - String get welcomeConnectOrCreateAccount => - 'Connectez un compte existant ou creez en un nouveau pour utiliser IS'; + String get areWeGoing => 'Are we going?'; @override - String get connectAccount => 'Connectez votre compte'; + String get editProfile => 'Edit Profile'; @override - String get welcomeExcl => 'Bienvenue!'; + String get reenterPassword => 'Re-entrez votre mot de passe'; @override - String get phoneNumber => 'Numero de telephone'; + String get username => 'Nom d\'utilisateur'; @override - String get termsAndConditions => '#Terms and Conditions'; + String get loginInformations => 'Informations de connection'; @override - String get continueGt => 'Continuer >'; + String get exploreSchools => 'Explore Schools'; @override - String get passwordShouldHaveAtleast8Characters => - 'Le mot-de-passe doit faire au moins 8 characteres de long'; + String get iHaveReadAndAgreeToTheTermsAndConditions => + 'I have read and agree to the terms and conditions.'; @override - String get createAccount => 'Creez un compte'; + String get welcomeConnectOrCreateAccount => + 'Connectez un compte existant ou creez en un nouveau pour utiliser IS'; @override - String get errorLoadingTerms => '#Error loading terms of service'; + String get phoneNumber => 'Numero de telephone'; @override - String get wasNotTranslated => '#Was not translated'; + String get termsAndConditions => '#Terms and Conditions'; + + @override + String get passwordShouldHaveAtleast8Characters => + 'Le mot-de-passe doit faire au moins 8 characteres de long'; + + @override + String get createAccount => 'Creez un compte'; @override String get retry => 'Reessayer'; diff --git a/lib/pages/dashboard/blank/dashboard.dart b/lib/pages/dashboard/blank/dashboard.dart index f6e2972..588bf8e 100644 --- a/lib/pages/dashboard/blank/dashboard.dart +++ b/lib/pages/dashboard/blank/dashboard.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:ins/appstate.dart'; import 'package:ins/pages/school/explore.dart'; +import 'package:ins/l10n/app_localizations.dart'; class BlankDashboard extends StatelessWidget { final AppState appState; @@ -9,7 +10,7 @@ class BlankDashboard extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: const Text("Are we going?")), + appBar: AppBar(title: Text(AppLocalizations.of(context)!.areWeGoing)), body: Center( child: SizedBox( width: 500, @@ -19,7 +20,7 @@ class BlankDashboard extends StatelessWidget { children: [ DashboardButton( icon: Icons.edit, - text: "Edit Profile", + text: AppLocalizations.of(context)!.editProfile, color: Colors.blue, onPressed: () { // TODO: Implement edit profile functionality @@ -28,7 +29,7 @@ class BlankDashboard extends StatelessWidget { const SizedBox(height: 20), DashboardButton( icon: Icons.settings, - text: "Edit Preferences", + text: AppLocalizations.of(context)!.editPreferences, color: Colors.orange, onPressed: () { // TODO: Implement edit preferences functionality @@ -37,7 +38,7 @@ class BlankDashboard extends StatelessWidget { const SizedBox(height: 20), DashboardButton( icon: Icons.school, - text: "Browse Schools", + text: AppLocalizations.of(context)!.browseSchools, color: Colors.green, onPressed: () { Navigator.of(context).push( diff --git a/lib/pages/dashboard/dashboard.dart b/lib/pages/dashboard/dashboard.dart index 212ca13..853db46 100644 --- a/lib/pages/dashboard/dashboard.dart +++ b/lib/pages/dashboard/dashboard.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:ins/appstate.dart'; import 'blank/dashboard.dart'; +import 'package:ins/l10n/app_localizations.dart'; Future getDashboard(AppState? state) async { state ??= await AppState.load(); @@ -8,7 +9,12 @@ Future getDashboard(AppState? state) async { return BlankDashboard(appState: state); } else { return Scaffold( - appBar: AppBar(leading: BackButton(), title: Text("Nothing here")), + appBar: AppBar( + leading: BackButton(), + title: Builder( + builder: (context) => Text(AppLocalizations.of(context)!.nothingHere), + ), + ), ); } } diff --git a/lib/pages/home.dart b/lib/pages/home.dart index ffcc3dc..1398365 100644 --- a/lib/pages/home.dart +++ b/lib/pages/home.dart @@ -46,7 +46,7 @@ Widget getPage() { return _inBlank( IMsgWidget( icon: Icon(Icons.error), - message: Text("Error loading your dashboard"), + message: Text(AppLocalizations.of(context)!.errorLoadingYourDashboard), ), ); } diff --git a/lib/pages/school/explore.dart b/lib/pages/school/explore.dart index 71e77e6..ee663c4 100644 --- a/lib/pages/school/explore.dart +++ b/lib/pages/school/explore.dart @@ -5,6 +5,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:ins/appstate.dart'; import 'package:ins/widgets/loading.dart'; import 'school_profile.dart'; +import 'package:ins/l10n/app_localizations.dart'; class SchoolExplorePage extends StatefulWidget { final AppState appState; @@ -22,7 +23,10 @@ class _SchoolExplorePageState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: Text("Explore Schools"), elevation: 0), + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.exploreSchools), + elevation: 0, + ), body: FutureBuilder>( future: models.School.getAllSchools( widget.appState.session, @@ -71,7 +75,7 @@ class _SchoolExplorePageState extends State { ), SizedBox(height: 30), Text( - "No school found", + AppLocalizations.of(context)!.noSchoolFound, style: Theme.of(context).textTheme.displayLarge, ), ], diff --git a/lib/pages/sign/signup/terms.dart b/lib/pages/sign/signup/terms.dart index 904f0b4..49d1a28 100644 --- a/lib/pages/sign/signup/terms.dart +++ b/lib/pages/sign/signup/terms.dart @@ -131,8 +131,10 @@ class _TermsWidgetState extends State { ), const SizedBox(height: 16), CheckboxListTile( - title: const Text( - "I have read and agree to the terms and conditions.", + title: Text( + AppLocalizations.of( + context, + )!.iHaveReadAndAgreeToTheTermsAndConditions, ), value: _termsAccepted, onChanged: (bool? value) { @@ -162,7 +164,7 @@ class _TermsWidgetState extends State { padding: const EdgeInsets.symmetric(vertical: 16.0), textStyle: Theme.of(context).textTheme.labelLarge, ), - child: Text("Accept & Continue"), + child: Text(AppLocalizations.of(context)!.acceptContinue), ), ], ), From fdbb21e5bd91129e819465bee372ad6f4e1b105a Mon Sep 17 00:00:00 2001 From: ken-morel Date: Sat, 12 Jul 2025 00:42:01 +0100 Subject: [PATCH 2/5] Full french support --- lib/l10n/app_en.arb | 16 ++ lib/l10n/app_fr.arb | 88 ++++++---- lib/l10n/app_localizations.dart | 96 +++++++++++ lib/l10n/app_localizations_en.dart | 49 ++++++ lib/l10n/app_localizations_fr.dart | 121 ++++++++++---- lib/pages/dashboard/blank/dashboard.dart | 5 +- lib/pages/dashboard/dashboard.dart | 49 ++++++ lib/pages/school/school_profile.dart | 199 +++-------------------- lib/pages/sign/signup/extlinked.dart | 2 +- lib/pages/sign/signup/submit.dart | 7 +- lib/utils/email.dart | 28 +++- 11 files changed, 407 insertions(+), 253 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 764f4ef..d980a46 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,6 +1,8 @@ { "acceptContinue": "Accept & Continue", + "contactInformation": "Contact Information", "accountCreatedSuccesfuly": "Account created succesfuly", + "invalidDomainComponent": "Invalid domain component", "loadingTerms": "Loading terms of service", "passwordsDoNotMatch": "Password do not match", "noSchoolFound": "No school found", @@ -8,38 +10,52 @@ "errorLoadingYourDashboard": "Error loading your dashboard", "fullName": "Full name", "welcomeToIS": "Welcome to IS", + "emailShouldContain1": "Email should contain 1 '@'", "wasNotTranslated": "Was not translated", + "students": "Students", "sloganShort": "Empowering connections, empowering futures", "optionalInformations": "Optional information", "waitingMessages": "We're getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...", + "invalidEmailDomainsecondPart": "Invalid email domain(second part)", + "rating": "Rating", "openDashboard": "Open dashboard", "editPreferences": "Edit Preferences", "addEmailaoPhoneNumber": "Add email and/or phone number", + "campus": "Campus", + "applyNow": "Apply Now", "usernameDesc": "A short public name visible by others", "usernameMustHaveBetween4And20Characters": "Username must have between 3 and 20 characters", "helloWorldOfThings": "hello world of things", "password": "Password", "connectAccount": "Connect account", + "emailShouldContain": "Email should contain '@'", "continueGt": "Continue >", "emailAddress": "Email address", "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Please review and accept our terms and conditions to continue.", "signupAssistant_phoneNumberError": "Phone number should be 9 digits long (without country code)", + "online": "Online", "homeLoadingMessages": "Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...", + "atAGlance": "At a Glance", "browseSchools": "Browse Schools", "thisUsernameIsAlreadyTaken": "This username is already taken", "creatingYourAccount": "Creating you account", + "emailNameTooShort": "Email name too short", + "loadingYourDashboard": "Loading your dashboard", "welcomeExcl": "Welcome!", + "noDescriptionProvided": "No description provided.", "errorLoadingTerms": "Error loading terms of service", "areWeGoing": "Are we going?", "editProfile": "Edit Profile", "reenterPassword": "Reenter password", "username": "Username", "loginInformations": "Login information", + "invalidCharacterInEmail": "Invalid character in email ", "exploreSchools": "Explore Schools", "iHaveReadAndAgreeToTheTermsAndConditions": "I have read and agree to the terms and conditions.", "welcomeConnectOrCreateAccount": "Connect an existing account or create a new one to embark on your journey with us", "phoneNumber": "Phone number", "termsAndConditions": "Terms and Conditions", + "establishedIn2023": "Established in 2023", "passwordShouldHaveAtleast8Characters": "Password should have atleast 8 characters length", "createAccount": "Create an account", "retry": "Retry" diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index aa40e40..8d54858 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1,46 +1,62 @@ { - "acceptContinue": "Accept & Continue", - "accountCreatedSuccesfuly": "Compte cree avec succes", - "loadingTerms": "#Loading terms of service", - "passwordsDoNotMatch": "Les mot-de-passe ne coincident pas", - "noSchoolFound": "No school found", - "nothingHere": "Nothing here", - "errorLoadingYourDashboard": "Error loading your dashboard", + "acceptContinue": "Accepter & Continuer", + "contactInformation": "Informations de contact", + "accountCreatedSuccesfuly": "Compte créé avec succès", + "invalidDomainComponent": "Composant de domaine invalide", + "loadingTerms": "Chargement des conditions d'utilisation", + "passwordsDoNotMatch": "Les mots de passe ne correspondent pas", + "noSchoolFound": "Aucune école trouvée", + "nothingHere": "Rien ici", + "errorLoadingYourDashboard": "Erreur lors du chargement de votre tableau de bord", "fullName": "Nom complet", "welcomeToIS": "Bienvenue sur IS", - "wasNotTranslated": "#Was not translated", + "emailShouldContain1": "L'e-mail doit contenir un '@'", + "wasNotTranslated": "N'a pas été traduit", + "students": "Étudiants", "sloganShort": "Construire des liens puissants, bâtir des avenirs prometteurs", - "optionalInformations": "Informations optionelles", - "waitingMessages": "Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d'attente...", - "openDashboard": "Ouvrir le tableaux de bord", - "editPreferences": "Edit Preferences", - "addEmailaoPhoneNumber": "Renseigner une addresse email et/ou numero de telephone", + "optionalInformations": "Informations optionnelles", + "waitingMessages": "Nous aurons bientôt fini...|Attendez encore un peu...|Tout se passe bien...|...|Un peu plus de temps...|Quelques instants d'attente...", + "invalidEmailDomainsecondPart": "Domaine de l'e-mail invalide (deuxième partie)", + "rating": "Évaluation", + "openDashboard": "Ouvrir le tableau de bord", + "editPreferences": "Modifier les préférences", + "addEmailaoPhoneNumber": "Renseigner une adresse e-mail et/ou un numéro de téléphone", + "campus": "Campus", + "applyNow": "Postuler maintenant", "usernameDesc": "Un surnom court, et visible des autres", - "usernameMustHaveBetween4And20Characters": "Le nom d'utilisateur doit faire entre 3 et 20 characteres de long", + "usernameMustHaveBetween4And20Characters": "Le nom d'utilisateur doit contenir entre 3 et 20 caractères", "helloWorldOfThings": "hello world of things", "password": "Mot de passe", - "connectAccount": "Connectez votre compte", + "connectAccount": "Connecter votre compte", + "emailShouldContain": "L'e-mail doit contenir '@'", "continueGt": "Continuer >", - "emailAddress": "Addresse email", - "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "#Please review and accept our terms and conditions to continue.", - "signupAssistant_phoneNumberError": "Le numero devrais faire 9 chiffres de long (Sans code iso)", - "homeLoadingMessages": "Verification des details d'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...", - "browseSchools": "Browse Schools", - "thisUsernameIsAlreadyTaken": "Ce nom d'utilisateur est deja prit", - "creatingYourAccount": "Nous creons votre compte", + "emailAddress": "Adresse e-mail", + "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Veuillez consulter et accepter nos conditions d'utilisation pour continuer.", + "signupAssistant_phoneNumberError": "Le numéro de téléphone doit comporter 9 chiffres (sans l'indicatif du pays)", + "online": "En ligne", + "homeLoadingMessages": "Vérification des détails de l'utilisateur...|Acquisition des permissions de votre école...|Veuillez patienter...|Nous y sommes presque...", + "atAGlance": "En un coup d'œil", + "browseSchools": "Parcourir les écoles", + "thisUsernameIsAlreadyTaken": "Ce nom d'utilisateur est déjà pris", + "creatingYourAccount": "Création de votre compte", + "emailNameTooShort": "Nom d'e-mail trop court", + "loadingYourDashboard": "Chargement de votre tableau de bord", "welcomeExcl": "Bienvenue!", - "errorLoadingTerms": "#Error loading terms of service", - "areWeGoing": "Are we going?", - "editProfile": "Edit Profile", - "reenterPassword": "Re-entrez votre mot de passe", + "noDescriptionProvided": "Aucune description fournie.", + "errorLoadingTerms": "Erreur de chargement des conditions d'utilisation", + "areWeGoing": "On y va?", + "editProfile": "Modifier le profil", + "reenterPassword": "Retapez votre mot de passe", "username": "Nom d'utilisateur", - "loginInformations": "Informations de connection", - "exploreSchools": "Explore Schools", - "iHaveReadAndAgreeToTheTermsAndConditions": "I have read and agree to the terms and conditions.", - "welcomeConnectOrCreateAccount": "Connectez un compte existant ou creez en un nouveau pour utiliser IS", - "phoneNumber": "Numero de telephone", - "termsAndConditions": "#Terms and Conditions", - "passwordShouldHaveAtleast8Characters": "Le mot-de-passe doit faire au moins 8 characteres de long", - "createAccount": "Creez un compte", - "retry": "Reessayer" -} + "loginInformations": "Informations de connexion", + "invalidCharacterInEmail": "Caractère invalide dans l'e-mail", + "exploreSchools": "Explorer les écoles", + "iHaveReadAndAgreeToTheTermsAndConditions": "J'ai lu et j'accepte les conditions d'utilisation.", + "welcomeConnectOrCreateAccount": "Connectez un compte existant ou créez-en un nouveau pour utiliser IS", + "phoneNumber": "Numéro de téléphone", + "termsAndConditions": "Conditions d'utilisation", + "establishedIn2023": "Établi en 2023", + "passwordShouldHaveAtleast8Characters": "Le mot de passe doit contenir au moins 8 caractères", + "createAccount": "Créer un compte", + "retry": "Réessayer" +} \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index ed59231..85d0b38 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -104,12 +104,24 @@ abstract class AppLocalizations { /// **'Accept & Continue'** String get acceptContinue; + /// No description provided for @contactInformation. + /// + /// In en, this message translates to: + /// **'Contact Information'** + String get contactInformation; + /// No description provided for @accountCreatedSuccesfuly. /// /// In en, this message translates to: /// **'Account created succesfuly'** String get accountCreatedSuccesfuly; + /// No description provided for @invalidDomainComponent. + /// + /// In en, this message translates to: + /// **'Invalid domain component'** + String get invalidDomainComponent; + /// No description provided for @loadingTerms. /// /// In en, this message translates to: @@ -152,12 +164,24 @@ abstract class AppLocalizations { /// **'Welcome to IS'** String get welcomeToIS; + /// No description provided for @emailShouldContain1. + /// + /// In en, this message translates to: + /// **'Email should contain 1 \'@\''** + String get emailShouldContain1; + /// No description provided for @wasNotTranslated. /// /// In en, this message translates to: /// **'Was not translated'** String get wasNotTranslated; + /// No description provided for @students. + /// + /// In en, this message translates to: + /// **'Students'** + String get students; + /// No description provided for @sloganShort. /// /// In en, this message translates to: @@ -176,6 +200,18 @@ abstract class AppLocalizations { /// **'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'** String get waitingMessages; + /// No description provided for @invalidEmailDomainsecondPart. + /// + /// In en, this message translates to: + /// **'Invalid email domain(second part)'** + String get invalidEmailDomainsecondPart; + + /// No description provided for @rating. + /// + /// In en, this message translates to: + /// **'Rating'** + String get rating; + /// No description provided for @openDashboard. /// /// In en, this message translates to: @@ -194,6 +230,18 @@ abstract class AppLocalizations { /// **'Add email and/or phone number'** String get addEmailaoPhoneNumber; + /// No description provided for @campus. + /// + /// In en, this message translates to: + /// **'Campus'** + String get campus; + + /// No description provided for @applyNow. + /// + /// In en, this message translates to: + /// **'Apply Now'** + String get applyNow; + /// No description provided for @usernameDesc. /// /// In en, this message translates to: @@ -224,6 +272,12 @@ abstract class AppLocalizations { /// **'Connect account'** String get connectAccount; + /// No description provided for @emailShouldContain. + /// + /// In en, this message translates to: + /// **'Email should contain \'@\''** + String get emailShouldContain; + /// No description provided for @continueGt. /// /// In en, this message translates to: @@ -248,12 +302,24 @@ abstract class AppLocalizations { /// **'Phone number should be 9 digits long (without country code)'** String get signupAssistant_phoneNumberError; + /// No description provided for @online. + /// + /// In en, this message translates to: + /// **'Online'** + String get online; + /// No description provided for @homeLoadingMessages. /// /// In en, this message translates to: /// **'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'** String get homeLoadingMessages; + /// No description provided for @atAGlance. + /// + /// In en, this message translates to: + /// **'At a Glance'** + String get atAGlance; + /// No description provided for @browseSchools. /// /// In en, this message translates to: @@ -272,12 +338,30 @@ abstract class AppLocalizations { /// **'Creating you account'** String get creatingYourAccount; + /// No description provided for @emailNameTooShort. + /// + /// In en, this message translates to: + /// **'Email name too short'** + String get emailNameTooShort; + + /// No description provided for @loadingYourDashboard. + /// + /// In en, this message translates to: + /// **'Loading your dashboard'** + String get loadingYourDashboard; + /// No description provided for @welcomeExcl. /// /// In en, this message translates to: /// **'Welcome!'** String get welcomeExcl; + /// No description provided for @noDescriptionProvided. + /// + /// In en, this message translates to: + /// **'No description provided.'** + String get noDescriptionProvided; + /// No description provided for @errorLoadingTerms. /// /// In en, this message translates to: @@ -314,6 +398,12 @@ abstract class AppLocalizations { /// **'Login information'** String get loginInformations; + /// No description provided for @invalidCharacterInEmail. + /// + /// In en, this message translates to: + /// **'Invalid character in email '** + String get invalidCharacterInEmail; + /// No description provided for @exploreSchools. /// /// In en, this message translates to: @@ -344,6 +434,12 @@ abstract class AppLocalizations { /// **'Terms and Conditions'** String get termsAndConditions; + /// No description provided for @establishedIn2023. + /// + /// In en, this message translates to: + /// **'Established in 2023'** + String get establishedIn2023; + /// No description provided for @passwordShouldHaveAtleast8Characters. /// /// In en, this message translates to: diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index 692ca82..a9bb807 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -11,9 +11,15 @@ class AppLocalizationsEn extends AppLocalizations { @override String get acceptContinue => 'Accept & Continue'; + @override + String get contactInformation => 'Contact Information'; + @override String get accountCreatedSuccesfuly => 'Account created succesfuly'; + @override + String get invalidDomainComponent => 'Invalid domain component'; + @override String get loadingTerms => 'Loading terms of service'; @@ -35,9 +41,15 @@ class AppLocalizationsEn extends AppLocalizations { @override String get welcomeToIS => 'Welcome to IS'; + @override + String get emailShouldContain1 => 'Email should contain 1 \'@\''; + @override String get wasNotTranslated => 'Was not translated'; + @override + String get students => 'Students'; + @override String get sloganShort => 'Empowering connections, empowering futures'; @@ -48,6 +60,13 @@ class AppLocalizationsEn extends AppLocalizations { String get waitingMessages => 'We\'re getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...'; + @override + String get invalidEmailDomainsecondPart => + 'Invalid email domain(second part)'; + + @override + String get rating => 'Rating'; + @override String get openDashboard => 'Open dashboard'; @@ -57,6 +76,12 @@ class AppLocalizationsEn extends AppLocalizations { @override String get addEmailaoPhoneNumber => 'Add email and/or phone number'; + @override + String get campus => 'Campus'; + + @override + String get applyNow => 'Apply Now'; + @override String get usernameDesc => 'A short public name visible by others'; @@ -73,6 +98,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get connectAccount => 'Connect account'; + @override + String get emailShouldContain => 'Email should contain \'@\''; + @override String get continueGt => 'Continue >'; @@ -87,10 +115,16 @@ class AppLocalizationsEn extends AppLocalizations { String get signupAssistant_phoneNumberError => 'Phone number should be 9 digits long (without country code)'; + @override + String get online => 'Online'; + @override String get homeLoadingMessages => 'Loading app state...|Verifying user details...|Getting permissions from your schools..|Verifying the age on your birth certificate...|Please wait...|Almost there...'; + @override + String get atAGlance => 'At a Glance'; + @override String get browseSchools => 'Browse Schools'; @@ -100,9 +134,18 @@ class AppLocalizationsEn extends AppLocalizations { @override String get creatingYourAccount => 'Creating you account'; + @override + String get emailNameTooShort => 'Email name too short'; + + @override + String get loadingYourDashboard => 'Loading your dashboard'; + @override String get welcomeExcl => 'Welcome!'; + @override + String get noDescriptionProvided => 'No description provided.'; + @override String get errorLoadingTerms => 'Error loading terms of service'; @@ -121,6 +164,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get loginInformations => 'Login information'; + @override + String get invalidCharacterInEmail => 'Invalid character in email '; + @override String get exploreSchools => 'Explore Schools'; @@ -138,6 +184,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get termsAndConditions => 'Terms and Conditions'; + @override + String get establishedIn2023 => 'Established in 2023'; + @override String get passwordShouldHaveAtleast8Characters => 'Password should have atleast 8 characters length'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index a1e889e..a3c84de 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -9,25 +9,32 @@ class AppLocalizationsFr extends AppLocalizations { AppLocalizationsFr([String locale = 'fr']) : super(locale); @override - String get acceptContinue => 'Accept & Continue'; + String get acceptContinue => 'Accepter & Continuer'; @override - String get accountCreatedSuccesfuly => 'Compte cree avec succes'; + String get contactInformation => 'Informations de contact'; @override - String get loadingTerms => '#Loading terms of service'; + String get accountCreatedSuccesfuly => 'Compte créé avec succès'; @override - String get passwordsDoNotMatch => 'Les mot-de-passe ne coincident pas'; + String get invalidDomainComponent => 'Composant de domaine invalide'; @override - String get noSchoolFound => 'No school found'; + String get loadingTerms => 'Chargement des conditions d\'utilisation'; @override - String get nothingHere => 'Nothing here'; + String get passwordsDoNotMatch => 'Les mots de passe ne correspondent pas'; @override - String get errorLoadingYourDashboard => 'Error loading your dashboard'; + String get noSchoolFound => 'Aucune école trouvée'; + + @override + String get nothingHere => 'Rien ici'; + + @override + String get errorLoadingYourDashboard => + 'Erreur lors du chargement de votre tableau de bord'; @override String get fullName => 'Nom complet'; @@ -36,35 +43,54 @@ class AppLocalizationsFr extends AppLocalizations { String get welcomeToIS => 'Bienvenue sur IS'; @override - String get wasNotTranslated => '#Was not translated'; + String get emailShouldContain1 => 'L\'e-mail doit contenir un \'@\''; + + @override + String get wasNotTranslated => 'N\'a pas été traduit'; + + @override + String get students => 'Étudiants'; @override String get sloganShort => 'Construire des liens puissants, bâtir des avenirs prometteurs'; @override - String get optionalInformations => 'Informations optionelles'; + String get optionalInformations => 'Informations optionnelles'; @override String get waitingMessages => - 'Nous ourons bientot fini...|Attendez encore un peu...|Tout ce passe bien...|...|Un peu plus de temps...|Quelques instants d\'attente...'; + 'Nous aurons bientôt fini...|Attendez encore un peu...|Tout se passe bien...|...|Un peu plus de temps...|Quelques instants d\'attente...'; @override - String get openDashboard => 'Ouvrir le tableaux de bord'; + String get invalidEmailDomainsecondPart => + 'Domaine de l\'e-mail invalide (deuxième partie)'; @override - String get editPreferences => 'Edit Preferences'; + String get rating => 'Évaluation'; + + @override + String get openDashboard => 'Ouvrir le tableau de bord'; + + @override + String get editPreferences => 'Modifier les préférences'; @override String get addEmailaoPhoneNumber => - 'Renseigner une addresse email et/ou numero de telephone'; + 'Renseigner une adresse e-mail et/ou un numéro de téléphone'; + + @override + String get campus => 'Campus'; + + @override + String get applyNow => 'Postuler maintenant'; @override String get usernameDesc => 'Un surnom court, et visible des autres'; @override String get usernameMustHaveBetween4And20Characters => - 'Le nom d\'utilisateur doit faire entre 3 et 20 characteres de long'; + 'Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'; @override String get helloWorldOfThings => 'hello world of things'; @@ -73,81 +99,106 @@ class AppLocalizationsFr extends AppLocalizations { String get password => 'Mot de passe'; @override - String get connectAccount => 'Connectez votre compte'; + String get connectAccount => 'Connecter votre compte'; + + @override + String get emailShouldContain => 'L\'e-mail doit contenir \'@\''; @override String get continueGt => 'Continuer >'; @override - String get emailAddress => 'Addresse email'; + String get emailAddress => 'Adresse e-mail'; @override String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => - '#Please review and accept our terms and conditions to continue.'; + 'Veuillez consulter et accepter nos conditions d\'utilisation pour continuer.'; @override String get signupAssistant_phoneNumberError => - 'Le numero devrais faire 9 chiffres de long (Sans code iso)'; + 'Le numéro de téléphone doit comporter 9 chiffres (sans l\'indicatif du pays)'; + + @override + String get online => 'En ligne'; @override String get homeLoadingMessages => - 'Verification des details d\'utilisateur...|Acquisition de permission de votre ecole..|Veuillez patienter...|Nous y sommes presque...'; + 'Vérification des détails de l\'utilisateur...|Acquisition des permissions de votre école...|Veuillez patienter...|Nous y sommes presque...'; @override - String get browseSchools => 'Browse Schools'; + String get atAGlance => 'En un coup d\'œil'; + + @override + String get browseSchools => 'Parcourir les écoles'; @override String get thisUsernameIsAlreadyTaken => - 'Ce nom d\'utilisateur est deja prit'; + 'Ce nom d\'utilisateur est déjà pris'; + + @override + String get creatingYourAccount => 'Création de votre compte'; @override - String get creatingYourAccount => 'Nous creons votre compte'; + String get emailNameTooShort => 'Nom d\'e-mail trop court'; + + @override + String get loadingYourDashboard => 'Chargement de votre tableau de bord'; @override String get welcomeExcl => 'Bienvenue!'; @override - String get errorLoadingTerms => '#Error loading terms of service'; + String get noDescriptionProvided => 'Aucune description fournie.'; + + @override + String get errorLoadingTerms => + 'Erreur de chargement des conditions d\'utilisation'; @override - String get areWeGoing => 'Are we going?'; + String get areWeGoing => 'On y va?'; @override - String get editProfile => 'Edit Profile'; + String get editProfile => 'Modifier le profil'; @override - String get reenterPassword => 'Re-entrez votre mot de passe'; + String get reenterPassword => 'Retapez votre mot de passe'; @override String get username => 'Nom d\'utilisateur'; @override - String get loginInformations => 'Informations de connection'; + String get loginInformations => 'Informations de connexion'; @override - String get exploreSchools => 'Explore Schools'; + String get invalidCharacterInEmail => 'Caractère invalide dans l\'e-mail'; + + @override + String get exploreSchools => 'Explorer les écoles'; @override String get iHaveReadAndAgreeToTheTermsAndConditions => - 'I have read and agree to the terms and conditions.'; + 'J\'ai lu et j\'accepte les conditions d\'utilisation.'; @override String get welcomeConnectOrCreateAccount => - 'Connectez un compte existant ou creez en un nouveau pour utiliser IS'; + 'Connectez un compte existant ou créez-en un nouveau pour utiliser IS'; + + @override + String get phoneNumber => 'Numéro de téléphone'; @override - String get phoneNumber => 'Numero de telephone'; + String get termsAndConditions => 'Conditions d\'utilisation'; @override - String get termsAndConditions => '#Terms and Conditions'; + String get establishedIn2023 => 'Établi en 2023'; @override String get passwordShouldHaveAtleast8Characters => - 'Le mot-de-passe doit faire au moins 8 characteres de long'; + 'Le mot de passe doit contenir au moins 8 caractères'; @override - String get createAccount => 'Creez un compte'; + String get createAccount => 'Créer un compte'; @override - String get retry => 'Reessayer'; + String get retry => 'Réessayer'; } diff --git a/lib/pages/dashboard/blank/dashboard.dart b/lib/pages/dashboard/blank/dashboard.dart index 588bf8e..171afe1 100644 --- a/lib/pages/dashboard/blank/dashboard.dart +++ b/lib/pages/dashboard/blank/dashboard.dart @@ -10,7 +10,10 @@ class BlankDashboard extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - appBar: AppBar(title: Text(AppLocalizations.of(context)!.areWeGoing)), + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.areWeGoing), + leading: null, + ), body: Center( child: SizedBox( width: 500, diff --git a/lib/pages/dashboard/dashboard.dart b/lib/pages/dashboard/dashboard.dart index 853db46..5b86407 100644 --- a/lib/pages/dashboard/dashboard.dart +++ b/lib/pages/dashboard/dashboard.dart @@ -1,8 +1,42 @@ import 'package:flutter/material.dart'; import 'package:ins/appstate.dart'; +import 'package:ins/widgets/imsg.dart'; +import 'package:ins/widgets/loading.dart'; import 'blank/dashboard.dart'; import 'package:ins/l10n/app_localizations.dart'; +Widget loadingDashboard(BuildContext context, {bool backButton = true}) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.loadingYourDashboard), + leading: backButton ? BackButton() : null, + ), + body: Column( + children: [ + LoadingWidget( + messages: AppLocalizations.of(context)!.waitingMessages.split("|"), + ), + ], + ), + ); +} + +Widget errorLoadingDashboard( + BuildContext context, + String message, { + bool backButton = true, +}) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.loadingYourDashboard), + leading: backButton ? BackButton() : null, + ), + body: Column( + children: [IMsgWidget(icon: Icon(Icons.error), message: Text(message))], + ), + ); +} + Future getDashboard(AppState? state) async { state ??= await AppState.load(); if (state.schoolUser == null) { @@ -18,3 +52,18 @@ Future getDashboard(AppState? state) async { ); } } + +Widget loadDashboard(AppState? state) { + return FutureBuilder( + future: getDashboard(state), + builder: (context, snapshot) { + if (snapshot.hasData) { + return snapshot.data!; + } else if (snapshot.connectionState == ConnectionState.waiting) { + return loadingDashboard(context); + } else { + return errorLoadingDashboard(context, snapshot.error.toString()); + } + }, + ); +} diff --git a/lib/pages/school/school_profile.dart b/lib/pages/school/school_profile.dart index 2f945ed..b2aaa25 100644 --- a/lib/pages/school/school_profile.dart +++ b/lib/pages/school/school_profile.dart @@ -3,6 +3,7 @@ import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:ins/models.dart' as models; import 'package:ins/appstate.dart'; +import 'package:ins/l10n/app_localizations.dart'; class SchoolProfilePage extends StatelessWidget { final models.School school; @@ -41,9 +42,9 @@ class SchoolProfilePage extends StatelessWidget { children: [ _buildAppBar(context, onWideLayout: true), const SizedBox(height: 40), - _buildSchoolHeader(onWideLayout: true), + _buildSchoolHeader(context, onWideLayout: true), const SizedBox(height: 40), - _buildDescription(onWideLayout: true), + _buildDescription(context, onWideLayout: true), ], ), ), @@ -57,7 +58,7 @@ class SchoolProfilePage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text( - "At a Glance", + AppLocalizations.of(context)!.atAGlance, style: GoogleFonts.poppins( fontSize: 22, fontWeight: FontWeight.bold, @@ -66,7 +67,7 @@ class SchoolProfilePage extends StatelessWidget { const SizedBox(height: 24), _buildStatsRow(context, onWideLayout: true), const Divider(height: 48, thickness: 0.5), - _buildAdditionalInfo(onWideLayout: true), + _buildAdditionalInfo(context, onWideLayout: true), const Spacer(), _buildApplyButton(context), ], @@ -94,13 +95,13 @@ class SchoolProfilePage extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildSchoolHeader(), + _buildSchoolHeader(context), const SizedBox(height: 32), _buildStatsRow(context), const Divider(height: 48, thickness: 0.5), - _buildDescription(), + _buildDescription(context), const SizedBox(height: 32), - _buildAdditionalInfo(), + _buildAdditionalInfo(context), const SizedBox(height: 32), _buildApplyButton(context), ], @@ -111,12 +112,15 @@ class SchoolProfilePage extends StatelessWidget { ); } - Widget _buildAdditionalInfo({bool onWideLayout = false}) { + Widget _buildAdditionalInfo( + BuildContext context, { + bool onWideLayout = false, + }) { final content = Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Contact Information", + AppLocalizations.of(context)!.contactInformation, style: GoogleFonts.poppins(fontSize: 18, fontWeight: FontWeight.w600), ), const SizedBox(height: 16), @@ -150,7 +154,7 @@ class SchoolProfilePage extends StatelessWidget { return FilledButton.icon( onPressed: null, // TODO: Implement application logic icon: const Icon(Icons.edit_document), - label: const Text("Apply Now"), + label: Text(AppLocalizations.of(context)!.applyNow), style: FilledButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 20), textStyle: GoogleFonts.poppins( @@ -161,9 +165,11 @@ class SchoolProfilePage extends StatelessWidget { ); } - Widget _buildDescription({bool onWideLayout = false}) { + Widget _buildDescription(BuildContext context, {bool onWideLayout = false}) { return MarkdownBody( - data: school.description ?? "No description provided.", + data: + school.description ?? + AppLocalizations.of(context)!.noDescriptionProvided, styleSheet: MarkdownStyleSheet( p: GoogleFonts.poppins( fontSize: 16, @@ -209,7 +215,7 @@ class SchoolProfilePage extends StatelessWidget { ); } - Widget _buildSchoolHeader({bool onWideLayout = false}) { + Widget _buildSchoolHeader(BuildContext context, {bool onWideLayout = false}) { return Row( children: [ Hero( @@ -247,7 +253,7 @@ class SchoolProfilePage extends StatelessWidget { ), const SizedBox(height: 4), Text( - "Established in 2023", // Placeholder + AppLocalizations.of(context)!.establishedIn2023, // Placeholder style: GoogleFonts.poppins(fontSize: 16, color: Colors.black54), ), ], @@ -283,9 +289,13 @@ class SchoolProfilePage extends StatelessWidget { Widget _buildStatsRow(BuildContext context, {bool onWideLayout = false}) { final stats = [ - _buildStatItem(Icons.star, "Rating", "4.4"), - _buildStatItem(Icons.people, "Students", "0"), - _buildStatItem(Icons.location_city, "Campus", "Online"), + _buildStatItem(Icons.star, AppLocalizations.of(context)!.rating, "4.4"), + _buildStatItem(Icons.people, AppLocalizations.of(context)!.students, "0"), + _buildStatItem( + Icons.location_city, + AppLocalizations.of(context)!.campus, + AppLocalizations.of(context)!.online, + ), ]; return IntrinsicHeight( @@ -302,158 +312,3 @@ class SchoolProfilePage extends StatelessWidget { ); } } - - - -//IconData _getFormIcon(models.SchoolApplicationForm form) { -// return Icons.school; -// /* -// switch (form.type.toLowerCase()) { -// case 'transfer': -// return Icons.swap_horiz; -// case 'international': -// return Icons.language; -// case 'graduate': -// return Icons.school; -// case 'scholarship': -// return Icons.attach_money; -// default: -// return Icons.description; -// }*/ -//} - -//Future _selectApplicationForm( -//BuildContext context, -//models.School school, -//models.Session session, -//models.User user, -//) async { -// final forms = await school.getApplicationForms(); -// if (!context.mounted) return; -// -// showModalBottomSheet( -// context: context, -// isScrollControlled: true, -// backgroundColor: Colors.transparent, -// barrierColor: Colors.black.withOpacity(0.4), -// builder: (context) => Container( -// decoration: BoxDecoration( -// color: Theme.of(context).scaffoldBackgroundColor, -// borderRadius: const BorderRadius.vertical(top: Radius.circular(25)), -// ), -// child: Padding( -// padding: const EdgeInsets.only( -// top: 12, -// left: 16, -// right: 16, -// bottom: 24, -// ), -// child: Column( -// mainAxisSize: MainAxisSize.min, -// children: [ -// Center( -// child: Container( -// width: 40, -// height: 4, -// decoration: BoxDecoration( -// color: Colors.grey[400], -// borderRadius: BorderRadius.circular(2), -// ), -// ), -// ), -// const SizedBox(height: 16), -// Text( -// "Select application form", -// style: GoogleFonts.poppins( -// fontSize: 22, -// fontWeight: FontWeight.w600, -// color: Theme.of(context).primaryColor, -// ), -// ), -// const SizedBox(height: 24), -// Flexible( -// child: ListView.separated( -// shrinkWrap: true, -// physics: const ClampingScrollPhysics(), -// itemCount: forms.length, -// separatorBuilder: (_, __) => const Divider(height: 1), -// itemBuilder: (context, index) { -// final form = forms[index]; -// return Material( -// color: Colors.transparent, -// child: InkWell( -// borderRadius: BorderRadius.circular(12), -// onTap: () { -// Navigator.pop(context); -// launchApplicationForm( -// context, -// school, -// session, -// user, -// form, -// ); -// }, -// child: Container( -// padding: const EdgeInsets.symmetric( -// vertical: 16, -// horizontal: 20, -// ), -// child: Row( -// children: [ -// Container( -// padding: const EdgeInsets.all(12), -// decoration: BoxDecoration( -// color: Theme.of( -// context, -// ).primaryColor.withOpacity(0.1), -// borderRadius: BorderRadius.circular(12), -// ), -// child: Icon( -// _getFormIcon(form), -// color: Theme.of(context).focusColor, -// size: 28, -// ), -// ), -// const SizedBox(width: 20), -// Expanded( -// child: Column( -// crossAxisAlignment: CrossAxisAlignment.start, -// children: [ -// Text( -// form.title, -// style: GoogleFonts.poppins( -// fontSize: 16, -// fontWeight: FontWeight.w600, -// ), -// ), -// Padding( -// padding: const EdgeInsets.only(top: 4), -// child: Text( -// form.description, -// style: GoogleFonts.poppins( -// fontSize: 14, -// color: Colors.grey[600], -// ), -// maxLines: 2, -// ), -// ), -// ], -// ), -// ), -// Icon(Icons.chevron_right, color: Colors.grey[400]), -// ], -// ), -// ), -// ), -// ); -// }, -// ), -// ), -// ], -// ), -// ), -// ), -// ); -//} - - diff --git a/lib/pages/sign/signup/extlinked.dart b/lib/pages/sign/signup/extlinked.dart index 1a7324b..5d8361f 100644 --- a/lib/pages/sign/signup/extlinked.dart +++ b/lib/pages/sign/signup/extlinked.dart @@ -122,7 +122,7 @@ class _ExtraLinkedPageState extends State { if (_emailController.text.isEmpty) { _emailError = null; } else { - _emailError = chechEmail(_emailController.text); + _emailError = chechEmail(context, _emailController.text); } }); } diff --git a/lib/pages/sign/signup/submit.dart b/lib/pages/sign/signup/submit.dart index 872e814..eecee67 100644 --- a/lib/pages/sign/signup/submit.dart +++ b/lib/pages/sign/signup/submit.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:ins/l10n/app_localizations.dart'; +import 'package:ins/pages/dashboard/dashboard.dart'; import 'package:ins/widgets/imsg.dart'; import 'form.dart'; import 'package:ins/widgets/loading.dart'; @@ -74,5 +75,9 @@ class SubmitingPage extends StatelessWidget { ); } - void _openDashboard(BuildContext context) {} + void _openDashboard(BuildContext context) { + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => loadDashboard(null)), + ); + } } diff --git a/lib/utils/email.dart b/lib/utils/email.dart index e9e315b..cea3aee 100644 --- a/lib/utils/email.dart +++ b/lib/utils/email.dart @@ -1,15 +1,29 @@ -String? chechEmail(String email) { +import 'package:flutter/material.dart'; +import 'package:ins/l10n/app_localizations.dart'; + +String? chechEmail(BuildContext context, String email) { final match = RegExp("[^a-zA-Z0-9@.]").firstMatch("email"); - if (match != null) return "Invalid character in email ${match[0]}"; - if (!email.contains("@")) return "Email should contain '@'"; + if (match != null) { + return AppLocalizations.of(context)!.invalidCharacterInEmail + + match[0].toString(); + } + if (!email.contains("@")) { + return AppLocalizations.of(context)!.emailShouldContain; + } final parts = email.split("@"); if (parts.length != 2) { - return "Email should contain 1 '@'"; + return AppLocalizations.of(context)!.emailShouldContain1; + } + if (parts[0].length < 2) { + return AppLocalizations.of(context)!.emailNameTooShort; + } + if (!parts[1].contains(".")) { + return AppLocalizations.of(context)!.invalidEmailDomainsecondPart; } - if (parts[0].length < 2) return "Email name too short"; - if (!parts[1].contains(".")) return "Invalid email domain(second part)"; for (var element in parts[1].split(".")) { - if (element.isEmpty) return "Invalid domain component"; + if (element.isEmpty) { + return AppLocalizations.of(context)!.invalidDomainComponent; + } } return null; } From f674739fa53f1f7af6791006a75cc542566680f4 Mon Sep 17 00:00:00 2001 From: ken-morel Date: Fri, 18 Jul 2025 21:48:47 +0100 Subject: [PATCH 3/5] Added translations --- GEMINI.md | 90 +++++++++++++++++++++++----- lib/l10n/app_en.arb | 28 ++++++--- lib/l10n/app_fr.arb | 36 +++++++---- lib/l10n/app_localizations.dart | 78 +++++++++++++++++++++--- lib/l10n/app_localizations_en.dart | 54 ++++++++++++++--- lib/l10n/app_localizations_fr.dart | 61 +++++++++++++++---- lib/models.dart | 1 + lib/models/school.dart | 17 +++--- lib/models/school_application.dart | 16 ++--- lib/pages/school/school_profile.dart | 8 ++- 10 files changed, 305 insertions(+), 84 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index 53fff26..a60772f 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -1,24 +1,82 @@ -# Intranet of schools +# Intranet of Schools (INS) Project Context -The intranet of schools is a flutter project worked on by the 'Record Breakers'. -It is a flutter application made to work on android, linux and the web. It communicates -with a web backend via hooks exported from lib/backend.dart. +This document provides essential context for the "Intranet of Schools" Flutter project to aid in development and maintenance. -## project structure +## 1. Project Overview -source code in lib/, arb translations at lib/l19n, backend models at lib/models/ . utility -widgets at lib/widgets/, utilities at lib/utils, app at lib/app.dart, theme at lib/theme.dart. +- **Name:** `ins` (Intranet of Schools) +- **Description:** A responsive Flutter application providing a user interface for the Intranet of Schools platform. It's designed for managing user accounts, interacting with platform features, and accessing school-related information across mobile, web, and desktop. +- **Target Platforms:** Android, iOS, Linux, macOS, Windows, and Web. -## startup +## 2. Project Structure -When the app startups, the app state is loaded using utilities at lib/appstate.dart -Where is stored the session, user, and other date. +The project follows a standard Flutter structure. -When a user has signin or signup using the two assistant pages folders at lib/sign/signup/ and lib/sign/signin/ -a session and/or user is created and saved in appstate. -If the user is login, depending if he integrated school or not and the role in the school, -it opens the set of pages at lib/pages/dashboard/*/. +- `lib/`: Main application source code. + - `main.dart`: Application entry point. + - `app.dart`: Root application widget and setup. + - `appstate.dart`: Manages global application state (session, user data) likely using `provider`. + - `backend.dart`: Contains hooks and functions for communicating with the backend API. + - `models/`: Data models for entities like `User`, `School`, `Session`, `ChatMessage`, etc. + - `pages/`: UI screens for different parts of the app (e.g., `home`, `signin`, `dashboard`). + - `widgets/`: Reusable UI components (e.g., `locale_chooser`, `loading`). + - `utils/`: Utility functions (e.g., `logger`, `email_validator`). + - `theme.dart`: Application-wide theme and styling. + - `l10n/`: Localization files. +- `assets/`: Static assets. + - `assets/icon/`: Application icons. +- `test/`: Widget and unit tests. +- Platform-specific directories: `android/`, `ios/`, `linux/`, `macos/`, `windows/`, `web/`. -## assets +## 3. Dependencies -app assets are at assets, icons at assets/icons/ and the app icon at assets/icons/is.png +Key dependencies from `pubspec.yaml`: + +- **State Management:** + - `provider`: For managing application state. +- **UI & UX:** + - `google_fonts`: For custom fonts. + - `cupertino_icons`: iOS style icons. + - `flutter_markdown`: To render Markdown content. + - `cached_network_image`: To display and cache network images. + - `transparent_image`: For placeholder images. + - `intl_phone_number_input`: For formatted phone number input. +- **Networking & Backend:** + - `http`: For making HTTP requests to the backend. +- **Storage:** + - `shared_preferences`: For simple key-value storage. +- **Utilities:** + - `url_launcher`: To launch URLs. + - `logger`: For application logging. +- **Localization:** + - `flutter_localizations` & `intl`: For internationalization and localization. + +## 4. Code Style and Linting + +- The project uses the standard `package:flutter_lints/flutter.yaml` ruleset. +- Custom linting rules can be configured in `analysis_options.yaml`. + +## 5. Localization (l10n) + +- **Configuration:** `l10n.yaml` +- **Source Directory:** `lib/l10n` +- **Template File:** `app_en.arb` (English) +- **Process:** The app supports internationalization. New translations should be added as `.arb` files in `lib/l10n/` and code generation must be run to update localizations. + +## 6. Build & Deployment + +- **Firebase Hosting:** The project is configured to deploy the web build to Firebase Hosting. + - The public directory is `build/web`. + - Configuration is in `firebase.json`. +- **CI/CD:** A GitHub Actions workflow is set up in `.github/workflows/firebase-hosting-pull-request.yml`. + - **Trigger:** On pull requests to the main repository. + - **Job:** It builds the Flutter web application (`flutter build web`) and deploys it to a Firebase Hosting preview channel. + - **Secrets:** Requires `FIREBASE_SERVICE_ACCOUNT_INTRANET_OF_SCHOOLS` for deployment. + +## 7. Application Startup Flow + +1. The app starts via `main.dart`. +2. The global `AppState` is loaded from `appstate.dart`, which likely restores session/user data from `shared_preferences`. +3. If a user is not logged in, they are directed to the sign-in/sign-up pages (`lib/pages/sign/`). +4. Upon successful login, a session and user object are created and stored in `AppState`. +5. The user is then navigated to the appropriate dashboard (`lib/pages/dashboard/`) based on their role and school association. \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index d980a46..cfbc5d6 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,36 +1,42 @@ { "acceptContinue": "Accept & Continue", "contactInformation": "Contact Information", - "accountCreatedSuccesfuly": "Account created succesfuly", + "accountCreatedSuccesfuly": "#Account succefsully created", "invalidDomainComponent": "Invalid domain component", "loadingTerms": "Loading terms of service", - "passwordsDoNotMatch": "Password do not match", + "passwordsDoNotMatch": "Passwords do not match", "noSchoolFound": "No school found", "nothingHere": "Nothing here", "errorLoadingYourDashboard": "Error loading your dashboard", "fullName": "Full name", "welcomeToIS": "Welcome to IS", "emailShouldContain1": "Email should contain 1 '@'", + "whatDoYouWantToApplyFor": "What do you want to apply for?", "wasNotTranslated": "Was not translated", "students": "Students", "sloganShort": "Empowering connections, empowering futures", - "optionalInformations": "Optional information", + "optionalInformations": "#Informations optionnelles", "waitingMessages": "We're getting this done...|Please wait a little more...|Things are going as expected...|...|Wait once more...|A few moments...", - "invalidEmailDomainsecondPart": "Invalid email domain(second part)", + "invalidEmailDomainsecondPart": "#Domaine de l'e-mail invalide (deuxième partie)", + "couldNotGetSchooolApplicationForms": "#Nous n'avons pas pu recevoid les formulaires d'inscription", + "passwordShouldHaveAtLeast8Characters": "Password should have at least 8 characters length", "rating": "Rating", "openDashboard": "Open dashboard", "editPreferences": "Edit Preferences", - "addEmailaoPhoneNumber": "Add email and/or phone number", + "addEmailaoPhoneNumber": "#Renseigner une adresse e-mail et/ou un numéro de téléphone", "campus": "Campus", "applyNow": "Apply Now", "usernameDesc": "A short public name visible by others", - "usernameMustHaveBetween4And20Characters": "Username must have between 3 and 20 characters", + "usernameMustHaveBetween4And20Characters": "###Le nom d'utilisateur doit contenir entre 3 et 20 caractères", "helloWorldOfThings": "hello world of things", "password": "Password", "connectAccount": "Connect account", + "usernameMustHaveBetween3And20Characters": "Username must have between 3 and 20 characters", "emailShouldContain": "Email should contain '@'", "continueGt": "Continue >", + "accountCreatedSuccessfully": "Account created successfully", "emailAddress": "Email address", + "optionalInformation": "Optional information", "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Please review and accept our terms and conditions to continue.", "signupAssistant_phoneNumberError": "Phone number should be 9 digits long (without country code)", "online": "Online", @@ -38,25 +44,29 @@ "atAGlance": "At a Glance", "browseSchools": "Browse Schools", "thisUsernameIsAlreadyTaken": "This username is already taken", - "creatingYourAccount": "Creating you account", + "creatingYourAccount": "Creating your account", "emailNameTooShort": "Email name too short", "loadingYourDashboard": "Loading your dashboard", + "couldNotGetSchoolApplicationForms": "Could not get school application forms", "welcomeExcl": "Welcome!", + "schoolApplication": "School Application", "noDescriptionProvided": "No description provided.", "errorLoadingTerms": "Error loading terms of service", "areWeGoing": "Are we going?", "editProfile": "Edit Profile", - "reenterPassword": "Reenter password", + "reenterPassword": "Re-enter password", "username": "Username", "loginInformations": "Login information", "invalidCharacterInEmail": "Invalid character in email ", "exploreSchools": "Explore Schools", + "invalidEmailDomainSecondPart": "Invalid email domain (second part)", "iHaveReadAndAgreeToTheTermsAndConditions": "I have read and agree to the terms and conditions.", "welcomeConnectOrCreateAccount": "Connect an existing account or create a new one to embark on your journey with us", "phoneNumber": "Phone number", "termsAndConditions": "Terms and Conditions", + "addEmailOrPhoneNumber": "Add email or phone number", "establishedIn2023": "Established in 2023", - "passwordShouldHaveAtleast8Characters": "Password should have atleast 8 characters length", + "passwordShouldHaveAtleast8Characters": "#Le mot de passe doit contenir au moins 8 caractères", "createAccount": "Create an account", "retry": "Retry" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 8d54858..5f6c0a7 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1,7 +1,7 @@ { "acceptContinue": "Accepter & Continuer", "contactInformation": "Informations de contact", - "accountCreatedSuccesfuly": "Compte créé avec succès", + "accountCreatedSuccesfuly": "##Account succefsully created", "invalidDomainComponent": "Composant de domaine invalide", "loadingTerms": "Chargement des conditions d'utilisation", "passwordsDoNotMatch": "Les mots de passe ne correspondent pas", @@ -11,52 +11,62 @@ "fullName": "Nom complet", "welcomeToIS": "Bienvenue sur IS", "emailShouldContain1": "L'e-mail doit contenir un '@'", + "whatDoYouWantToApplyFor": "Pour quoi voulez-vous postuler ?", "wasNotTranslated": "N'a pas été traduit", "students": "Étudiants", - "sloganShort": "Construire des liens puissants, bâtir des avenirs prometteurs", - "optionalInformations": "Informations optionnelles", + "sloganShort": "Des liens forts, un avenir prometteur", + "optionalInformations": "##Informations optionnelles", "waitingMessages": "Nous aurons bientôt fini...|Attendez encore un peu...|Tout se passe bien...|...|Un peu plus de temps...|Quelques instants d'attente...", - "invalidEmailDomainsecondPart": "Domaine de l'e-mail invalide (deuxième partie)", + "invalidEmailDomainsecondPart": "##Domaine de l'e-mail invalide (deuxième partie)", + "couldNotGetSchooolApplicationForms": "##Nous n'avons pas pu recevoid les formulaires d'inscription", + "passwordShouldHaveAtLeast8Characters": "Le mot de passe doit contenir au moins 8 caractères", "rating": "Évaluation", "openDashboard": "Ouvrir le tableau de bord", "editPreferences": "Modifier les préférences", - "addEmailaoPhoneNumber": "Renseigner une adresse e-mail et/ou un numéro de téléphone", + "addEmailaoPhoneNumber": "##Renseigner une adresse e-mail et/ou un numéro de téléphone", "campus": "Campus", "applyNow": "Postuler maintenant", "usernameDesc": "Un surnom court, et visible des autres", - "usernameMustHaveBetween4And20Characters": "Le nom d'utilisateur doit contenir entre 3 et 20 caractères", - "helloWorldOfThings": "hello world of things", + "usernameMustHaveBetween4And20Characters": "####Le nom d'utilisateur doit contenir entre 3 et 20 caractères", + "helloWorldOfThings": "Salut le monde des choses", "password": "Mot de passe", "connectAccount": "Connecter votre compte", + "usernameMustHaveBetween3And20Characters": "Le nom d'utilisateur doit contenir entre 3 et 20 caractères", "emailShouldContain": "L'e-mail doit contenir '@'", "continueGt": "Continuer >", + "accountCreatedSuccessfully": "Compte créé avec succès", "emailAddress": "Adresse e-mail", + "optionalInformation": "Informations optionnelles", "pleaseReviewAndAcceptOurTermsAndConditionsToContinue": "Veuillez consulter et accepter nos conditions d'utilisation pour continuer.", "signupAssistant_phoneNumberError": "Le numéro de téléphone doit comporter 9 chiffres (sans l'indicatif du pays)", "online": "En ligne", - "homeLoadingMessages": "Vérification des détails de l'utilisateur...|Acquisition des permissions de votre école...|Veuillez patienter...|Nous y sommes presque...", + "homeLoadingMessages": "Chargement de l'état de l'application...|Vérification des détails de l'utilisateur...|Obtention des autorisations de vos écoles...|Vérification de l'âge sur votre acte de naissance...|Veuillez patienter...|Presque là...", "atAGlance": "En un coup d'œil", "browseSchools": "Parcourir les écoles", "thisUsernameIsAlreadyTaken": "Ce nom d'utilisateur est déjà pris", "creatingYourAccount": "Création de votre compte", "emailNameTooShort": "Nom d'e-mail trop court", "loadingYourDashboard": "Chargement de votre tableau de bord", - "welcomeExcl": "Bienvenue!", + "couldNotGetSchoolApplicationForms": "Impossible de récupérer les formulaires de demande d'école", + "welcomeExcl": "Bienvenue !", + "schoolApplication": "Candidature scolaire", "noDescriptionProvided": "Aucune description fournie.", "errorLoadingTerms": "Erreur de chargement des conditions d'utilisation", - "areWeGoing": "On y va?", + "areWeGoing": "On y va ?", "editProfile": "Modifier le profil", "reenterPassword": "Retapez votre mot de passe", "username": "Nom d'utilisateur", "loginInformations": "Informations de connexion", "invalidCharacterInEmail": "Caractère invalide dans l'e-mail", "exploreSchools": "Explorer les écoles", + "invalidEmailDomainSecondPart": "Domaine de l'e-mail invalide (deuxième partie)", "iHaveReadAndAgreeToTheTermsAndConditions": "J'ai lu et j'accepte les conditions d'utilisation.", - "welcomeConnectOrCreateAccount": "Connectez un compte existant ou créez-en un nouveau pour utiliser IS", + "welcomeConnectOrCreateAccount": "Connectez un compte existant ou créez-en un nouveau pour commencer votre voyage avec nous", "phoneNumber": "Numéro de téléphone", "termsAndConditions": "Conditions d'utilisation", + "addEmailOrPhoneNumber": "Ajouter une adresse e-mail ou un numéro de téléphone", "establishedIn2023": "Établi en 2023", - "passwordShouldHaveAtleast8Characters": "Le mot de passe doit contenir au moins 8 caractères", + "passwordShouldHaveAtleast8Characters": "##Le mot de passe doit contenir au moins 8 caractères", "createAccount": "Créer un compte", "retry": "Réessayer" -} \ No newline at end of file +} diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 85d0b38..d396719 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -113,7 +113,7 @@ abstract class AppLocalizations { /// No description provided for @accountCreatedSuccesfuly. /// /// In en, this message translates to: - /// **'Account created succesfuly'** + /// **'#Account succefsully created'** String get accountCreatedSuccesfuly; /// No description provided for @invalidDomainComponent. @@ -131,7 +131,7 @@ abstract class AppLocalizations { /// No description provided for @passwordsDoNotMatch. /// /// In en, this message translates to: - /// **'Password do not match'** + /// **'Passwords do not match'** String get passwordsDoNotMatch; /// No description provided for @noSchoolFound. @@ -170,6 +170,12 @@ abstract class AppLocalizations { /// **'Email should contain 1 \'@\''** String get emailShouldContain1; + /// No description provided for @whatDoYouWantToApplyFor. + /// + /// In en, this message translates to: + /// **'What do you want to apply for?'** + String get whatDoYouWantToApplyFor; + /// No description provided for @wasNotTranslated. /// /// In en, this message translates to: @@ -191,7 +197,7 @@ abstract class AppLocalizations { /// No description provided for @optionalInformations. /// /// In en, this message translates to: - /// **'Optional information'** + /// **'#Informations optionnelles'** String get optionalInformations; /// No description provided for @waitingMessages. @@ -203,9 +209,21 @@ abstract class AppLocalizations { /// No description provided for @invalidEmailDomainsecondPart. /// /// In en, this message translates to: - /// **'Invalid email domain(second part)'** + /// **'#Domaine de l\'e-mail invalide (deuxième partie)'** String get invalidEmailDomainsecondPart; + /// No description provided for @couldNotGetSchooolApplicationForms. + /// + /// In en, this message translates to: + /// **'#Nous n\'avons pas pu recevoid les formulaires d\'inscription'** + String get couldNotGetSchooolApplicationForms; + + /// No description provided for @passwordShouldHaveAtLeast8Characters. + /// + /// In en, this message translates to: + /// **'Password should have at least 8 characters length'** + String get passwordShouldHaveAtLeast8Characters; + /// No description provided for @rating. /// /// In en, this message translates to: @@ -227,7 +245,7 @@ abstract class AppLocalizations { /// No description provided for @addEmailaoPhoneNumber. /// /// In en, this message translates to: - /// **'Add email and/or phone number'** + /// **'#Renseigner une adresse e-mail et/ou un numéro de téléphone'** String get addEmailaoPhoneNumber; /// No description provided for @campus. @@ -251,7 +269,7 @@ abstract class AppLocalizations { /// No description provided for @usernameMustHaveBetween4And20Characters. /// /// In en, this message translates to: - /// **'Username must have between 3 and 20 characters'** + /// **'###Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'** String get usernameMustHaveBetween4And20Characters; /// No description provided for @helloWorldOfThings. @@ -272,6 +290,12 @@ abstract class AppLocalizations { /// **'Connect account'** String get connectAccount; + /// No description provided for @usernameMustHaveBetween3And20Characters. + /// + /// In en, this message translates to: + /// **'Username must have between 3 and 20 characters'** + String get usernameMustHaveBetween3And20Characters; + /// No description provided for @emailShouldContain. /// /// In en, this message translates to: @@ -284,12 +308,24 @@ abstract class AppLocalizations { /// **'Continue >'** String get continueGt; + /// No description provided for @accountCreatedSuccessfully. + /// + /// In en, this message translates to: + /// **'Account created successfully'** + String get accountCreatedSuccessfully; + /// No description provided for @emailAddress. /// /// In en, this message translates to: /// **'Email address'** String get emailAddress; + /// No description provided for @optionalInformation. + /// + /// In en, this message translates to: + /// **'Optional information'** + String get optionalInformation; + /// No description provided for @pleaseReviewAndAcceptOurTermsAndConditionsToContinue. /// /// In en, this message translates to: @@ -335,7 +371,7 @@ abstract class AppLocalizations { /// No description provided for @creatingYourAccount. /// /// In en, this message translates to: - /// **'Creating you account'** + /// **'Creating your account'** String get creatingYourAccount; /// No description provided for @emailNameTooShort. @@ -350,12 +386,24 @@ abstract class AppLocalizations { /// **'Loading your dashboard'** String get loadingYourDashboard; + /// No description provided for @couldNotGetSchoolApplicationForms. + /// + /// In en, this message translates to: + /// **'Could not get school application forms'** + String get couldNotGetSchoolApplicationForms; + /// No description provided for @welcomeExcl. /// /// In en, this message translates to: /// **'Welcome!'** String get welcomeExcl; + /// No description provided for @schoolApplication. + /// + /// In en, this message translates to: + /// **'School Application'** + String get schoolApplication; + /// No description provided for @noDescriptionProvided. /// /// In en, this message translates to: @@ -383,7 +431,7 @@ abstract class AppLocalizations { /// No description provided for @reenterPassword. /// /// In en, this message translates to: - /// **'Reenter password'** + /// **'Re-enter password'** String get reenterPassword; /// No description provided for @username. @@ -410,6 +458,12 @@ abstract class AppLocalizations { /// **'Explore Schools'** String get exploreSchools; + /// No description provided for @invalidEmailDomainSecondPart. + /// + /// In en, this message translates to: + /// **'Invalid email domain (second part)'** + String get invalidEmailDomainSecondPart; + /// No description provided for @iHaveReadAndAgreeToTheTermsAndConditions. /// /// In en, this message translates to: @@ -434,6 +488,12 @@ abstract class AppLocalizations { /// **'Terms and Conditions'** String get termsAndConditions; + /// No description provided for @addEmailOrPhoneNumber. + /// + /// In en, this message translates to: + /// **'Add email or phone number'** + String get addEmailOrPhoneNumber; + /// No description provided for @establishedIn2023. /// /// In en, this message translates to: @@ -443,7 +503,7 @@ abstract class AppLocalizations { /// No description provided for @passwordShouldHaveAtleast8Characters. /// /// In en, this message translates to: - /// **'Password should have atleast 8 characters length'** + /// **'#Le mot de passe doit contenir au moins 8 caractères'** String get passwordShouldHaveAtleast8Characters; /// No description provided for @createAccount. diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart index a9bb807..73df91c 100644 --- a/lib/l10n/app_localizations_en.dart +++ b/lib/l10n/app_localizations_en.dart @@ -15,7 +15,7 @@ class AppLocalizationsEn extends AppLocalizations { String get contactInformation => 'Contact Information'; @override - String get accountCreatedSuccesfuly => 'Account created succesfuly'; + String get accountCreatedSuccesfuly => '#Account succefsully created'; @override String get invalidDomainComponent => 'Invalid domain component'; @@ -24,7 +24,7 @@ class AppLocalizationsEn extends AppLocalizations { String get loadingTerms => 'Loading terms of service'; @override - String get passwordsDoNotMatch => 'Password do not match'; + String get passwordsDoNotMatch => 'Passwords do not match'; @override String get noSchoolFound => 'No school found'; @@ -44,6 +44,9 @@ class AppLocalizationsEn extends AppLocalizations { @override String get emailShouldContain1 => 'Email should contain 1 \'@\''; + @override + String get whatDoYouWantToApplyFor => 'What do you want to apply for?'; + @override String get wasNotTranslated => 'Was not translated'; @@ -54,7 +57,7 @@ class AppLocalizationsEn extends AppLocalizations { String get sloganShort => 'Empowering connections, empowering futures'; @override - String get optionalInformations => 'Optional information'; + String get optionalInformations => '#Informations optionnelles'; @override String get waitingMessages => @@ -62,7 +65,15 @@ class AppLocalizationsEn extends AppLocalizations { @override String get invalidEmailDomainsecondPart => - 'Invalid email domain(second part)'; + '#Domaine de l\'e-mail invalide (deuxième partie)'; + + @override + String get couldNotGetSchooolApplicationForms => + '#Nous n\'avons pas pu recevoid les formulaires d\'inscription'; + + @override + String get passwordShouldHaveAtLeast8Characters => + 'Password should have at least 8 characters length'; @override String get rating => 'Rating'; @@ -74,7 +85,8 @@ class AppLocalizationsEn extends AppLocalizations { String get editPreferences => 'Edit Preferences'; @override - String get addEmailaoPhoneNumber => 'Add email and/or phone number'; + String get addEmailaoPhoneNumber => + '#Renseigner une adresse e-mail et/ou un numéro de téléphone'; @override String get campus => 'Campus'; @@ -87,7 +99,7 @@ class AppLocalizationsEn extends AppLocalizations { @override String get usernameMustHaveBetween4And20Characters => - 'Username must have between 3 and 20 characters'; + '###Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'; @override String get helloWorldOfThings => 'hello world of things'; @@ -98,15 +110,25 @@ class AppLocalizationsEn extends AppLocalizations { @override String get connectAccount => 'Connect account'; + @override + String get usernameMustHaveBetween3And20Characters => + 'Username must have between 3 and 20 characters'; + @override String get emailShouldContain => 'Email should contain \'@\''; @override String get continueGt => 'Continue >'; + @override + String get accountCreatedSuccessfully => 'Account created successfully'; + @override String get emailAddress => 'Email address'; + @override + String get optionalInformation => 'Optional information'; + @override String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => 'Please review and accept our terms and conditions to continue.'; @@ -132,7 +154,7 @@ class AppLocalizationsEn extends AppLocalizations { String get thisUsernameIsAlreadyTaken => 'This username is already taken'; @override - String get creatingYourAccount => 'Creating you account'; + String get creatingYourAccount => 'Creating your account'; @override String get emailNameTooShort => 'Email name too short'; @@ -140,9 +162,16 @@ class AppLocalizationsEn extends AppLocalizations { @override String get loadingYourDashboard => 'Loading your dashboard'; + @override + String get couldNotGetSchoolApplicationForms => + 'Could not get school application forms'; + @override String get welcomeExcl => 'Welcome!'; + @override + String get schoolApplication => 'School Application'; + @override String get noDescriptionProvided => 'No description provided.'; @@ -156,7 +185,7 @@ class AppLocalizationsEn extends AppLocalizations { String get editProfile => 'Edit Profile'; @override - String get reenterPassword => 'Reenter password'; + String get reenterPassword => 'Re-enter password'; @override String get username => 'Username'; @@ -170,6 +199,10 @@ class AppLocalizationsEn extends AppLocalizations { @override String get exploreSchools => 'Explore Schools'; + @override + String get invalidEmailDomainSecondPart => + 'Invalid email domain (second part)'; + @override String get iHaveReadAndAgreeToTheTermsAndConditions => 'I have read and agree to the terms and conditions.'; @@ -184,12 +217,15 @@ class AppLocalizationsEn extends AppLocalizations { @override String get termsAndConditions => 'Terms and Conditions'; + @override + String get addEmailOrPhoneNumber => 'Add email or phone number'; + @override String get establishedIn2023 => 'Established in 2023'; @override String get passwordShouldHaveAtleast8Characters => - 'Password should have atleast 8 characters length'; + '#Le mot de passe doit contenir au moins 8 caractères'; @override String get createAccount => 'Create an account'; diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart index a3c84de..ade6c4d 100644 --- a/lib/l10n/app_localizations_fr.dart +++ b/lib/l10n/app_localizations_fr.dart @@ -15,7 +15,7 @@ class AppLocalizationsFr extends AppLocalizations { String get contactInformation => 'Informations de contact'; @override - String get accountCreatedSuccesfuly => 'Compte créé avec succès'; + String get accountCreatedSuccesfuly => '##Account succefsully created'; @override String get invalidDomainComponent => 'Composant de domaine invalide'; @@ -45,6 +45,9 @@ class AppLocalizationsFr extends AppLocalizations { @override String get emailShouldContain1 => 'L\'e-mail doit contenir un \'@\''; + @override + String get whatDoYouWantToApplyFor => 'Pour quoi voulez-vous postuler ?'; + @override String get wasNotTranslated => 'N\'a pas été traduit'; @@ -52,11 +55,10 @@ class AppLocalizationsFr extends AppLocalizations { String get students => 'Étudiants'; @override - String get sloganShort => - 'Construire des liens puissants, bâtir des avenirs prometteurs'; + String get sloganShort => 'Des liens forts, un avenir prometteur'; @override - String get optionalInformations => 'Informations optionnelles'; + String get optionalInformations => '##Informations optionnelles'; @override String get waitingMessages => @@ -64,7 +66,15 @@ class AppLocalizationsFr extends AppLocalizations { @override String get invalidEmailDomainsecondPart => - 'Domaine de l\'e-mail invalide (deuxième partie)'; + '##Domaine de l\'e-mail invalide (deuxième partie)'; + + @override + String get couldNotGetSchooolApplicationForms => + '##Nous n\'avons pas pu recevoid les formulaires d\'inscription'; + + @override + String get passwordShouldHaveAtLeast8Characters => + 'Le mot de passe doit contenir au moins 8 caractères'; @override String get rating => 'Évaluation'; @@ -77,7 +87,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String get addEmailaoPhoneNumber => - 'Renseigner une adresse e-mail et/ou un numéro de téléphone'; + '##Renseigner une adresse e-mail et/ou un numéro de téléphone'; @override String get campus => 'Campus'; @@ -90,10 +100,10 @@ class AppLocalizationsFr extends AppLocalizations { @override String get usernameMustHaveBetween4And20Characters => - 'Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'; + '####Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'; @override - String get helloWorldOfThings => 'hello world of things'; + String get helloWorldOfThings => 'Salut le monde des choses'; @override String get password => 'Mot de passe'; @@ -101,15 +111,25 @@ class AppLocalizationsFr extends AppLocalizations { @override String get connectAccount => 'Connecter votre compte'; + @override + String get usernameMustHaveBetween3And20Characters => + 'Le nom d\'utilisateur doit contenir entre 3 et 20 caractères'; + @override String get emailShouldContain => 'L\'e-mail doit contenir \'@\''; @override String get continueGt => 'Continuer >'; + @override + String get accountCreatedSuccessfully => 'Compte créé avec succès'; + @override String get emailAddress => 'Adresse e-mail'; + @override + String get optionalInformation => 'Informations optionnelles'; + @override String get pleaseReviewAndAcceptOurTermsAndConditionsToContinue => 'Veuillez consulter et accepter nos conditions d\'utilisation pour continuer.'; @@ -123,7 +143,7 @@ class AppLocalizationsFr extends AppLocalizations { @override String get homeLoadingMessages => - 'Vérification des détails de l\'utilisateur...|Acquisition des permissions de votre école...|Veuillez patienter...|Nous y sommes presque...'; + 'Chargement de l\'état de l\'application...|Vérification des détails de l\'utilisateur...|Obtention des autorisations de vos écoles...|Vérification de l\'âge sur votre acte de naissance...|Veuillez patienter...|Presque là...'; @override String get atAGlance => 'En un coup d\'œil'; @@ -145,7 +165,14 @@ class AppLocalizationsFr extends AppLocalizations { String get loadingYourDashboard => 'Chargement de votre tableau de bord'; @override - String get welcomeExcl => 'Bienvenue!'; + String get couldNotGetSchoolApplicationForms => + 'Impossible de récupérer les formulaires de demande d\'école'; + + @override + String get welcomeExcl => 'Bienvenue !'; + + @override + String get schoolApplication => 'Candidature scolaire'; @override String get noDescriptionProvided => 'Aucune description fournie.'; @@ -155,7 +182,7 @@ class AppLocalizationsFr extends AppLocalizations { 'Erreur de chargement des conditions d\'utilisation'; @override - String get areWeGoing => 'On y va?'; + String get areWeGoing => 'On y va ?'; @override String get editProfile => 'Modifier le profil'; @@ -175,13 +202,17 @@ class AppLocalizationsFr extends AppLocalizations { @override String get exploreSchools => 'Explorer les écoles'; + @override + String get invalidEmailDomainSecondPart => + 'Domaine de l\'e-mail invalide (deuxième partie)'; + @override String get iHaveReadAndAgreeToTheTermsAndConditions => 'J\'ai lu et j\'accepte les conditions d\'utilisation.'; @override String get welcomeConnectOrCreateAccount => - 'Connectez un compte existant ou créez-en un nouveau pour utiliser IS'; + 'Connectez un compte existant ou créez-en un nouveau pour commencer votre voyage avec nous'; @override String get phoneNumber => 'Numéro de téléphone'; @@ -189,12 +220,16 @@ class AppLocalizationsFr extends AppLocalizations { @override String get termsAndConditions => 'Conditions d\'utilisation'; + @override + String get addEmailOrPhoneNumber => + 'Ajouter une adresse e-mail ou un numéro de téléphone'; + @override String get establishedIn2023 => 'Établi en 2023'; @override String get passwordShouldHaveAtleast8Characters => - 'Le mot de passe doit contenir au moins 8 caractères'; + '##Le mot de passe doit contenir au moins 8 caractères'; @override String get createAccount => 'Créer un compte'; diff --git a/lib/models.dart b/lib/models.dart index 6c76718..8326e69 100644 --- a/lib/models.dart +++ b/lib/models.dart @@ -7,3 +7,4 @@ export 'models/thread.dart'; export 'models/class.dart'; export 'models/userrole.dart'; export 'models/school_user.dart'; +export 'models/school_application.dart'; diff --git a/lib/models/school.dart b/lib/models/school.dart index 09ad05f..6450d05 100644 --- a/lib/models/school.dart +++ b/lib/models/school.dart @@ -84,17 +84,20 @@ class School implements Model { Future> getApplicationForms( Session? session, ) async { - final data = await backend.query("v1/school/applications/forschool", { + final data = await backend.query("v1/school/application/forschool", { "school_id": id.toString(), }, session); if (data['status'] < 0) { throw Exception(data['message']); } - return (data['forms'] as List) - .map( - (form) => - SchoolApplicationForm.fromJson(form as Map), - ) - .toList(); + return data['forms'] == null + ? [] + : (data['forms'] as List) + .map( + (form) => SchoolApplicationForm.fromJson( + form as Map, + ), + ) + .toList(); } } diff --git a/lib/models/school_application.dart b/lib/models/school_application.dart index 1aef42a..ecbe77f 100644 --- a/lib/models/school_application.dart +++ b/lib/models/school_application.dart @@ -81,13 +81,15 @@ class SchoolApplicationForm implements Model { description: data['description'] as String?, instructions: data['instructions'] as String?, submittedMessage: data['submitted_message'] as String, - questions: (data['questions'] as List) - .map( - (e) => SchoolApplicationFormQuestion.fromJson( - e as Map, - ), - ) - .toList(), + questions: data['questions'] == null + ? [] + : (data['questions'] as List) + .map( + (e) => SchoolApplicationFormQuestion.fromJson( + e as Map, + ), + ) + .toList(), ); } @override diff --git a/lib/pages/school/school_profile.dart b/lib/pages/school/school_profile.dart index b2aaa25..db8c59b 100644 --- a/lib/pages/school/school_profile.dart +++ b/lib/pages/school/school_profile.dart @@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:ins/models.dart' as models; import 'package:ins/appstate.dart'; import 'package:ins/l10n/app_localizations.dart'; +import 'package:ins/pages/school/apply/home.dart'; class SchoolProfilePage extends StatelessWidget { final models.School school; @@ -152,7 +153,12 @@ class SchoolProfilePage extends StatelessWidget { Widget _buildApplyButton(BuildContext context) { return FilledButton.icon( - onPressed: null, // TODO: Implement application logic + onPressed: () => Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + SchoolApplyHomePage(school: school, appState: appState), + ), + ), icon: const Icon(Icons.edit_document), label: Text(AppLocalizations.of(context)!.applyNow), style: FilledButton.styleFrom( From 4500af866d51842fb070b4cd10649ed79284fb09 Mon Sep 17 00:00:00 2001 From: ken-morel Date: Fri, 18 Jul 2025 21:49:32 +0100 Subject: [PATCH 4/5] Enabled multidex --- android/app/build.gradle.kts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index d9e8cf3..c1af55c 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -24,10 +24,11 @@ android { applicationId = "cm.rbs.ins" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + minSdk = 21 targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName + multiDexEnabled = true } buildTypes { From 7c003717a483b2e547686be3fe76f233ef1be3fb Mon Sep 17 00:00:00 2001 From: ken-morel Date: Fri, 18 Jul 2025 21:49:55 +0100 Subject: [PATCH 5/5] Updated android --- ...kotlin-compiler-5112185348243535662.salive | 0 ...kotlin-compiler-8168454384994847072.salive | 0 .../example => cm/rbs}/ins/MainActivity.kt | 2 +- lib/pages/school/apply/home.dart | 118 ++++++++++++++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 android/.kotlin/sessions/kotlin-compiler-5112185348243535662.salive create mode 100644 android/.kotlin/sessions/kotlin-compiler-8168454384994847072.salive rename android/app/src/main/kotlin/{com/example => cm/rbs}/ins/MainActivity.kt (79%) create mode 100644 lib/pages/school/apply/home.dart diff --git a/android/.kotlin/sessions/kotlin-compiler-5112185348243535662.salive b/android/.kotlin/sessions/kotlin-compiler-5112185348243535662.salive new file mode 100644 index 0000000..e69de29 diff --git a/android/.kotlin/sessions/kotlin-compiler-8168454384994847072.salive b/android/.kotlin/sessions/kotlin-compiler-8168454384994847072.salive new file mode 100644 index 0000000..e69de29 diff --git a/android/app/src/main/kotlin/com/example/ins/MainActivity.kt b/android/app/src/main/kotlin/cm/rbs/ins/MainActivity.kt similarity index 79% rename from android/app/src/main/kotlin/com/example/ins/MainActivity.kt rename to android/app/src/main/kotlin/cm/rbs/ins/MainActivity.kt index 833d6b7..5d7936c 100644 --- a/android/app/src/main/kotlin/com/example/ins/MainActivity.kt +++ b/android/app/src/main/kotlin/cm/rbs/ins/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.ins +package cm.rbs.ins import io.flutter.embedding.android.FlutterActivity diff --git a/lib/pages/school/apply/home.dart b/lib/pages/school/apply/home.dart new file mode 100644 index 0000000..e0d89c5 --- /dev/null +++ b/lib/pages/school/apply/home.dart @@ -0,0 +1,118 @@ +import 'package:flutter/material.dart'; +import 'package:ins/appstate.dart'; +import 'package:ins/l10n/app_localizations.dart'; +import 'package:ins/models.dart' as models; +import 'package:ins/widgets/imsg.dart'; + +class SchoolApplyHomePage extends StatelessWidget { + final AppState appState; + final models.School school; + + const SchoolApplyHomePage({ + super.key, + required this.school, + required this.appState, + }); + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(AppLocalizations.of(context)!.schoolApplication), + ), + body: FutureBuilder>( + future: school.getApplicationForms(appState.session), + builder: (context, snapshot) { + if (snapshot.hasData) { + if (snapshot.data!.isEmpty) { + return Center( + child: Text(AppLocalizations.of(context)!.nothingHere), + ); + } + return _buildPage(context, snapshot.data!); + } else if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else { + return IMsgWidget( + icon: const Icon(Icons.error, size: 200, color: Colors.red), + message: Text( + "${AppLocalizations.of(context)!.couldNotGetSchoolApplicationForms}: ${snapshot.error}", + style: Theme.of( + context, + ).textTheme.bodyLarge?.copyWith(color: Colors.red), + ), + ); + } + }, + ), + ); + } + + Widget _buildPage( + BuildContext context, + List forms, + ) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(16.0, 16.0, 16.0, 8.0), + child: Text( + AppLocalizations.of(context)!.whatDoYouWantToApplyFor, + style: Theme.of( + context, + ).textTheme.headlineSmall?.copyWith(fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: ListView.builder( + padding: const EdgeInsets.only(top: 8.0), + itemCount: forms.length, + itemBuilder: (BuildContext context, int index) { + final form = forms[index]; + return Card( + margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + clipBehavior: Clip.antiAlias, + child: InkWell( + onTap: () { + // TODO: Handle form selection and navigation + }, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + form.title, + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 8), + if (form.description != null && + form.description!.isNotEmpty) + Text( + form.description!, + maxLines: 3, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodyMedium, + ) + else + Text( + AppLocalizations.of(context)!.noDescriptionProvided, + style: Theme.of(context).textTheme.bodyMedium + ?.copyWith( + fontStyle: FontStyle.italic, + color: Colors.grey, + ), + ), + ], + ), + ), + ), + ); + }, + ), + ), + ], + ); + } +} +