From cf6f4f51213a2f5418c292585e136af399596876 Mon Sep 17 00:00:00 2001 From: sansan88 Date: Thu, 20 Jun 2024 17:46:07 +0200 Subject: [PATCH] Neue Version 1.5.2 --- android/app/build.gradle | 4 +- ios/App/App.xcodeproj/project.pbxproj | 8 +- package-lock.json | 4 +- package.json | 2 +- .../championship-detail.page.html | 2 +- .../championship-detail.page.ts | 158 ++++++++---------- src/app/pages/profile/profile.page.html | 2 +- .../training-detail/training-detail.page.ts | 110 +++++++----- .../training/trainings/trainings.page.html | 2 +- src/assets/lang/de.json | 1 - src/assets/lang/en.json | 1 - src/assets/lang/fr.json | 1 - src/assets/lang/it.json | 1 - 13 files changed, 147 insertions(+), 149 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index cbbba6e4..5dd21edf 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "app.myclub.defaultapp" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 36 - versionName "1.5.0" + versionCode 38 + versionName "1.5.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index faa675b7..20a034e4 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -389,7 +389,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/AppDebug.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 38; DEVELOPMENT_TEAM = U7DQUX87VS; INFOPLIST_FILE = App/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = myclub; @@ -399,7 +399,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5.0; + MARKETING_VERSION = 1.5.2; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = app.myclub.default; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -416,7 +416,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = App/AppRelease.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 36; + CURRENT_PROJECT_VERSION = 38; DEVELOPMENT_TEAM = U7DQUX87VS; INFOPLIST_FILE = App/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = myclub; @@ -426,7 +426,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.5.0; + MARKETING_VERSION = 1.5.2; PRODUCT_BUNDLE_IDENTIFIER = app.myclub.default; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; diff --git a/package-lock.json b/package-lock.json index 109fcd6c..c3683ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "myclub", - "version": "1.4.15", + "version": "1.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "myclub", - "version": "1.4.15", + "version": "1.5.0", "dependencies": { "@angular/common": "^17.3.10", "@angular/core": "^17.3.10", diff --git a/package.json b/package.json index 6a883fd1..5212345a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "myclub", - "version": "1.5.0", + "version": "1.5.2", "author": "liitu consulting gmbh", "homepage": "https://my-club.app/", "scripts": { diff --git a/src/app/pages/championship/championship-detail/championship-detail.page.html b/src/app/pages/championship/championship-detail/championship-detail.page.html index 7deb43bf..37983d0d 100644 --- a/src/app/pages/championship/championship-detail/championship-detail.page.html +++ b/src/app/pages/championship/championship-detail/championship-detail.page.html @@ -15,7 +15,7 @@ - + diff --git a/src/app/pages/championship/championship-detail/championship-detail.page.ts b/src/app/pages/championship/championship-detail/championship-detail.page.ts index 37727b9e..ab380865 100644 --- a/src/app/pages/championship/championship-detail/championship-detail.page.ts +++ b/src/app/pages/championship/championship-detail/championship-detail.page.ts @@ -8,7 +8,7 @@ import { } from "@angular/core"; import { ModalController, - NavController, + // NavController, NavParams, ToastController, } from "@ionic/angular"; @@ -27,7 +27,7 @@ import { User } from "@angular/fire/auth"; import { catchError, map, switchMap, take, tap } from "rxjs/operators"; import { UserProfileService } from "src/app/services/firebase/user-profile.service"; import { environment } from "src/environments/environment"; -import { ActivatedRoute } from "@angular/router"; +// import { ActivatedRoute } from "@angular/router"; import { TranslateService } from "@ngx-translate/core"; import { LineupPage } from "../lineup/lineup.page"; import { Profile } from "src/app/models/user"; @@ -111,105 +111,88 @@ export class ChampionshipDetailPage implements OnInit { } } // ng - getGame(teamId: string, gameId: string) { return this.authService.getUser$().pipe( take(1), tap((user) => { + this.setMap(); this.user = user; - if (!user) { - console.log("No user found"); - throw new Error("User not found"); - } + if (!user) throw new Error("User not found"); }), switchMap(() => this.championshipService.getTeamGameRef(teamId, gameId)), switchMap((game) => { if (!game) return of(null); - // Get both attendees and team members in parallel - return combineLatest([ - this.championshipService.getTeamGameAttendeesRef(teamId, gameId), - this.fbService.getTeamMemberRefs(teamId) - ]).pipe( - /*return this.championshipService - .getTeamGameAttendeesRef(teamId, gameId) - .pipe( - switchMap((attendees) => {*/ - switchMap(([attendees, teamMembers]) => { - if (attendees.length === 0) { - // If no attendees, return event data immediately - return of({ - ...game, - attendees: [], - attendeeListTrue: [], - attendeeListFalse: [], - status: null, - }); - } - const attendeeProfiles$ = attendees.map((attendee) => - this.userProfileService.getUserProfileById(attendee.id).pipe( - take(1), - map((profile) => ({ ...profile, ...attendee })), // Combine attendee object with profile - catchError(() => - of({ - ...attendee, - firstName: "Unknown", - lastName: "Unknown", - }) - ) - ) - ); - // Fetch profiles for all club members - const teamMemberProfiles$ = teamMembers.map(member => - this.userProfileService.getUserProfileById(member.id).pipe( - take(1), - catchError(() => of({ ...member, firstName: "Unknown", lastName: "Unknown" })) - ) + + // Fetch all team members first + return this.fbService.getTeamMemberRefs(teamId).pipe( + switchMap(teamMembers => { + const teamMemberProfiles$ = teamMembers.map(member => + this.userProfileService.getUserProfileById(member.id).pipe( + take(1), + catchError(err => { + console.log(`Failed to fetch profile for team member ${member.id}:`, err); + return of({ ...member, firstName: "Unknown", lastName: "Unknown", status: null }); + }) + ) ); - //return forkJoin(attendeeProfiles$).pipe( - //map((attendeesWithDetails) => { - return combineLatest([forkJoin(attendeeProfiles$), forkJoin(teamMemberProfiles$)]).pipe( - map(([attendeesWithDetails, teamMembersWithDetails]) => { - // Find the attendee that matches the current user's ID - const userAttendee = attendeesWithDetails.find( - (att) => att.id === this.user.uid - ); + // Fetch all attendees next + return forkJoin(teamMemberProfiles$).pipe( + switchMap(teamMembersWithDetails => { + // Fetch all game attendees next + return this.championshipService.getTeamGameAttendeesRef(teamId, gameId).pipe( + map(attendees => { + const attendeeDetails = attendees.map(attendee => { + const detail = teamMembersWithDetails.find(member => member.id === attendee.id); + return detail ? { ...detail, status: attendee.status } : null; + }).filter(item => item !== null); - // If userAttendee is undefined, status will default to null - const status = userAttendee ? userAttendee.status : null; + const attendeeListTrue = attendeeDetails.filter(att => att.status === true); + const attendeeListFalse = attendeeDetails.filter(att => att.status === false); + const respondedIds = new Set(attendeeDetails.map(att => att.id)); + const unrespondedMembers = teamMembersWithDetails.filter(member => !respondedIds.has(member.id)); - // Determine members who have not responded - const respondedIds = new Set(attendeesWithDetails.map(att => att.id)); - const unrespondedMembers = teamMembersWithDetails.filter(member => !respondedIds.has(member.id)); + const userAttendee = attendeeDetails.find(att => att.id === this.user.uid); + const status = userAttendee ? userAttendee.status : null; - return { - ...game, - attendees: attendeesWithDetails, - attendeeListTrue: attendeesWithDetails.filter( - (e) => e.status === true - ), - attendeeListFalse: attendeesWithDetails.filter( - (e) => e.status === false - ), - unrespondedMembers: unrespondedMembers, - status: status, // use the variable set above - }; - }) - ); - }), - catchError(() => - of({ - ...game, - attendees: [], - attendeeListTrue: [], - attendeeListFalse: [], - unrespondedMembers: [], - status: null, - }) - ) - ); + return { + ...game, + attendees: attendeeDetails, + attendeeListTrue, + attendeeListFalse, + unrespondedMembers, + status, + }; + }), + catchError(err => { + console.error("Error fetching attendees:", err); + return of({ + ...game, + attendees: [], + attendeeListTrue: [], + attendeeListFalse: [], + unrespondedMembers: teamMembers, + status: null + }); + }) + ); + }), + ); + }), + catchError(err => { + console.error("Error fetching team members:", err); + return of({ + ...game, + attendees: [], + attendeeListTrue: [], + attendeeListFalse: [], + unrespondedMembers: [], + status: null + }); + }) + ); }), - catchError((err) => { - console.error("Error in getTrainingWithAttendees:", err); + catchError(err => { + console.error("Error in getGameWithAttendees:", err); return of(null); }) ); @@ -378,3 +361,4 @@ export class ChampionshipDetailPage implements OnInit { } } } + diff --git a/src/app/pages/profile/profile.page.html b/src/app/pages/profile/profile.page.html index 1229aa2f..a9bf7a1f 100644 --- a/src/app/pages/profile/profile.page.html +++ b/src/app/pages/profile/profile.page.html @@ -213,7 +213,7 @@ {{"profile.push__message__activate" | translate}} - {{"profile.push__message__deactivate" | + {{"profile.push__message__deactivate" | translate}} diff --git a/src/app/pages/training/training-detail/training-detail.page.ts b/src/app/pages/training/training-detail/training-detail.page.ts index dbf36425..6b9ace97 100644 --- a/src/app/pages/training/training-detail/training-detail.page.ts +++ b/src/app/pages/training/training-detail/training-detail.page.ts @@ -7,6 +7,7 @@ import { Observable, catchError, combineLatest, + defaultIfEmpty, forkJoin, lastValueFrom, map, @@ -61,69 +62,84 @@ export class TrainingDetailPage implements OnInit { this.exerciseList$ = this.exerciseService.getTeamTrainingExerciseRefs(this.training.teamId, this.training.id); } - getTraining(teamId: string, trainingId: string) { + + getTraining(teamId: string, trainingId: string) { return this.authService.getUser$().pipe( take(1), tap((user) => { this.user = user; if (!user) throw new Error("User not found"); }), - switchMap(() => - this.trainingService.getTeamTrainingRef(teamId, trainingId) - ), + switchMap(() => this.trainingService.getTeamTrainingRef(teamId, trainingId)), switchMap((training) => { if (!training) return of(null); - // Get both attendees and team members in parallel - return combineLatest([ - this.trainingService.getTeamTrainingsAttendeesRef(teamId, trainingId), - this.fbService.getTeamMemberRefs(teamId) - ]).pipe( - switchMap(([attendees, teamMembers]) => { - const attendeeProfiles$ = attendees.map(attendee => - this.userProfileService.getUserProfileById(attendee.id).pipe( - take(1), - map(profile => ({ ...profile, ...attendee })), - catchError(() => of({ ...attendee, firstName: "Unknown", lastName: "Unknown", status: null })) - ) - ); - - // Fetch profiles for all team members + // Fetch all team members first + return this.fbService.getTeamMemberRefs(teamId).pipe( + switchMap(teamMembers => { const teamMemberProfiles$ = teamMembers.map(member => this.userProfileService.getUserProfileById(member.id).pipe( take(1), - catchError(() => of({ ...member, firstName: "Unknown", lastName: "Unknown" })) + catchError(err => { + console.log(`Failed to fetch profile for team member ${member.id}:`, err); + return of({ ...member, firstName: "Unknown", lastName: "Unknown", status: null }); + }) ) ); - return combineLatest([forkJoin(attendeeProfiles$), forkJoin(teamMemberProfiles$)]).pipe( - map(([attendeesWithDetails, teamMembersWithDetails]) => { - const userAttendee = attendeesWithDetails.find(att => att.id === this.user.uid); - const status = userAttendee ? userAttendee.status : null; - - // Determine members who have not responded - const respondedIds = new Set(attendeesWithDetails.map(att => att.id)); - const unrespondedMembers = teamMembersWithDetails.filter(member => !respondedIds.has(member.id)); - - return { - ...training, - attendees: attendeesWithDetails, - attendeeListTrue: attendeesWithDetails.filter(e => e.status === true), - attendeeListFalse: attendeesWithDetails.filter(e => e.status === false), - unrespondedMembers: unrespondedMembers, - status: status, - }; + // Fetch all attendees next + return forkJoin(teamMemberProfiles$).pipe( + switchMap(teamMembersWithDetails => { + return this.trainingService.getTeamTrainingsAttendeesRef(teamId, trainingId).pipe( + map(attendees => { + const attendeeDetails = attendees.map(attendee => { + const detail = teamMembersWithDetails.find(member => member.id === attendee.id); + return detail ? { ...detail, status: attendee.status } : null; + }).filter(item => item !== null); + + const attendeeListTrue = attendeeDetails.filter(att => att.status === true); + const attendeeListFalse = attendeeDetails.filter(att => att.status === false); + const respondedIds = new Set(attendeeDetails.map(att => att.id)); + const unrespondedMembers = teamMembersWithDetails.filter(member => !respondedIds.has(member.id)); + + const userAttendee = attendeeDetails.find(att => att.id === this.user.uid); + const status = userAttendee ? userAttendee.status : null; + + return { + ...training, + attendees: attendeeDetails, + attendeeListTrue, + attendeeListFalse, + unrespondedMembers, + status, + }; + }), + catchError(err => { + console.error("Error fetching attendees:", err); + return of({ + ...training, + attendees: [], + attendeeListTrue: [], + attendeeListFalse: [], + unrespondedMembers: teamMembersWithDetails, + status: null + }); + }) + ); }) ); }), - catchError(() => of({ - ...training, - attendees: [], - attendeeListTrue: [], - attendeeListFalse: [], - unrespondedMembers: [], - status: null - })) + catchError(err => { + console.error("Error fetching team members:", err); + return of({ + ...training, + attendees: [], + attendeeListTrue: [], + attendeeListFalse: [], + unrespondedMembers: [], + status: null + }); + }) ); }), catchError(err => { @@ -133,6 +149,7 @@ export class TrainingDetailPage implements OnInit { ); } + async toggle(status: boolean, training: Training) { console.log( `Set Status ${status} for user ${this.user.uid} and team ${this.training.teamId} and training ${training.id}` @@ -147,7 +164,7 @@ export class TrainingDetailPage implements OnInit { async presentToast() { const toast = await this.toastController.create({ - message: await lastValueFrom(this.translate.get("success__saved")), + message: await lastValueFrom(this.translate.get("common.success__saved")), color: "primary", duration: 2000, position: "top", @@ -200,3 +217,4 @@ export class TrainingDetailPage implements OnInit { } } + diff --git a/src/app/pages/training/trainings/trainings.page.html b/src/app/pages/training/trainings/trainings.page.html index 734cdeb5..cc5418f7 100644 --- a/src/app/pages/training/trainings/trainings.page.html +++ b/src/app/pages/training/trainings/trainings.page.html @@ -76,7 +76,7 @@ - {{"training.upcomming__training_courses" | translate}} + {{"training.upcomming__training" | translate}} diff --git a/src/assets/lang/de.json b/src/assets/lang/de.json index 5c90191b..029d457c 100644 --- a/src/assets/lang/de.json +++ b/src/assets/lang/de.json @@ -178,7 +178,6 @@ }, "traning-detail": {}, "training": { - "upcomming__training_courses": "Kommende Schulungen", "upcomming__training": "Kommende Trainings", "no_training__found": "keine Trainings gefunden", "past__training": "Vergangene Trainings", diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 0f99daa8..471c3023 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -148,7 +148,6 @@ }, "traning-detail": {}, "training": { - "upcomming__training_courses": "Upcoming training courses", "upcomming__training": "Upcoming trainings", "no_training__found": "no trainings found", "past__training": "Past trainings", diff --git a/src/assets/lang/fr.json b/src/assets/lang/fr.json index c032ed80..e955e44f 100644 --- a/src/assets/lang/fr.json +++ b/src/assets/lang/fr.json @@ -148,7 +148,6 @@ }, "traning-detail": {}, "training": { - "upcomming__training_courses": "Formations à venir", "upcomming__training": "Entraînements à venir", "no_training__found": "aucun entraînement trouvé", "past__training": "Entraînements passés", diff --git a/src/assets/lang/it.json b/src/assets/lang/it.json index d17904bf..f7eb5c51 100644 --- a/src/assets/lang/it.json +++ b/src/assets/lang/it.json @@ -148,7 +148,6 @@ }, "traning-detail": {}, "training": { - "upcomming__training_courses": "Corsi di formazione imminenti", "upcomming__training": "Allenamenti imminenti", "no_training__found": "nessun allenamento trovato", "past__training": "Allenamenti passati",