diff --git a/Sources/AllInApp/AllIn/Components/BetCard.swift b/Sources/AllInApp/AllIn/Components/BetCard.swift index 9eefbf8..2b7f637 100644 --- a/Sources/AllInApp/AllIn/Components/BetCard.swift +++ b/Sources/AllInApp/AllIn/Components/BetCard.swift @@ -19,7 +19,7 @@ struct BetCard: View { VStack(alignment: .leading,spacing: 2){ HStack{ Spacer() - Text("proposé par " + bet.author.capitalized) + Text("bet_proposed_by_format \(bet.author.capitalized)") .font(.system(size: 10)) .foregroundColor(AllInColors.grey800Color) @@ -31,7 +31,7 @@ struct BetCard: View { .font(.system(size: 20)) .fontWeight(.bold) HStack{ - Text("Commence le") + Text("bet_starting") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) TextCapsule(date: bet.endRegisterDate) @@ -46,7 +46,7 @@ struct BetCard: View { HStack{ Spacer() UsersPreview() - Text(bet.registered.count.description + " joueurs en attente") + Text("bet_players_waiting_format \(bet.registered.count.description)") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) .fontWeight(.medium) diff --git a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift index 1fe447a..bd3ff71 100644 --- a/Sources/AllInApp/AllIn/Components/BetLineLoading.swift +++ b/Sources/AllInApp/AllIn/Components/BetLineLoading.swift @@ -73,7 +73,7 @@ struct BetLineLoading: View { HStack { Spacer() - Text("Détails") + Text("bet_status_details_drawer") .textStyle(weight: .medium, color: AllInColors.primaryTextColor, size: 10) Image(showInfos ? "chevronUpIcon" : "chevronDownIcon") .resizable() diff --git a/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift b/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift index f6fc4bc..f540b1a 100644 --- a/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift +++ b/Sources/AllInApp/AllIn/Components/ChoiceCapsule.swift @@ -14,14 +14,14 @@ struct ChoiceCapsule: View { var body: some View { Group { if(pressed) { - Text("En cours") + Text("bet_current") .textStyle(weight: .semibold, color: .white, size: 15) .padding([.leading,.trailing],13.8) .padding([.top,.bottom], 7) .background(AllInColors.lightPurpleColor) .clipShape(Capsule()) } else { - Text("En cours") + Text("bet_current") .textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15) .padding([.leading,.trailing], 15) .padding([.top,.bottom], 7) diff --git a/Sources/AllInApp/AllIn/Components/DropDownFriends.swift b/Sources/AllInApp/AllIn/Components/DropDownFriends.swift index 0789158..96ce832 100644 --- a/Sources/AllInApp/AllIn/Components/DropDownFriends.swift +++ b/Sources/AllInApp/AllIn/Components/DropDownFriends.swift @@ -26,7 +26,7 @@ struct DropDownFriends: View { HStack(spacing: 3){ Text("41") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 15) - Text("amis disponibles") + Text("bet_creation_friends_available_format") .textStyle(weight: .regular, color: AllInColors.grey800Color, size: 15) Spacer() diff --git a/Sources/AllInApp/AllIn/Components/Friend.swift b/Sources/AllInApp/AllIn/Components/Friend.swift index db3fb5c..2cf3ca5 100644 --- a/Sources/AllInApp/AllIn/Components/Friend.swift +++ b/Sources/AllInApp/AllIn/Components/Friend.swift @@ -24,7 +24,7 @@ struct Friend: View { .font(.system(size: 18)) .lineLimit(1) Spacer() - Button("Supprimer") {} + Button("generic_delete") {} .frame(width: 90, height: 30) .foregroundColor(AllInColors.grey400Color) .font(.system(size: 14)) diff --git a/Sources/AllInApp/AllIn/Components/Menu.swift b/Sources/AllInApp/AllIn/Components/Menu.swift index 9d184d8..c7ace88 100644 --- a/Sources/AllInApp/AllIn/Components/Menu.swift +++ b/Sources/AllInApp/AllIn/Components/Menu.swift @@ -39,7 +39,7 @@ struct Menu: View { .fontWeight(.heavy) .font(.system(size: 15)) .foregroundColor(.white) - Text("Bets") + Text(String(localized: "drawer_bets")) .fontWeight(.regular) .font(.system(size: 12)) .foregroundColor(AllInColors.grey600Color) @@ -49,7 +49,7 @@ struct Menu: View { .fontWeight(.heavy) .font(.system(size: 15)) .foregroundColor(.white) - Text("Meilleur gain") + Text(String(localized: "drawer_best_win")) .fontWeight(.regular) .font(.system(size: 12)) .foregroundColor(AllInColors.grey600Color) @@ -59,7 +59,7 @@ struct Menu: View { .fontWeight(.heavy) .font(.system(size: 15)) .foregroundColor(.white) - Text("Amis") + Text(String(localized: "drawer_nb_friends")) .fontWeight(.regular) .font(.system(size: 12)) .foregroundColor(AllInColors.grey600Color) @@ -70,48 +70,50 @@ struct Menu: View { NavigationLink(destination: MainView(page: "CreationBet").navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "videoGameImage", title: "CREER UN BET", description: "Créez un nouveau BET et faites participer vos amis.") + ParameterMenu(image: "videoGameImage", title: String(localized: "drawer_create_a_bet"), description: String(localized: "drawer_create_a_bet_subtitle")) .padding([.leading,.trailing], 13) } - NavigationLink(destination: MainView(page: "Historic").navigationBarBackButtonHidden(true)) + NavigationLink(destination: MainView(page: "Historic") + .navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "eyesImage", title: "HISTORIQUE DES BETS", description: "Consultez vos paris en cours et terminés.") + ParameterMenu(image: "eyesImage", title: String(localized: "drawer_bet_history"), description: String(localized: "drawer_bet_history_subtitle")) .padding([.leading,.trailing], 13) } - NavigationLink(destination: MainView(page: "Friends").navigationBarBackButtonHidden(true)) + NavigationLink(destination: MainView(page: "Friends") + .navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "friendsImage", title: "AMIS", description: "Défiez vos porches en les ajoutant en amis.") + ParameterMenu(image: "friendsImage", title: String(localized: "drawer_friends"), description: String(localized: "drawer_friends_subtitle")) .padding([.leading,.trailing], 13) } VStack { - NavigationLink(destination: MainView(page: "Bet").navigationBarBackButtonHidden(true)) + NavigationLink(destination: MainView(page: "Bet") + .navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "moneyImage", title: "BET EN COURS", description: "Gérez vos bets et récompensez les gagnants.") + ParameterMenu(image: "moneyImage", title: String(localized: "drawer_public_bets"), description: String(localized: "drawer_public_bets_subtitle")) .padding([.leading,.trailing], 13) } NavigationLink(destination: MainView(page: "Ranking").navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "rankingImage", title: "CLASSEMENT", description: "Consultez votre classement parmis vos amis.") + ParameterMenu(image: "rankingImage", title: String(localized: "drawer_ranking"), description: String(localized: "drawer_ranking_subtitle")) .padding([.leading,.trailing], 13) } } NavigationLink(destination: MainView(page: "Current").navigationBarBackButtonHidden(true)) { - ParameterMenu(image: "eyesImage", title: "BETS EN COURS", description: "Consultez vos paris en cours.") + ParameterMenu(image: "eyesImage", title: String(localized: "drawer_current_bets"), description: String(localized: "drawer_current_bets_subtitle")) .padding([.leading,.trailing], 13) } - HStack { Spacer() Button { authService.logout() } label: { - Text("Deconnexion") + Text("generic_logout") .foregroundColor(.white) } Spacer() diff --git a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift index 0be07be..d0ad4e9 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipateButton.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipateButton.swift @@ -32,7 +32,7 @@ struct ParticipateButton: View { isOpen = true isParticapatedOpen = true } label: { - Text("Participer") + Text("bet_participate") .font(.system(size: 27)) .fontWeight(.semibold) .frame(maxWidth: .infinity).padding(10) @@ -42,7 +42,7 @@ struct ParticipateButton: View { case true: AllInColors.grey700Color.frame(width: 170) .mask( - Text("Participer") + Text("bet_participate") .font(.system(size: 27)) .fontWeight(.semibold) .frame(maxWidth: .infinity).padding(10) @@ -50,7 +50,7 @@ struct ParticipateButton: View { case false: AllInColors.primaryGradient.frame(width: 170) .mask( - Text("Participer") + Text("bet_participate") .font(.system(size: 27)) .fontWeight(.semibold) .frame(maxWidth: .infinity).padding(10) diff --git a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift index 78b3ee4..2a1b918 100644 --- a/Sources/AllInApp/AllIn/Components/ParticipationModal.swift +++ b/Sources/AllInApp/AllIn/Components/ParticipationModal.swift @@ -47,7 +47,7 @@ struct ParticipationModal: View { } .padding(10) HStack{ - Text("Faites vos paris") + Text("bet_status_place_your_bets") .font(.system(size: 18)) .foregroundColor(AllInColors.primaryTextColor) .fontWeight(.semibold) @@ -63,7 +63,7 @@ struct ParticipationModal: View { DropDownAnswerMenu(selectedOption: $selectedOption, options: options) - TextField("", text: $mise, prompt: Text("Mise") + TextField("", text: $mise, prompt: Text("generic_stake") .foregroundColor(AllInColors.lightGrey300Color) .font(.system(size: 16)) .fontWeight(.bold)) @@ -87,7 +87,7 @@ struct ParticipationModal: View { Spacer() VStack{ HStack{ - Text("Gains possibles") + Text("participation_possible_winnings") .font(.system(size: 13)) .foregroundColor(AllInColors.primaryTextColor) .fontWeight(.medium) diff --git a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift index 7d48284..15e0e73 100644 --- a/Sources/AllInApp/AllIn/Components/RecapBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/RecapBetCard.swift @@ -19,7 +19,7 @@ struct RecapBetCard: View { VStack(alignment: .leading,spacing: 2){ HStack{ Spacer() - Text("proposé par Lucas") + Text("bet_proposed_by_format \("Lucas")") .font(.system(size: 10)) .foregroundColor(AllInColors.grey800Color) @@ -31,7 +31,7 @@ struct RecapBetCard: View { .font(.system(size: 20)) .fontWeight(.bold) HStack{ - Text("Fini le ") + Text("bet_ends") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) TextCapsule(date: Date()) diff --git a/Sources/AllInApp/AllIn/Components/ReviewCard.swift b/Sources/AllInApp/AllIn/Components/ReviewCard.swift index fb356c6..300e782 100644 --- a/Sources/AllInApp/AllIn/Components/ReviewCard.swift +++ b/Sources/AllInApp/AllIn/Components/ReviewCard.swift @@ -22,7 +22,7 @@ struct ReviewCard: View { VStack(alignment: .leading,spacing: 2){ HStack{ Spacer() - Text("proposé par \(betDetail.bet.author)") + Text("bet_proposed_by_format \(betDetail.bet.author)") .font(.system(size: 10)) .foregroundColor(AllInColors.grey800Color) @@ -30,7 +30,7 @@ struct ReviewCard: View { Text(betDetail.bet.theme).font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) Text(betDetail.bet.phrase).font(.system(size: 20)).fontWeight(.bold) HStack{ - Text("Fini le").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) + Text("bet_ends").font(.system(size: 15)).foregroundColor(AllInColors.grey800Color) TextCapsule(date: betDetail.bet.endBetDate) Spacer() @@ -45,7 +45,7 @@ struct ReviewCard: View { HStack(){ Spacer() if(betDetail.bet.endBetDate < Date()){ - Text("Terminé") + Text("bet_finished") .foregroundColor(.white) .font(.system(size: 25)) .fontWeight(.bold) diff --git a/Sources/AllInApp/AllIn/Components/TrendingBetCard.swift b/Sources/AllInApp/AllIn/Components/TrendingBetCard.swift index cf65264..82f39a7 100644 --- a/Sources/AllInApp/AllIn/Components/TrendingBetCard.swift +++ b/Sources/AllInApp/AllIn/Components/TrendingBetCard.swift @@ -15,7 +15,7 @@ struct TrendingBetCard: View { .resizable() .frame(width: 15, height: 15, alignment: .leading) - Text("Populaire") + Text("bet_popular") .textStyle(weight: .medium, color: AllInColors.pinkAccentColor, size: 17) } .padding([.leading, .top], 10) @@ -33,7 +33,7 @@ struct TrendingBetCard: View { Text("12") .textStyle(weight: .bold, color: AllInColors.pinkAccentColor, size: 14) - Text("joueurs") + Text("bet_players_format") .textStyle(weight: .regular, color: .white, size: 14) .padding([.leading], 2) @@ -41,7 +41,7 @@ struct TrendingBetCard: View { .textStyle(weight: .bold, color: AllInColors.pinkAccentColor, size: 14) .padding([.leading], 10) - Text("points misés") + Text("bet_points_at_stake_format") .textStyle(weight: .regular, color: .white, size: 14) .padding([.leading], 2) } diff --git a/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings new file mode 100644 index 0000000..bdfcf8f --- /dev/null +++ b/Sources/AllInApp/AllIn/Ressources/en.lproj/Localizable.strings @@ -0,0 +1,177 @@ +/* + Localizable.strings + AllInApp + + Created by Emre on 15/05/2024. + +*/ + +/// Core + +"generic_username" = "Username"; +"generic_email" = "Email"; +"generic_password" = "Password"; +"generic_login" = "Login"; +"generic_logout" = "Logout"; +"generic_already_have_account" = "Already have an account ?"; +"generic_register" = "Register"; +"generic_validate" = "Validate"; +"generic_ok" = "OK"; +"generic_error" = "Error"; +"generic_in_waiting" = "In waiting"; +"generic_search" = "Search"; +"generic_add" = "Add"; +"generic_delete" = "Delete"; +"generic_stake" = "Stake"; +"network_error_text" = "Make sure to be properly connected to the network then try again."; + +/// Bet type + +"bet_type_binary" = "Yes / No"; +"bet_type_match" = "Sport match"; +"bet_type_custom" = "Custom answers"; + +/// Field error + +"field_error_mandatory" = "This field is mandatory."; +"field_error_not_identical" = "The fields are not identical."; +"field_error_bad_email" = "Please enter a valid email."; + +/// Drawer + +"drawer_bets" = "Bets"; +"drawer_best_win" = "Best win"; +"drawer_nb_friends" = "Friends"; +"drawer_friends" = "FRIENDS"; +"drawer_friends_subtitle" = "Challenge your folks by adding them as friends."; +"drawer_public_bets" = "PUBLIC BETS"; +"drawer_public_bets_subtitle" = "Browse the most popular bets of the moment."; +"drawer_current_bets" = "CURRENT BETS"; +"drawer_current_bets_subtitle" = "View your current bets."; +"drawer_create_a_bet" = "CREATE A BET"; +"drawer_create_a_bet_subtitle" = "Create a net bet and get your friends participating."; +"drawer_bet_history" = "BET HISTORY"; +"drawer_bet_history_subtitle" = "View your current and finished bets."; +"drawer_current_bets" = "CURRENT BETS"; +"drawer_current_bets_subtitle" = "Manage your bets and reward the winners."; +"drawer_ranking" = "RANKING"; +"drawer_ranking_subtitle" = "Check your ranking among your friends."; + +/// Welcome Page + +"welcome_title" = "Welcome to,"; +"welcome_subtitle" = "Collect your Allcoins and come bet with your friend to prove who\'s best."; +"welcome_join" = "Join"; + +/// Register Page + +"register_hello" = "Hello,"; +"register_hello %@" = "Hello %@,"; +"register_title" = "We need this!"; +"register_subtitle" = "Don\'t worry it\'s fast."; +"register_error_title" = "Error saving"; +"register_error_content" = "Registration failed. Try Again."; +"register_confirm_password" = "Confirm password"; +"register_already_used" = "Email or nickname already used."; + +/// Login Page + +"login_title" = "Welcome back !"; +"login_subtitle" = "We missed you."; +"login_error_title" = "Connection error"; +"login_error_content" = "Failed to login. Please try again."; +"login_no_account" = "Don't have an account ?"; +"login_forgot_password" = "Forgot password ?"; +"login_bad_credentials" = "Incorrect login or password."; + +/// Bet Creation Page + +"bet_creation_theme_tooltip" = "Usually a common name describing the overall theme of the bet for reference.."; +"bet_creation_phrase_tooltip" = "Generally the question the participants will answer to."; +"bet_creation_register_tooltip" = "After this date, nobody will be able to register anymore."; +"bet_creation_bet_end_tooltip" = "After this date, the result will be announced."; +"bet_creation_privacy_tooltip" = "Determines who will be able to see the bet."; +"bet_creation_question" = "Question"; +"bet_creation_answer" = "Answer"; +"bet_creation_publish" = "Publish the bet"; +"bet_creation_theme" = "Theme"; +"bet_creation_theme_placeholder" = "Studies, sports, party…"; +"bet_creation_bet_phrase" = "Bet phrase"; +"bet_creation_bet_phrase_placeholder" = "Will David be missing this Monday in class ?"; +"bet_creation_end_registration_date" = "Registration end date"; +"bet_creation_end_bet_date" = "Bet end date"; +"bet_creation_bet_privacy" = "Bet privacy"; +"bet_creation_friends_available_format" = "friends available"; +"bet_creation_public_bottom_text_1" = "Your BET will be visible by all the users."; +"bet_creation_public_bottom_text_2" = "Everyone will be able to join the BET."; +"bet_creation_private_bottom_text_1" = "Your BET will only be visible by your friends."; +"bet_creation_private_bottom_text_2" = "Only your friends will be able to join the BET."; +"bet_creation_bottom_text_3" = "You can invite friends at any moment during the registration period."; +"bet_creation_yes_no_bottom_text_1" = "The participants will have to respond with either YES or NO."; +"bet_creation_yes_no_bottom_text_2" = "No other answer will be accepted."; +"bet_creation_custom_bottom_text_1" = "You are going to fill in the different answers available in this bet."; +"bet_creation_custom_bottom_text_2" = "Be careful to be clear and avoid any uncertainties"; +"bet_creation_error" = "Error while creating the bet."; +"bet_creation_success_message" = "Bet created !"; +"bet_creation_response_title" = "Response title"; +"bet_creation_max_answers %lld" = "%lld more max."; +"bet_creation_error_past_date" = "The registration end date must be later than the current date."; +"bet_creation_error_date_order" = "The betting end date must be later than the registration end date."; + +/// Bet page + +"bet_popular" = "Popular"; +"bet_public" = "Public"; +"bet_private" = "Private"; +"bet_invitation" = "Invitation"; +"bet_current" = "Current"; +"bet_finished" = "Finished"; +"bet_starting" = "Starting on"; +"bet_started" = "Started on"; +"bet_ends" = "Ends on"; +"bet_ended" = "Ended on"; +"bet_participate" = "Participate"; +"bet_proposed_by_format %@" = "Proposed by %@"; +"bet_players_waiting_format %@" = "%@ joueurs en attente"; +"bet_players_format" = "players"; +"bet_points_at_stake_format" = "points at stake"; + +/// Bet status + +"bet_status_finished" = "Finished !"; +"bet_status_in_progress" = "In progress…"; +"bet_status_waiting" = "Waiting…"; +"bet_status_unavailable" = "Status unavailable"; +"bet_status_cancelled" = "Cancelled"; +"bet_status_place_your_bets" = "Place your bets"; +"bet_status_participants_list" = "Participants"; +"bet_status_details_drawer" = "Details"; +"participation_possible_winnings" = "Possible winnings"; + +/// Bet history + +"bet_history_current_title" = "Current"; +"bet_history_title" = "History"; + +/// Bet confirmation + +"bet_confirmation_text" = "This bet has now ended. You may now distribute the winnings by selecting the right answer."; +"bet_confirmation_choose_response" = "Please select the final answer :"; + +/// Ranking + +"ranking_title" = "Ranking"; + +/// Friends + +"friends_title" = "Friends"; + +/// Daily reward + +"daily_reward_title" = "Daily reward"; +"daily_reward_subtitle" = "Your daily reward is unlocked every day at 00:00 UTC and allows you to get between 10 and 150 Allcoins."; + +/// Notification + +"notification_title_end_bet_date" = "Who will be the winners?"; +"notification_subtitle_end_bet_date %@" = "The %@ bet has reached its deadline. Go to the app to enter the winning answer."; diff --git a/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings new file mode 100644 index 0000000..f3e9b2d --- /dev/null +++ b/Sources/AllInApp/AllIn/Ressources/fr.lproj/Localizable.strings @@ -0,0 +1,177 @@ +/* + Localizable.strings + AllInApp + + Created by Emre on 15/05/2024. + +*/ + +/// Core + +"generic_username" = "Pseudo"; +"generic_email" = "Email"; +"generic_password" = "Mot de passe"; +"generic_login" = "Se connecter"; +"generic_logout" = "Déconnexion"; +"generic_already_have_account" = "Tu as déjà un compte ?"; +"generic_register" = "S'inscrire"; +"generic_validate" = "Valider"; +"generic_ok" = "OK"; +"generic_error" = "Erreur"; +"generic_in_waiting" = "En attente"; +"generic_search" = "Rechercher"; +"generic_add" = "Ajouter"; +"generic_delete" = "Supprimer"; +"generic_stake" = "Mise"; +"network_error_text" = "Assurez-vous d\'être bien connecté au réseau puis réessayez."; + +/// Bet type + +"bet_type_binary" = "Oui / Non"; +"bet_type_match" = "Match sportif"; +"bet_type_custom" = "Réponses personnalisées"; + +/// Field error + +"field_error_mandatory" = "Ce champ est obligatoire."; +"field_error_not_identical" = "Les champs ne sont pas identiques."; +"field_error_bad_email" = "Veuillez saisir un email valide."; + +/// Drawer + +"drawer_bets" = "Bets"; +"drawer_best_win" = "Meilleur gain"; +"drawer_nb_friends" = "Amis"; +"drawer_friends" = "AMIS"; +"drawer_friends_subtitle" = "Défiez vos proches en les ajoutant en amis."; +"drawer_public_bets" = "BETS PUBLIQUES"; +"drawer_public_bets_subtitle" = "Parcourez les bets les plus populaires du moment."; +"drawer_current_bets" = "BETS EN COURS"; +"drawer_current_bets_subtitle" = "Consultez vos paris en cours."; +"drawer_create_a_bet" = "CREER UN BET"; +"drawer_create_a_bet_subtitle" = "Créez un nouveau bet et faites participer vos amis."; +"drawer_bet_history" = "HISTORIQUE DES BETS"; +"drawer_bet_history_subtitle" = "Consultez vos paris en cours et terminés."; +"drawer_current_bets" = "BETS EN COURS"; +"drawer_current_bets_subtitle" = "Gérez vos bets et récompensez les gagnants."; +"drawer_ranking" = "CLASSEMENT"; +"drawer_ranking_subtitle" = "Consultez votre classement parmis vos amis."; + +/// Welcome Page + +"welcome_title" = "Bienvenue sur,"; +"welcome_subtitle" = "Récupère tes Allcoins et viens parier avec tes amis pour prouver qui est le meilleur."; +"welcome_join" = "Rejoindre"; + +/// Register Page + +"register_hello" = "Bonjour"; +"register_hello %@" = "Bonjour %@,"; +"register_title" = "On a besoins de ça!"; +"register_subtitle" = "Promis c\'est rapide."; +"register_error_title" = "Erreur lors de l'enregistrement"; +"register_error_content" = "L'enregistrement a échoué. Veuillez réessayer."; +"register_confirm_password" = "Confirmation du mot de passe"; +"register_already_used" = "Email ou pseudo déjà utilisé."; + +/// Login Page + +"login_title" = "Te revoilà !"; +"login_subtitle" = "Bon retour parmis nous tu nous as manqué !"; +"login_error_title" = "Erreur de connexion"; +"login_error_content" = "La connexion a échoué. Veuillez réessayer."; +"login_no_account" = "Pas encore inscrit ?"; +"login_forgot_password" = "Mot de passe oublié ?"; +"login_bad_credentials" = "Login ou mot de passe incorrects."; + +/// Bet Creation Page + +"bet_creation_theme_tooltip" = "Généralement un nom commun décrivant le thème global du pari pour servir de référence."; +"bet_creation_phrase_tooltip" = "Généralement la question à laquelle les participants devront répondre."; +"bet_creation_register_tooltip" = "Après cette date, plus personne ne pourra s\'inscrire."; +"bet_creation_bet_end_tooltip" = "Après cette date, les résultats seront annoncés."; +"bet_creation_privacy_tooltip" = "Détermine qui pourra voir le bet."; +"bet_creation_question" = "Question"; +"bet_creation_answer" = "Réponse"; +"bet_creation_publish" = "Publier le bet"; +"bet_creation_theme" = "Thème"; +"bet_creation_theme_placeholder" = "Études, sport, soirée…"; +"bet_creation_bet_phrase" = "Phrase du BET"; +"bet_creation_bet_phrase_placeholder" = "David sera-il absent lundi matin en cours ?"; +"bet_creation_end_registration_date" = "Date de fin des inscriptions"; +"bet_creation_end_bet_date" = "Date de fin du BET"; +"bet_creation_bet_privacy" = "Confidentialité du bet"; +"bet_creation_friends_available_format" = "amis disponibles"; +"bet_creation_public_bottom_text_1" = "Votre BET sera visible par tous les utilisateurs."; +"bet_creation_public_bottom_text_2" = "Tout le monde pourra rejoindre le BET."; +"bet_creation_private_bottom_text_1" = "Votre BET sera visible uniquement par vos amis."; +"bet_creation_private_bottom_text_2" = "Seulement vos amis pourront rejoindre le BET."; +"bet_creation_bottom_text_3" = "Vous pourrez inviter des amis à tout moment pendant la période d’inscription."; +"bet_creation_yes_no_bottom_text_1" = "Les utilisateurs devront répondre au pari avec OUI ou NON."; +"bet_creation_yes_no_bottom_text_2" = "Aucune autre réponse ne sera acceptée."; +"bet_creation_custom_bottom_text_1" = "Vous allez renseigner les différentes réponses disponibles dans ce pari."; +"bet_creation_custom_bottom_text_2" = "Faites attention a etre claire et éviter toutes incertitudes"; +"bet_creation_error" = "Erreur lors de la création du bet."; +"bet_creation_success_message" = "Bet créé !"; +"bet_creation_response_title" = "Intitulé de réponse"; +"bet_creation_max_answers %lld" = "encore %lld max."; +"bet_creation_error_past_date" = "La date de fin des inscriptions doit être ultérieure à la date actuelle."; +"bet_creation_error_date_order" = "La date de fin des paris doit être ultérieure à la date de fin des inscriptions."; + +/// Bet page + +"bet_popular" = "Populaire"; +"bet_public" = "Public"; +"bet_private" = "Privé"; +"bet_invitation" = "Invitation"; +"bet_current" = "En cours"; +"bet_finished" = "Terminés"; +"bet_starting" = "Commence le"; +"bet_started" = "A commencé le"; +"bet_ends" = "Prend fin le"; +"bet_ended" = "A pris fin le"; +"bet_participate" = "Participer"; +"bet_proposed_by_format %@" = "Proposé par %@"; +"bet_players_waiting_format %@" = "%@ players waiting"; +"bet_players_format" = "joueurs"; +"bet_points_at_stake_format" = "points en jeu"; + +/// Bet status + +"bet_status_finished" = "Terminé !"; +"bet_status_in_progress" = "En cours…"; +"bet_status_waiting" = "En attente…"; +"bet_status_unavailable" = "Statut indisponible"; +"bet_status_cancelled" = "Annulé"; +"bet_status_place_your_bets" = "Faites vos paris"; +"bet_status_participants_list" = "Liste des participants"; +"bet_status_details_drawer" = "Détails"; +"participation_possible_winnings" = "Gains possibles"; + +/// Bet history + +"bet_history_current_title" = "En cours"; +"bet_history_title" = "Historique"; + +/// Bet confirmation + +"bet_confirmation_text" = "Ce bet est arrivé à la date de fin. Vous devez à présent distribuer les gains en validant le pari gagnant."; +"bet_confirmation_choose_response" = "Veuillez choisir la réponse finale :"; + +/// Ranking + +"ranking_title" = "Classement"; + +/// Friends + +"friends_title" = "Amis"; + +/// Daily reward + +"daily_reward_title" = "Récompense quotidienne"; +"daily_reward_subtitle" = "Votre récompense quotidienne est débloquée tous les jours à 00:00 UTC et vous permets d’obtenir entre 10 et 150 Allcoins."; + +/// Notification + +"notification_title_end_bet_date" = "Qui seront les vainqueurs ?"; +"notification_subtitle_end_bet_date %@" = "Le pari %@ a atteint sa date limite. Rendez-vous dans l'application pour renseigner la réponse gagnante."; diff --git a/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift index e7aeecc..4e92112 100644 --- a/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/CreationBetViewModel.swift @@ -42,11 +42,11 @@ class CreationBetViewModel: ObservableObject { switch statusCode { case 201: self.betAdded = true - let notificationItem = NotificationItem(title: "Qui seront les vainqueurs ?", content: "Le pari \"\(self.theme)\" a atteint sa date limite. Rendez-vous dans l'application pour renseigner la réponse gagnante.", interval: self.endBetDate.timeIntervalSinceNow) + let notificationItem = NotificationItem(title: String(localized: "notification_title_end_bet_date"), content: String(localized: "notification_subtitle_end_bet_date \(self.theme)"), interval: self.endBetDate.timeIntervalSinceNow) AppStateContainer.shared.notificationState.scheduleNotification(with: notificationItem) default: - self.setErrorMessage(errorMessage: "Problème de connexion. Veuillez réessayer ultérieurement.") + self.setErrorMessage(errorMessage: String(localized: "network_error_text")) } } } @@ -63,25 +63,25 @@ class CreationBetViewModel: ObservableObject { // Theme if checkTheme, theme.isEmpty { - newThemeFieldError = "Veuillez saisir le thème." + newThemeFieldError = String(localized: "field_error_mandatory") hasError = true } // Description if checkDescription, description.isEmpty { - newDescriptionFieldError = "Veuillez saisir la description." + newDescriptionFieldError = String(localized: "field_error_mandatory") hasError = true } // End Register Date if checkEndRegisterDate, endRegisterDate < Date() { - newEndRegisterDateFieldError = "La date de fin des inscriptions doit être ultérieure à la date actuelle." + newEndRegisterDateFieldError = String(localized: "bet_creation_error_past_date") hasError = true } // End Bet Date if checkEndBetDate, endBetDate < endRegisterDate { - newEndBetDateFieldError = "La date de fin des paris doit être ultérieure à la date de fin des inscriptions." + newEndBetDateFieldError = String(localized: "bet_creation_error_date_order") hasError = true } diff --git a/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift index 2d5e698..07ea5e1 100644 --- a/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/LoginViewModel.swift @@ -36,10 +36,10 @@ class LoginViewModel: ObservableObject { self.onLoginSuccess() case 404: AppStateContainer.shared.loggedState.connectedUser = false - self.setErrorMessage(errorMessage: "Login ou mot de passe incorrects.") + self.setErrorMessage(errorMessage: String(localized: "login_bad_credentials")) default: AppStateContainer.shared.loggedState.connectedUser = false - self.setErrorMessage(errorMessage: "La connexion a échoué. Veuillez réessayer.") + self.setErrorMessage(errorMessage: String(localized: "login_error_content")) } } } @@ -55,13 +55,13 @@ class LoginViewModel: ObservableObject { // Login if checkLogin, loginIdentifier.isEmpty { - newLoginIdentifierFieldError = "Veuillez saisir votre identifiant." + newLoginIdentifierFieldError = String(localized: "field_error_mandatory") hasError = true } // Password if checkPassword, loginPassword.isEmpty { - newLoginPasswordFieldError = "Veuillez saisir votre mot de passe." + newLoginPasswordFieldError = String(localized: "field_error_mandatory") hasError = true } diff --git a/Sources/AllInApp/AllIn/ViewModels/RegisterViewModel.swift b/Sources/AllInApp/AllIn/ViewModels/RegisterViewModel.swift index 8cd0aa3..dcdc885 100644 --- a/Sources/AllInApp/AllIn/ViewModels/RegisterViewModel.swift +++ b/Sources/AllInApp/AllIn/ViewModels/RegisterViewModel.swift @@ -40,10 +40,10 @@ class RegisterViewModel: ObservableObject { self.onRegisterSuccess() case 409: AppStateContainer.shared.loggedState.connectedUser = false - self.setErrorMessage(errorMessage: "Email ou pseudo déjà utilisé.") + self.setErrorMessage(errorMessage: String(localized: "register_already_used")) default: AppStateContainer.shared.loggedState.connectedUser = false - self.setErrorMessage(errorMessage: "La connexion a échoué. Veuillez réessayer.") + self.setErrorMessage(errorMessage: String(localized: "register_error_content")) } } } @@ -61,35 +61,33 @@ class RegisterViewModel: ObservableObject { // Username if checkUsername, registerUsername.isEmpty { - newRegisterUsernameFieldError = "Veuillez saisir votre pseudo." + newRegisterUsernameFieldError = String(localized: "field_error_mandatory") hasError = true } // Email if checkEmail, registerEmail.isEmpty { - newRegisterEmailFieldError = "Veuillez saisir votre email." + newRegisterEmailFieldError = String(localized: "field_error_mandatory") hasError = true - } - - if checkEmail, isValidEmail(email: registerEmail) { - newRegisterEmailFieldError = "Veuillez saisir un email valide." + } else if checkEmail, isValidEmail(email: registerEmail) { + newRegisterEmailFieldError = String(localized: "field_error_bad_email") hasError = true } // Password if checkPassword, registerPassword.isEmpty { - newRegisterPasswordFieldError = "Veuillez saisir votre mot de passe." + newRegisterPasswordFieldError = String(localized: "field_error_mandatory") hasError = true } // Confirm password if checkConfirmPassword, registerConfirmPassword.isEmpty { - newRegisterConfirmPasswordFieldError = "Veuillez confirmer votre mot de passe." + newRegisterConfirmPasswordFieldError = String(localized: "field_error_mandatory") hasError = true } if checkConfirmPassword, registerConfirmPassword != registerPassword { - newRegisterConfirmPasswordFieldError = "Les mots de passe ne sont pas identiques." + newRegisterConfirmPasswordFieldError = String(localized: "field_error_not_identical") hasError = true } diff --git a/Sources/AllInApp/AllIn/Views/BetEndingValidationView.swift b/Sources/AllInApp/AllIn/Views/BetEndingValidationView.swift index 997f6a6..ee3651b 100644 --- a/Sources/AllInApp/AllIn/Views/BetEndingValidationView.swift +++ b/Sources/AllInApp/AllIn/Views/BetEndingValidationView.swift @@ -51,11 +51,11 @@ struct BetEndingValidationView: View { ReviewCard(betDetail: bet, amountBetted: 0, isAWin: false) .padding(.top, 20) .padding(.bottom, 10) - Text("Ce bet est arrivé à la date de fin. Vous devez à présent distribuer les gains en validant le pari gagnant.") + Text("bet_confirmation_text") .textStyle(weight: .regular, color: AllInColors.grey800Color, size: 13) .multilineTextAlignment(.center) - Text("Veuillez choisir la réponse finale:") + Text("bet_confirmation_choose_response") .font(.system(size: 17)) .foregroundStyle(.white) .fontWeight(.bold) @@ -80,7 +80,7 @@ struct BetEndingValidationView: View { dismiss() viewModel.post() } label: { - Text("Valider") + Text("generic_validate") .font(.system(size: 23)) .foregroundColor(.white) .fontWeight(.bold) diff --git a/Sources/AllInApp/AllIn/Views/CreationBetView.swift b/Sources/AllInApp/AllIn/Views/CreationBetView.swift index 98a367f..38ca381 100644 --- a/Sources/AllInApp/AllIn/Views/CreationBetView.swift +++ b/Sources/AllInApp/AllIn/Views/CreationBetView.swift @@ -32,9 +32,9 @@ struct CreationBetView: View { @State private var values: [String] = [] let options: [(Int, String, String)] = [ - (0, "questionMarkIcon", "Oui / Non"), - (1, "footballIcon", "Pari sportif"), - (2, "paintbrushIcon", "Réponses personnalisées") + (0, "questionMarkIcon", String(localized: "bet_type_binary")), + (1, "footballIcon", String(localized: "bet_type_match")), + (2, "paintbrushIcon", String(localized: "bet_type_custom")) ] @State var groupedItems: [[String]] = [[String]] () @@ -81,7 +81,7 @@ struct CreationBetView: View { VStack(spacing: 5) { VStack() { HStack(spacing: 5) { - Text("Thème") + Text("bet_creation_theme") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 17) Image("questionMarkGreyIcon") @@ -91,7 +91,7 @@ struct CreationBetView: View { showTitlePopover.toggle() } .allInPopover(isPresented: $showTitlePopover, paddingHorizontal: 20) { - "Généralement un nom commun décrivant le thème global du pari pour servir de référence." + String(localized: "bet_creation_theme_tooltip") } Spacer() @@ -104,7 +104,7 @@ struct CreationBetView: View { Text(themeError) .textStyle(weight: .bold, color: .red, size: 10) } - TextField("", text: $viewModel.theme, prompt: Text("Études, sport, soirée...") + TextField("", text: $viewModel.theme, prompt: Text("bet_creation_theme_placeholder") .foregroundColor(AllInColors.lightGrey300Color) .font(.system(size: 14)) .fontWeight(.light)) @@ -125,14 +125,14 @@ struct CreationBetView: View { } HStack(spacing: 5) { - Text("Phrase du BET") + Text("bet_creation_bet_phrase") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 17) Image("questionMarkGreyIcon") .resizable() .frame(width: 14, height: 14) .allInPopover(isPresented: $showDescriptionPopover, paddingHorizontal: 10) { - "Court descriptif du pari, souvent une question ouverte ou fermée." + String(localized: "bet_creation_phrase_tooltip") } Spacer() @@ -141,11 +141,13 @@ struct CreationBetView: View { .padding(.leading, 10) VStack { + if let descriptionError = $viewModel.descriptionFieldError.wrappedValue { Text(descriptionError) .textStyle(weight: .bold, color: .red, size: 10) } - TextField("", text: $viewModel.description, prompt: Text("David sera absent Lundi matin en cours ?") + + TextField("", text: $viewModel.description, prompt: Text("bet_creation_bet_phrase_placeholder") .foregroundColor(AllInColors.lightGrey300Color) .font(.system(size: 14)) .fontWeight(.light), axis: .vertical) @@ -166,13 +168,13 @@ struct CreationBetView: View { } HStack(spacing: 5) { - Text("Date de fin des inscriptions") + Text("bet_creation_end_registration_date") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 17) Image("questionMarkGreyIcon") .resizable() .frame(width: 14, height: 14) .allInPopover(isPresented: $showRegistrationEndDatePopover) { - "Date de fin avant laquelle les joueurs peuvent s'inscrire en pariant leurs Allcoins." + String(localized: "bet_creation_register_tooltip") } Spacer() @@ -203,14 +205,14 @@ struct CreationBetView: View { VStack(alignment: .leading, spacing: 5) { VStack() { HStack(spacing: 5) { - Text("Date de fin du BET") + Text("bet_creation_end_bet_date") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 17) Image("questionMarkGreyIcon") .resizable() .frame(width: 14, height: 14) .allInPopover(isPresented: $showBetEndDatePopover) { - "Date des résultats où seront redistribués les Allcoins aux vainqueurs." + String(localized: "bet_creation_bet_end_tooltip") } Spacer() @@ -241,13 +243,13 @@ struct CreationBetView: View { VStack { HStack(spacing: 5) { - Text("Confidentialité du BET") + Text("bet_creation_bet_privacy") .textStyle(weight: .bold, color: AllInColors.primaryTextColor, size: 17) Image("questionMarkGreyIcon") .resizable() .frame(width: 14, height: 14) .allInPopover(isPresented: $showConfidentialityPopover, paddingHorizontal: 15) { - "Option permettant d'ouvrir ou non le pari à des inconnus." + String(localized: "bet_creation_privacy_tooltip") } Spacer() @@ -255,13 +257,13 @@ struct CreationBetView: View { .padding(.leading, 10) HStack(spacing: 5) { - ConfidentialityButton(image: "globe", text: "Public", selected: viewModel.isPublic) + ConfidentialityButton(image: "globe", text: String(localized: "bet_public"), selected: viewModel.isPublic) .onTapGesture { viewModel.isPublic = true } .padding(.trailing, 5) - ConfidentialityButton(image: "lock", text: "Privé", selected: !viewModel.isPublic) + ConfidentialityButton(image: "lock", text: String(localized: "bet_private"), selected: !viewModel.isPublic) .onTapGesture { viewModel.isPublic = false } @@ -277,25 +279,43 @@ struct CreationBetView: View { if !self.viewModel.isPublic { DropDownFriends() .padding(.bottom, 30) + + HStack() { + Spacer() + Text("bet_creation_private_bottom_text_1") + .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) + .multilineTextAlignment(.center) + Spacer() + } + + HStack() { + Spacer() + Text("bet_creation_private_bottom_text_2") + .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) + .multilineTextAlignment(.center) + Spacer() + } + } else { + HStack() { + Spacer() + Text("bet_creation_public_bottom_text_1") + .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) + .multilineTextAlignment(.center) + Spacer() + } + + HStack() { + Spacer() + Text("bet_creation_public_bottom_text_2") + .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) + .multilineTextAlignment(.center) + Spacer() + } } HStack() { Spacer() - Text("Votre BET sera visible par tous les utilisateurs.") - .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) - .multilineTextAlignment(.center) - Spacer() - } - HStack() { - Spacer() - Text("Tout le monde pourra rejoindre le BET.") - .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) - .multilineTextAlignment(.center) - Spacer() - } - HStack() { - Spacer() - Text("Vous pourrez inviter des amis à tout moment pendant la période d’inscription.") + Text("bet_creation_bottom_text_3") .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) .padding(.leading, 35) .multilineTextAlignment(.center) @@ -308,13 +328,13 @@ struct CreationBetView: View { Button(action: { viewModel.create() }) { - Text("Publier le bet") + Text("bet_creation_publish") .font(.system(size: 24)) .fontWeight(.bold) .overlay { - AllInColors.primaryGradient.frame(width: 150) + AllInColors.primaryGradient.frame(width: 200) .mask( - Text("Publier le bet") + Text("bet_creation_publish") .font(.system(size: 24)) .fontWeight(.bold) .frame(maxWidth: .infinity) @@ -349,25 +369,25 @@ struct CreationBetView: View { Group { switch viewModel.selectedOption { case 0: - Text("Les utilisateurs devront répondre au pari avec OUI ou NON.") + Text("bet_creation_yes_no_bottom_text_1") .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) .padding([.leading, .trailing], 20) - Text("Aucune autre réponse ne sera acceptée.") + Text("bet_creation_yes_no_bottom_text_2") .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) case 2: - Text("Vous allez renseigner les différentes réponses disponibles dans ce pari.") + Text("bet_creation_custom_bottom_text_1") .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) .padding(.leading, 13) - Text("Faites attention a etre claire et éviter toutes incertitudes") + Text("bet_creation_custom_bottom_text_2") .textStyle(weight: .bold, color: AllInColors.veryLightPurpleColor, size: 13) .padding(.bottom, 15) VStack(spacing: 5) { HStack(spacing: 0) { - TextField("", text: $response, prompt: Text("Intitulé de réponse") + TextField("", text: $response, prompt: Text("bet_creation_response_title") .foregroundColor(AllInColors.lightGrey200Color) .font(.system(size: 16)) .fontWeight(.medium)) @@ -393,7 +413,7 @@ struct CreationBetView: View { response = "" } }) { - Text("Ajouter") + Text("generic_add") .foregroundColor(.white) } .frame(width: 95, height: 40) @@ -403,7 +423,7 @@ struct CreationBetView: View { } HStack { Spacer() - Text("encore \(5 - values.count) max.") + Text(String(localized: "bet_creation_max_answers \(5 - values.count)")) .textStyle(weight: .regular, color: AllInColors.primaryTextColor, size: 12) } @@ -438,7 +458,7 @@ struct CreationBetView: View { } } default: - Text("En attente") + Text("generic_in_waiting") } } Spacer() @@ -452,7 +472,7 @@ struct CreationBetView: View { Button(action: { selectedTab = 0 }) { - Text("Question") + Text("bet_creation_question") .font(.system(size: 16)) .padding() .fontWeight(selectedTab == 0 ? .bold : .semibold) @@ -462,7 +482,7 @@ struct CreationBetView: View { Button(action: { selectedTab = 1 }) { - Text("Réponses") + Text("bet_creation_answer") .font(.system(size: 16)) .padding() .fontWeight(selectedTab == 1 ? .bold : .semibold) @@ -477,7 +497,7 @@ struct CreationBetView: View { hideKeyboard() } .alert(isPresented: $viewModel.showErrorMessage) { - Alert(title: Text("Erreur lors de la création d'un Bet"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("OK"))) + Alert(title: Text("bet_creation_error"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("generic_ok"))) } .edgesIgnoringSafeArea(.bottom) .background(AllInColors.backgroundColor) diff --git a/Sources/AllInApp/AllIn/Views/CurrentBetView.swift b/Sources/AllInApp/AllIn/Views/CurrentBetView.swift index aad6ed3..f9d3817 100644 --- a/Sources/AllInApp/AllIn/Views/CurrentBetView.swift +++ b/Sources/AllInApp/AllIn/Views/CurrentBetView.swift @@ -20,7 +20,7 @@ struct CurrentBetView: View { TopBar(showMenu: self.$showMenu) ScrollView(showsIndicators: false) { - Text("En cours") + Text("bet_history_current_title") .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25) .padding([.top],15) VStack(spacing: 20){ diff --git a/Sources/AllInApp/AllIn/Views/DailyGiftPage.swift b/Sources/AllInApp/AllIn/Views/DailyGiftPage.swift index 6acf82f..c72951f 100644 --- a/Sources/AllInApp/AllIn/Views/DailyGiftPage.swift +++ b/Sources/AllInApp/AllIn/Views/DailyGiftPage.swift @@ -35,7 +35,7 @@ struct DailyGiftPage: View { .edgesIgnoringSafeArea(.all) VStack { - Text("Récompense quotidienne") + Text("daily_reward_title") .textStyle(weight: .bold, color: .white, size: 25) Group { @@ -110,7 +110,7 @@ struct DailyGiftPage: View { } } - Text("Votre récompense quotidienne est débloquée tous les jours à 00:00 UTC et vous permet d’obtenir entre 10 et 150 Allcoins.") + Text("daily_reward_subtitle") .textStyle(weight: .medium, color: .white, size: 13) .multilineTextAlignment(.center) .padding(.horizontal, geometry.size.width * 0.13) diff --git a/Sources/AllInApp/AllIn/Views/DetailsView.swift b/Sources/AllInApp/AllIn/Views/DetailsView.swift index fea924d..f354f52 100644 --- a/Sources/AllInApp/AllIn/Views/DetailsView.swift +++ b/Sources/AllInApp/AllIn/Views/DetailsView.swift @@ -16,16 +16,16 @@ struct DetailsView: View { if let betType = viewModel.betDetail?.bet.status { switch betType { case .inProgress: - return ("En cours...", AllInColors.darkPurpleColor) + return ("bet_status_in_progress", AllInColors.darkPurpleColor) case .waiting, .closing: - return ("En attente...", AllInColors.pink100) + return ("bet_status_waiting", AllInColors.pink100) case .finished: - return ("Terminé", AllInColors.grey100Color) + return ("bet_status_finished", AllInColors.grey100Color) case .cancelled: - return ("Annulé", AllInColors.grey100Color) + return ("bet_status_cancelled", AllInColors.grey100Color) } } else { - return ("Statut indisponible", AllInColors.pink100) + return ("bet_status_unavailable", AllInColors.pink100) } } @@ -63,7 +63,7 @@ struct DetailsView: View { VStack(alignment: .leading, spacing: 5) { HStack(spacing: 3) { Spacer() - Text("proposé par") + Text("bet_proposed_by_format") .font(.system(size: 10)) .foregroundColor(AllInColors.grey800Color) Text((viewModel.betDetail?.bet.author ?? "Unknown").capitalized) @@ -82,7 +82,7 @@ struct DetailsView: View { HStack { HStack { Spacer() - Text("Commence le") + Text("bet_starting") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) } @@ -95,7 +95,7 @@ struct DetailsView: View { HStack { HStack { Spacer() - Text("Prend fin le") + Text("bet_ends") .font(.system(size: 15)) .foregroundColor(AllInColors.grey800Color) } @@ -116,7 +116,7 @@ struct DetailsView: View { VStack(alignment: .leading, spacing: 5) { BetLineLoading(participations: viewModel.betDetail?.participations ?? []) .padding(.vertical,15) - Text("Liste des participants") + Text("bet_status_participants_list") .font(.system(size: 18)) .foregroundStyle(AllInColors.grey100Color) .fontWeight(.bold) diff --git a/Sources/AllInApp/AllIn/Views/FriendsView.swift b/Sources/AllInApp/AllIn/Views/FriendsView.swift index 20f5b0e..7b1ccc1 100644 --- a/Sources/AllInApp/AllIn/Views/FriendsView.swift +++ b/Sources/AllInApp/AllIn/Views/FriendsView.swift @@ -14,7 +14,7 @@ struct FriendsView: View { var body: some View { VStack(alignment: .center, spacing: 0) { TopBar(showMenu: self.$showMenu) - Text("Amis") + Text("friends_title") .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25) .padding([.top,.bottom],15) diff --git a/Sources/AllInApp/AllIn/Views/HistoricBetView.swift b/Sources/AllInApp/AllIn/Views/HistoricBetView.swift index ab1bdd2..3768a8e 100644 --- a/Sources/AllInApp/AllIn/Views/HistoricBetView.swift +++ b/Sources/AllInApp/AllIn/Views/HistoricBetView.swift @@ -18,7 +18,7 @@ struct HistoricBetView: View { TopBar(showMenu: self.$showMenu) ScrollView(showsIndicators: false) { - Text("Historique") + Text("bet_history_title") .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25) .padding([.top],15) VStack(spacing: 20){ diff --git a/Sources/AllInApp/AllIn/Views/LoginView.swift b/Sources/AllInApp/AllIn/Views/LoginView.swift index e417a6b..8ab28aa 100644 --- a/Sources/AllInApp/AllIn/Views/LoginView.swift +++ b/Sources/AllInApp/AllIn/Views/LoginView.swift @@ -14,7 +14,6 @@ struct LoginView: View { case password } - @AppStorage("test") var test: String? @StateObject private var viewModel = LoginViewModel() @FocusState private var focusedField: Field? @State private var isPasswordVisible = true @@ -26,9 +25,9 @@ struct LoginView: View { VStack(spacing: 15) { Spacer() - Text("Te revoilà!") + Text("login_title") .textStyle(weight: .semibold, color: AllInColors.darkBlueColor, size: 40) - Text("Bon retour parmis nous tu nous as manqué!") + Text("login_subtitle") .textStyle(weight: .regular, color: AllInColors.darkBlueColor, size: 20) .frame(width: 220) .multilineTextAlignment(.center) @@ -40,7 +39,7 @@ struct LoginView: View { Text(identifierError) .textStyle(weight: .bold, color: .red, size: 10) } - TextField("", text: $viewModel.loginIdentifier, prompt: Text("Email").foregroundColor(.gray)) + TextField("", text: $viewModel.loginIdentifier, prompt: Text("generic_email").foregroundColor(.gray)) .padding() .background(Color.white.cornerRadius(9)) .frame(width: 300) @@ -51,6 +50,7 @@ struct LoginView: View { ) .autocapitalization(.none) .padding(.bottom, 8) + .autocorrectionDisabled(true) .focused($focusedField, equals: .email) } @@ -61,9 +61,9 @@ struct LoginView: View { } Group { if isPasswordVisible { - SecureField("", text: $viewModel.loginPassword, prompt: Text("Mot de passe").foregroundColor(.gray)) + SecureField("", text: $viewModel.loginPassword, prompt: Text("generic_password").foregroundColor(.gray)) } else { - TextField("", text: $viewModel.loginPassword, prompt: Text("Mot de passe").foregroundColor(.gray)) + TextField("", text: $viewModel.loginPassword, prompt: Text("generic_password").foregroundColor(.gray)) .autocapitalization(.none) } } @@ -90,7 +90,7 @@ struct LoginView: View { .focused($focusedField, equals: .password) } - Text("Mot de passe oublié?") + Text("login_forgot_password") .textStyle(weight: .medium, color: AllInColors.darkBlueColor, size: 14) .frame(alignment: .trailing) .padding(.bottom, 20) @@ -98,9 +98,8 @@ struct LoginView: View { Button(action: { viewModel.login() - test = "REtoutt" }) { - Text("Se connecter") + Text("generic_login") .textStyle(weight: .bold, color: .white, size: 17) .frame(width: 300, height: 60) .background(LinearGradient(gradient: @@ -110,12 +109,12 @@ struct LoginView: View { } Spacer() - HStack(spacing: 0) { - Text("Pas encore inscrit? ") + HStack(spacing: 4) { + Text("login_no_account") .textStyle(weight: .regular, color: AllInColors.darkBlueColor, size: 16) NavigationLink(destination: RegisterView().navigationBarBackButtonHidden(true)) { - Text("S'inscrire") + Text("generic_register") .textStyle(weight: .semibold, color: AllInColors.darkPurpleColor, size: 16) } } @@ -129,7 +128,7 @@ struct LoginView: View { } } .alert(isPresented: $viewModel.showErrorMessage) { - Alert(title: Text("Erreur de connexion"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("OK"))) + Alert(title: Text("login_error_title"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("generic_ok"))) } .onSubmit { switch focusedField { diff --git a/Sources/AllInApp/AllIn/Views/RankingView.swift b/Sources/AllInApp/AllIn/Views/RankingView.swift index 916bab3..f1e08be 100644 --- a/Sources/AllInApp/AllIn/Views/RankingView.swift +++ b/Sources/AllInApp/AllIn/Views/RankingView.swift @@ -15,7 +15,7 @@ struct RankingView: View { GeometryReader { geometry in VStack(alignment: .center, spacing: 0) { TopBar(showMenu: self.$showMenu) - Text("Classement") + Text("ranking_title") .textStyle(weight: .bold, color: AllInColors.grey500Color, size: 25) .padding([.top,.bottom],15) diff --git a/Sources/AllInApp/AllIn/Views/RegisterView.swift b/Sources/AllInApp/AllIn/Views/RegisterView.swift index 32e32e1..5b30829 100644 --- a/Sources/AllInApp/AllIn/Views/RegisterView.swift +++ b/Sources/AllInApp/AllIn/Views/RegisterView.swift @@ -27,18 +27,18 @@ struct RegisterView: View { Spacer() VStack { if !viewModel.registerUsername.isEmpty { - Text("Bonjour " + viewModel.registerUsername + ",") + Text("register_hello \(viewModel.registerUsername)") .textStyle(weight: .semibold, color: AllInColors.darkBlueColor, size: 40) .padding([.trailing, .leading], 30) } else { - Text("Bonjour,") + Text("register_hello") .textStyle(weight: .semibold, color: AllInColors.darkBlueColor, size: 40) } - Text("On a besoin de ça!") + Text("register_title") .textStyle(weight: .semibold, color: AllInColors.darkBlueColor, size: 40) } - Text("Promis c’est rapide.") + Text("register_subtitle") .textStyle(weight: .regular, color: AllInColors.darkBlueColor, size: 20) .frame(width: 220) .multilineTextAlignment(.center) @@ -49,7 +49,7 @@ struct RegisterView: View { Text(usernameError) .textStyle(weight: .bold, color: .red, size: 10) } - TextField("", text: $viewModel.registerUsername, prompt: Text("Pseudo").foregroundColor(.gray)) + TextField("", text: $viewModel.registerUsername, prompt: Text("generic_username").foregroundColor(.gray)) .padding() .background(Color.white.cornerRadius(9)) .frame(width: 300) @@ -59,6 +59,7 @@ struct RegisterView: View { .stroke(AllInColors.blueGrey800Color, lineWidth: 1) ) .padding(.bottom, 8) + .autocorrectionDisabled(true) .onChange(of: viewModel.registerUsername, perform: { value in guard value != viewModel.registerUsername else { return } if value.count > 25 { @@ -74,7 +75,7 @@ struct RegisterView: View { Text(emailError) .textStyle(weight: .bold, color: .red, size: 10) } - TextField("", text: $viewModel.registerEmail, prompt: Text("Email").foregroundColor(.gray)) + TextField("", text: $viewModel.registerEmail, prompt: Text("generic_email").foregroundColor(.gray)) .padding() .keyboardType(.emailAddress) .background(Color.white.cornerRadius(9)) @@ -85,6 +86,7 @@ struct RegisterView: View { .stroke(AllInColors.blueGrey800Color, lineWidth: 1) ) .padding(.bottom, 8) + .autocorrectionDisabled(true) .onChange(of: viewModel.registerEmail, perform: { value in guard value != viewModel.registerEmail else { return } if value.count > 50 { @@ -105,9 +107,9 @@ struct RegisterView: View { } Group { if isPasswordVisible { - SecureField("", text: $viewModel.registerPassword, prompt: Text("Mot de passe").foregroundColor(.gray)) + SecureField("", text: $viewModel.registerPassword, prompt: Text("generic_password").foregroundColor(.gray)) } else { - TextField("", text: $viewModel.registerPassword, prompt: Text("Mot de passe").foregroundColor(.gray)) + TextField("", text: $viewModel.registerPassword, prompt: Text("generic_password").foregroundColor(.gray)) .autocapitalization(.none) } } @@ -146,9 +148,9 @@ struct RegisterView: View { Group { if isPasswordVisible { - SecureField("", text: $viewModel.registerConfirmPassword, prompt: Text("Confirmation du Mot de passe").foregroundColor(.gray)) + SecureField("", text: $viewModel.registerConfirmPassword, prompt: Text("register_confirm_password").foregroundColor(.gray)) } else { - TextField("", text: $viewModel.registerConfirmPassword, prompt: Text("Confirmation du Mot de passe").foregroundColor(.gray)) + TextField("", text: $viewModel.registerConfirmPassword, prompt: Text("register_confirm_password").foregroundColor(.gray)) .autocapitalization(.none) } } @@ -180,7 +182,7 @@ struct RegisterView: View { Button(action: { viewModel.register() }) { - Text("S'inscrire") + Text("generic_register") .textStyle(weight: .bold, color: .white, size: 17) .frame(width: 300, height: 60) @@ -195,13 +197,13 @@ struct RegisterView: View { Spacer() - HStack(spacing: 0) { - Text("Tu as déjà un compte? ") + HStack(spacing: 4) { + Text("generic_already_have_account") .textStyle(weight: .regular, color: AllInColors.darkBlueColor, size: 16) NavigationLink(destination: LoginView().navigationBarBackButtonHidden(true)) { - Text("Se connecter") + Text("generic_login") .textStyle(weight: .semibold, color: AllInColors.darkPurpleColor, size: 16) } } @@ -215,7 +217,7 @@ struct RegisterView: View { } .alert(isPresented: $viewModel.showErrorMessage) { - Alert(title: Text("Erreur lors de l'enregistrement"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("OK"))) + Alert(title: Text("register_error_title"), message: Text(viewModel.errorMessage ?? ""), dismissButton: .default(Text("generic_ok"))) } .background(AllInColors.startBackgroundColor) .onSubmit { diff --git a/Sources/AllInApp/AllIn/Views/WelcomeView.swift b/Sources/AllInApp/AllIn/Views/WelcomeView.swift index 768683f..d16783f 100644 --- a/Sources/AllInApp/AllIn/Views/WelcomeView.swift +++ b/Sources/AllInApp/AllIn/Views/WelcomeView.swift @@ -15,7 +15,7 @@ struct WelcomeView: View { VStack(alignment: .leading, spacing: -5) { Spacer() Spacer() - Text("Bienvenue sur,") + Text("welcome_title") .textStyle(weight: .bold, color: AllInColors.darkBlueColor, size: 30) .frame(alignment: .topLeading) .frame(width: geometry.size.width, alignment: .topLeading) @@ -54,7 +54,7 @@ struct WelcomeView: View { endPoint: UnitPoint(x: 0.5, y: 0.85) )) VStack() { - Text("Récupère tes Allcoins et vient parier avec tes amis pour prouver qui est le meilleur.") + Text("welcome_subtitle") .textStyle(weight: .regular, color: AllInColors.darkBlueColor, size: 15) .frame(width: geometry.size.width*0.8, alignment: .leading) .padding([.leading,.trailing], 40) @@ -64,20 +64,20 @@ struct WelcomeView: View { NavigationLink(destination: RegisterView().navigationBarBackButtonHidden(true)) { - Text("Rejoindre") + Text("welcome_join") .textStyle(weight: .bold, color: AllInColors.whiteColor, size: 17) .frame(width: min(geometry.size.width*0.85, 500), height: 50) .background(AllInColors.loginPurpleColor) .cornerRadius(30) } - HStack(spacing: 0) { - Text("Tu as déja un compte? ") + HStack(spacing: 4) { + Text("generic_already_have_account") .textStyle(weight: .regular, color: AllInColors.loginPurpleColor, size: 16) NavigationLink(destination: LoginView().navigationBarBackButtonHidden(true)) { - Text("Connexion") + Text("generic_login") .textStyle(weight: .semibold, color: AllInColors.loginPurpleColor, size: 16) .underline() } diff --git a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj index 3b1a353..1acba34 100644 --- a/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj +++ b/Sources/AllInApp/AllInApp.xcodeproj/project.pbxproj @@ -78,6 +78,7 @@ ECB7BC6C2B2F43EE002A6654 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB7BC6B2B2F43EE002A6654 /* AppState.swift */; }; ECB7BC702B336E28002A6654 /* RegisterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB7BC6F2B336E28002A6654 /* RegisterViewModel.swift */; }; ECCD244A2B4DE8010071FA9E /* Api in Frameworks */ = {isa = PBXBuildFile; productRef = ECCD24492B4DE8010071FA9E /* Api */; }; + ECDDD48A2BF4A7920009223A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = ECDDD48C2BF4A7920009223A /* Localizable.strings */; }; ECED90B52B6D9CEC00F50937 /* DailyGiftPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */; }; ECF872662B9266C000F9D240 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF872652B9266C000F9D240 /* WidgetKit.framework */; }; ECF872682B9266C000F9D240 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ECF872672B9266C000F9D240 /* SwiftUI.framework */; }; @@ -215,6 +216,8 @@ ECB7BC672B2F1ADF002A6654 /* LoginViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewModel.swift; sourceTree = ""; }; ECB7BC6B2B2F43EE002A6654 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = ""; }; ECB7BC6F2B336E28002A6654 /* RegisterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegisterViewModel.swift; sourceTree = ""; }; + ECDDD48B2BF4A7920009223A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + ECDDD48D2BF4A7970009223A /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; ECED90B42B6D9CEC00F50937 /* DailyGiftPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyGiftPage.swift; sourceTree = ""; }; ECF872642B9266C000F9D240 /* AllInWidgetsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AllInWidgetsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; ECF872652B9266C000F9D240 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; @@ -360,6 +363,7 @@ children = ( EC6B96CE2B24B8D900FC1C58 /* Config.swift */, EC3077082B24CF7F0060E34D /* Colors.swift */, + ECDDD48C2BF4A7920009223A /* Localizable.strings */, ); path = Ressources; sourceTree = ""; @@ -594,6 +598,7 @@ knownRegions = ( en, Base, + fr, ); mainGroup = EC6B968F2B24B4CC00FC1C58; packageReferences = ( @@ -616,6 +621,7 @@ buildActionMask = 2147483647; files = ( EC650A622B28CB72003AFCAD /* Launch Screen.storyboard in Resources */, + ECDDD48A2BF4A7920009223A /* Localizable.strings in Resources */, EC6B96A32B24B4CC00FC1C58 /* Preview Assets.xcassets in Resources */, EC6B96A02B24B4CC00FC1C58 /* Assets.xcassets in Resources */, ); @@ -765,6 +771,18 @@ }; /* End PBXTargetDependency section */ +/* Begin PBXVariantGroup section */ + ECDDD48C2BF4A7920009223A /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + ECDDD48B2BF4A7920009223A /* en */, + ECDDD48D2BF4A7970009223A /* fr */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + /* Begin XCBuildConfiguration section */ EC6B96BA2B24B4CC00FC1C58 /* Debug */ = { isa = XCBuildConfiguration;