diff --git a/ios/App/Podfile.lock b/ios/App/Podfile.lock index e32cd68f..db7668db 100644 --- a/ios/App/Podfile.lock +++ b/ios/App/Podfile.lock @@ -124,4 +124,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 8e6a2a27555a43af8fdcda646e72fe803c20f937 -COCOAPODS: 1.14.2 +COCOAPODS: 1.11.3 diff --git a/package-lock.json b/package-lock.json index f0cfb4d6..feddc98c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,6 +37,8 @@ "@fortawesome/free-solid-svg-icons": "6.4.2", "@ionic/angular": "7.5.5", "@ionic/pwa-elements": "^3.1.1", + "@ngx-translate/core": "^15.0.0", + "@ngx-translate/http-loader": "^8.0.0", "@tailwindcss/forms": "0.5.6", "@tailwindcss/typography": "0.5.10", "@trapezedev/configure": "7.0.10", @@ -5431,6 +5433,33 @@ "webpack": "^5.54.0" } }, + "node_modules/@ngx-translate/core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz", + "integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==", + "engines": { + "node": "^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0", + "rxjs": "^6.5.5 || ^7.4.0" + } + }, + "node_modules/@ngx-translate/http-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz", + "integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==", + "engines": { + "node": "^16.13.0 || >=18.10.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0", + "@ngx-translate/core": ">=15.0.0", + "rxjs": "^6.5.5 || ^7.4.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -23952,6 +23981,18 @@ "dev": true, "requires": {} }, + "@ngx-translate/core": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/core/-/core-15.0.0.tgz", + "integrity": "sha512-Am5uiuR0bOOxyoercDnAA3rJVizo4RRqJHo8N3RqJ+XfzVP/I845yEnMADykOHvM6HkVm4SZSnJBOiz0Anx5BA==", + "requires": {} + }, + "@ngx-translate/http-loader": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@ngx-translate/http-loader/-/http-loader-8.0.0.tgz", + "integrity": "sha512-SFMsdUcmHF5OdZkL1CHEoSAwbP5EbAOPTLLboOCRRoOg21P4GJx+51jxGdJeGve6LSKLf4Pay7BkTwmE6vxYlg==", + "requires": {} + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", diff --git a/package.json b/package.json index 55310c9c..3a4f336c 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,8 @@ "@fortawesome/free-solid-svg-icons": "6.4.2", "@ionic/angular": "7.5.5", "@ionic/pwa-elements": "^3.1.1", + "@ngx-translate/core": "^15.0.0", + "@ngx-translate/http-loader": "^8.0.0", "@tailwindcss/forms": "0.5.6", "@tailwindcss/typography": "0.5.10", "@trapezedev/configure": "7.0.10", diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 0ba1e9d4..955c8846 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -11,6 +11,7 @@ import { onAuthStateChanged } from "@angular/fire/auth"; import { UserProfileService } from "./services/firebase/user-profile.service"; import { Device, DeviceId, DeviceInfo } from "@capacitor/device"; import { Network, ConnectionStatus } from '@capacitor/network'; +import { TranslateService } from "@ngx-translate/core"; @Component({ selector: "app-root", @@ -36,7 +37,8 @@ export class AppComponent implements OnInit { private readonly fbService: FirebaseService, private readonly profileService: UserProfileService, private readonly router: Router, - public readonly menuCtrl: MenuController + public readonly menuCtrl: MenuController, + private translate: TranslateService, ) { this.initializeApp(); // this.initializeFirebase(); @@ -158,7 +160,7 @@ export class AppComponent implements OnInit { initializeApp(): void { this.showSplashScreen(); - + this.translate.setDefaultLang('de'); this.swUpdate.versionUpdates.subscribe((event: VersionEvent) => { if (event.type === "VERSION_READY") { this.presentAlertUpdateVersion(); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1af31984..6261779f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,7 +9,7 @@ import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { ServiceWorkerModule } from '@angular/service-worker'; import { environment } from '../environments/environment'; -import { HttpClientModule } from '@angular/common/http'; +import { HttpClientModule,HttpClient } from '@angular/common/http'; // import { GraphQLModule } from './graphql.module'; @@ -38,6 +38,8 @@ import { EventDetailPage } from './pages/event/event-detail/event-detail.page'; import { ClubPage } from './pages/club/club.page'; import { TeamPage } from './pages/team/team.page'; import { Capacitor } from '@capacitor/core'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; @NgModule({ @@ -66,6 +68,13 @@ import { Capacitor } from '@capacitor/core'; }), // GraphQLModule, HttpClientModule, + TranslateModule.forRoot({ // <--- add this + loader: { // <--- add this + provide: TranslateLoader, // <--- add this + useFactory: (createTranslateLoader), // <--- add this + deps: [HttpClient] // <--- add this + } // <--- add this + }), provideFirebaseApp(() => { const init = initializeApp(environment.firebase); return init; @@ -96,3 +105,6 @@ import { Capacitor } from '@capacitor/core'; schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class AppModule {} +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/lang/', '.json'); +} \ No newline at end of file diff --git a/src/app/pages/auth/login/login.module.ts b/src/app/pages/auth/login/login.module.ts index b1c5d21b..e0429757 100644 --- a/src/app/pages/auth/login/login.module.ts +++ b/src/app/pages/auth/login/login.module.ts @@ -6,6 +6,7 @@ import { IonicModule } from '@ionic/angular'; import { LoginPageRoutingModule } from './login-routing.module'; import { LoginPage } from './login.page'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ @@ -13,7 +14,8 @@ import { LoginPage } from './login.page'; FormsModule, ReactiveFormsModule, IonicModule, - LoginPageRoutingModule + LoginPageRoutingModule, + TranslateModule ], declarations: [LoginPage] }) diff --git a/src/app/pages/auth/login/login.page.html b/src/app/pages/auth/login/login.page.html index 0d415446..5e5631aa 100644 --- a/src/app/pages/auth/login/login.page.html +++ b/src/app/pages/auth/login/login.page.html @@ -10,12 +10,12 @@

- Melden Dich mit deinem Konto an + {{"login__title" | translate}}

- Oder - - erstelle einen neuen Account + {{"or"|translate}} + + {{"signin_create__account"|translate}}

@@ -25,7 +25,7 @@

@@ -55,15 +55,16 @@

- Passwort vergessen? + {{"forget__password" | translate}}

diff --git a/src/app/pages/auth/login/login.page.ts b/src/app/pages/auth/login/login.page.ts index c981583e..d41cc322 100644 --- a/src/app/pages/auth/login/login.page.ts +++ b/src/app/pages/auth/login/login.page.ts @@ -11,7 +11,8 @@ import { } from "@angular/forms"; import { AlertController, MenuController } from "@ionic/angular"; import { AuthService } from "src/app/services/auth.service"; - +import { TranslateService } from "@ngx-translate/core"; +import { lastValueFrom } from 'rxjs'; @Component({ selector: "app-login", templateUrl: "./login.page.html", @@ -27,9 +28,10 @@ export class LoginPage implements OnInit { private readonly authService: AuthService, private readonly router: Router, private readonly formBuilder: UntypedFormBuilder, - public readonly menuCtrl: MenuController + public readonly menuCtrl: MenuController, + private translate: TranslateService ) { - this.menuCtrl.enable(true,"menu"); + this.menuCtrl.enable(true, "menu"); this.authForm = this.formBuilder.group({ email: ["", Validators.compose([Validators.required, Validators.email])], password: ["", Validators.minLength(6)], @@ -37,7 +39,7 @@ export class LoginPage implements OnInit { } ngOnInit() { - this.menuCtrl.enable(true,"menu"); + this.menuCtrl.enable(true, "menu"); this.user = { email: "", password: "", @@ -60,20 +62,20 @@ export class LoginPage implements OnInit { console.error(err.code); if (err.code == "auth/user-not-found") { - message = "Kein Account mit dieser E-Mail-Adresse gefunden."; + message = await lastValueFrom(this.translate.get("error__no_acount_found")); } else if (err.code == "auth/wrong-password") { - message = "Die Kombination aus Benutzername und Passwort ist falsch."; + message = await lastValueFrom(this.translate.get("error__no_acount_found")); } else if (err.code == "auth/network-request-failed") { - message = "Es gibt ein Problem mit der Netzwerkverbindung."; + message = await lastValueFrom(this.translate.get("error__network_connection")); } else { - + } const alert = await this.alertCtrl.create({ - message: message, - buttons: [{ text: "OK", role: "cancel" }], - }); - alert.present(); + message: message, + buttons: [{ text: await lastValueFrom(this.translate.get("ok")), role: "cancel" }], + }); + alert.present(); } } } diff --git a/src/app/pages/auth/logout/logout.module.ts b/src/app/pages/auth/logout/logout.module.ts index 482999da..73432ede 100644 --- a/src/app/pages/auth/logout/logout.module.ts +++ b/src/app/pages/auth/logout/logout.module.ts @@ -6,6 +6,7 @@ import { IonicModule } from '@ionic/angular'; import { LogoutPageRoutingModule } from './logout-routing.module'; import { LogoutPage } from './logout.page'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ @@ -13,7 +14,8 @@ import { LogoutPage } from './logout.page'; FormsModule, ReactiveFormsModule, IonicModule, - LogoutPageRoutingModule + LogoutPageRoutingModule, + TranslateModule, ], declarations: [LogoutPage] }) diff --git a/src/app/pages/auth/logout/logout.page.html b/src/app/pages/auth/logout/logout.page.html index 44b59137..854e20f2 100644 --- a/src/app/pages/auth/logout/logout.page.html +++ b/src/app/pages/auth/logout/logout.page.html @@ -18,14 +18,14 @@

- Logout war erfolgreich! + {{"logout__success"|translate}}

- zurück zum Login + {{"back_to__login"| translate}}

@@ -35,7 +35,7 @@

Hintergrundbild

diff --git a/src/app/pages/auth/reset-password/reset-password.module.ts b/src/app/pages/auth/reset-password/reset-password.module.ts index 07594e1a..30a882ce 100644 --- a/src/app/pages/auth/reset-password/reset-password.module.ts +++ b/src/app/pages/auth/reset-password/reset-password.module.ts @@ -6,6 +6,7 @@ import { IonicModule } from '@ionic/angular'; import { ResetPasswordPageRoutingModule } from './reset-password-routing.module'; import { ResetPasswordPage } from './reset-password.page'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ @@ -13,7 +14,8 @@ import { ResetPasswordPage } from './reset-password.page'; FormsModule, ReactiveFormsModule, IonicModule, - ResetPasswordPageRoutingModule + ResetPasswordPageRoutingModule, + TranslateModule ], declarations: [ResetPasswordPage] }) diff --git a/src/app/pages/auth/reset-password/reset-password.page.html b/src/app/pages/auth/reset-password/reset-password.page.html index d34a957f..e58c2c3e 100644 --- a/src/app/pages/auth/reset-password/reset-password.page.html +++ b/src/app/pages/auth/reset-password/reset-password.page.html @@ -18,15 +18,15 @@

- Passwort vergessen + {{"forget__password"| translate}}

- oder + {{"or"| translate}} - Login nochmals probieren? + {{"try__login_again"| translate}}

@@ -39,7 +39,7 @@

for="email" class="block text-sm font-medium text-gray-700" > - E-Mail Adresse + {{"email__address"| translate}}
(click)="submitCredentials(authForm)" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white dark:text-white bg-myclublight dark:bg-myclubdark hover:bg-myclubdark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bg-myclubdark" > - Passwort zurücksetzen + {{"reset__password"| translate}}
@@ -84,7 +84,7 @@

background image mountains diff --git a/src/app/pages/auth/reset-password/reset-password.page.ts b/src/app/pages/auth/reset-password/reset-password.page.ts index e2893209..dd0579df 100644 --- a/src/app/pages/auth/reset-password/reset-password.page.ts +++ b/src/app/pages/auth/reset-password/reset-password.page.ts @@ -10,6 +10,8 @@ import { LoadingController, MenuController } from '@ionic/angular'; +import { TranslateService } from '@ngx-translate/core'; +import { lastValueFrom } from 'rxjs'; import { UserCredentialLogin } from 'src/app/models/user'; import { AuthService } from 'src/app/services/auth.service'; @@ -27,7 +29,8 @@ export class ResetPasswordPage implements OnInit { private readonly alertCtrl: AlertController, private readonly router: Router, private readonly formBuilder: UntypedFormBuilder, - private readonly loadingCtrl: LoadingController + private readonly loadingCtrl: LoadingController, + private translate: TranslateService ) { this.menuCtrl.enable(false, 'menu'); this.authForm = this.formBuilder.group({ @@ -44,13 +47,13 @@ export class ResetPasswordPage implements OnInit { }; } - submitCredentials (authForm: UntypedFormGroup): void { + async submitCredentials (authForm: UntypedFormGroup): Promise { if (!authForm.get('email').valid) { // console.log('Form is not valid yet, current value:', authForm.value); this.alertCtrl .create({ - message: 'Formular ist noch fehlerhaft', - buttons: [{ text: 'Ok', role: 'cancel' }] + message: await lastValueFrom(this.translate.get("error__invalid_form")), + buttons: [{ text: await lastValueFrom(this.translate.get("ok")), role: 'cancel' }] }) .then((alert) => { alert.present(); @@ -69,7 +72,7 @@ export class ResetPasswordPage implements OnInit { async presentLoading () { const loading = await this.loadingCtrl.create({ cssClass: 'my-custom-class', - message: 'Bitte warten...', + message: await lastValueFrom(this.translate.get("please__wait"))+'...', duration: 2000 }) await loading.present(); @@ -82,10 +85,10 @@ export class ResetPasswordPage implements OnInit { this.authService.resetPassword(credentials.email).then( async () => { const alert = await this.alertCtrl.create({ - message: 'Suchen Sie in Ihren E-Mails nach einem Link zum Zurücksetzen des Passworts', + message: await lastValueFrom(this.translate.get("check__email_for_reset_link")), buttons: [ { - text: 'Ok', + text: await lastValueFrom(this.translate.get("ok")), role: 'cancel', handler: () => { this.router.navigateByUrl('login'); @@ -98,7 +101,7 @@ export class ResetPasswordPage implements OnInit { async (error) => { const errorAlert = await this.alertCtrl.create({ message: error.message, - buttons: [{ text: 'Ok', role: 'cancel' }] + buttons: [{ text: await lastValueFrom(this.translate.get("ok")), role: 'cancel' }] }) await errorAlert.present(); } diff --git a/src/app/pages/auth/signup/signup.module.ts b/src/app/pages/auth/signup/signup.module.ts index 4dea2b02..3d70e08e 100644 --- a/src/app/pages/auth/signup/signup.module.ts +++ b/src/app/pages/auth/signup/signup.module.ts @@ -6,6 +6,7 @@ import { IonicModule } from '@ionic/angular'; import { SignupPageRoutingModule } from './signup-routing.module'; import { SignupPage } from './signup.page'; +import { TranslateModule } from '@ngx-translate/core'; @NgModule({ imports: [ @@ -13,7 +14,8 @@ import { SignupPage } from './signup.page'; FormsModule, ReactiveFormsModule, IonicModule, - SignupPageRoutingModule + SignupPageRoutingModule, + TranslateModule ], declarations: [SignupPage] }) diff --git a/src/app/pages/auth/signup/signup.page.html b/src/app/pages/auth/signup/signup.page.html index dfbdda7a..b1033d07 100644 --- a/src/app/pages/auth/signup/signup.page.html +++ b/src/app/pages/auth/signup/signup.page.html @@ -18,15 +18,15 @@

- Neuen Account erstellen + {{"signup__title"| translate}}

- Oder + {{"or" | translate}} - bist Du bereits registriert? + {{"already_have__acount" | translate}}

@@ -39,7 +39,7 @@

for="email" class="block text-sm font-medium text-gray-700" > - E-Mail Adresse + {{"email__address"| translate}}
for="password" class="block text-sm font-medium text-gray-700" > - Passwort + {{"password" | translate}}
for="firstName" class="block text-sm font-medium text-gray-700" > - Vorname + {{"first__name" | translate}}
for="lastName" class="block text-sm font-medium text-gray-700" > - Nachname + {{"last__name" | translate}}
(click)="submitCredentials(authForm)" class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white dark:text-white bg-myclublight dark:bg-myclubdark hover:bg-myclubdark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-bg-myclubdark" > - Registrieren + {{"to__register" | translate}}
@@ -143,7 +143,7 @@

Hintergrundbild Berge

diff --git a/src/app/pages/auth/signup/signup.page.ts b/src/app/pages/auth/signup/signup.page.ts index fd335c4e..82846214 100644 --- a/src/app/pages/auth/signup/signup.page.ts +++ b/src/app/pages/auth/signup/signup.page.ts @@ -10,6 +10,8 @@ import { LoadingController, MenuController, } from "@ionic/angular"; +import { TranslateService } from "@ngx-translate/core"; +import { lastValueFrom } from "rxjs"; import { UserCredentialLogin, Profile } from "src/app/models/user"; import { AuthService } from "src/app/services/auth.service"; @@ -29,7 +31,8 @@ export class SignupPage implements OnInit { // private afs: AngularFirestore, public menuCtrl: MenuController, private readonly loadingCtrl: LoadingController, - private readonly router: Router + private readonly router: Router, + private translate: TranslateService ) { this.authForm = this.formBuilder.group({ email: ["", Validators.compose([Validators.required, Validators.email])], @@ -48,13 +51,13 @@ export class SignupPage implements OnInit { this.menuCtrl.enable(false, "menu"); } - submitCredentials(authForm: UntypedFormGroup): void { + async submitCredentials(authForm: UntypedFormGroup): Promise { if (!authForm.valid) { // console.log('Form is not valid yet, current value:', authForm.value); this.alertCtrl .create({ - message: "Formular ist noch fehlerhaft", - buttons: [{ text: "Ok", role: "cancel" }], + message: await lastValueFrom(this.translate.get("error__invalid_form")), + buttons: [{ text: await lastValueFrom(this.translate.get("ok")), role: "cancel" }], }) .then((alert) => { alert.present(); @@ -76,7 +79,7 @@ export class SignupPage implements OnInit { async presentLoading() { const loading = await this.loadingCtrl.create({ cssClass: "my-custom-class", - message: "Bitte warten...", + message: await lastValueFrom(this.translate.get("please__wait"))+"...", duration: 2000, }); await loading.present(); @@ -104,7 +107,7 @@ export class SignupPage implements OnInit { this.alertCtrl .create({ message: err.message, - buttons: [{ text: "Ok", role: "cancel" }], + buttons: [{ text: await lastValueFrom(this.translate.get("ok")), role: "cancel" }], }) .then((alert) => { alert.present(); diff --git a/src/assets/lang/de.json b/src/assets/lang/de.json new file mode 100644 index 00000000..051388a2 --- /dev/null +++ b/src/assets/lang/de.json @@ -0,0 +1,89 @@ +{ + "login__title": "Melden Dich mit deinem Konto an", + "or": "Oder", + "signin_create__account": "erstelle einen neuen Account", + "email__address": "E-Mail Adresse", + "password": "Passwort", + "forget__password": "Passwort vergessen?", + "register": "Anmelden", + "error__no_acount_found": "Kein Account mit dieser E-Mail-Adresse gefunden", + "error__invalid_username_password": "Die Kombination aus Benutzername und Passwort ist falsch.", + "error__network_connection": "Es gibt ein Problem mit der Netzwerkverbindung", + "ok": "OK", + "logout__success": "Logout war erfolgreich!", + "back_to__login": "zurück zum Login", + "backgroud_image__alt": "Hintergrundbild", + "signup__title": "Neuen Account erstellen", + "already_have__acount": "bist Du bereits registriert?", + "first__name": "Vorname", + "last__name": "Nachname", + "to__register": "Registrieren", + "mountain_background__alt": "Hintergrundbild Berge", + "error__invalid_form": "Formular ist noch fehlerhaft", + "please__wait": "Bitte warten", + "try__login_again": "Login nochmals probieren?", + "reset__password": "Passwort zurücksetzen", + "check__email_for_reset_link": "Suchen Sie in Ihren E-Mails nach einem Link zum Zurücksetzen des Passworts", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "", + "": "" +} \ No newline at end of file diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json new file mode 100644 index 00000000..e69de29b diff --git a/src/assets/lang/fr.json b/src/assets/lang/fr.json new file mode 100644 index 00000000..e69de29b diff --git a/src/assets/lang/it.json b/src/assets/lang/it.json new file mode 100644 index 00000000..e69de29b