diff --git a/guard_app/src/api/guardScore.ts b/guard_app/src/api/guardScore.ts new file mode 100644 index 000000000..797bfa102 --- /dev/null +++ b/guard_app/src/api/guardScore.ts @@ -0,0 +1,47 @@ +import axios from 'axios'; + +import http from '../lib/http'; + +export type GuardScore = { + guardId?: string; + score?: number; + rating?: number; + performanceScore?: number; + currentRating?: number; + completedShifts?: number; + totalShifts?: number; + attendanceRate?: number; + punctualityRate?: number; + summary?: string; + message?: string; +}; + +export async function getGuardScore(guardId: string): Promise { + if (!guardId || guardId === 'undefined' || guardId === 'null') { + throw new Error('Missing valid guardId for score request'); + } + + try { + const response = await http.get<{ success: boolean; data: GuardScore }>( + `/users/guards/${guardId}/score`, + ); + + return response.data.data; + } catch (error) { + throw new Error( + `Failed to fetch guard score (${ + axios.isAxiosError(error) ? error.response?.status : 'unknown' + })`, + ); + } +} + +export async function fetchGuardScore(guardId?: string): Promise { + if (!guardId) return null; + + try { + return await getGuardScore(guardId); + } catch { + return null; + } +} diff --git a/guard_app/src/screen/HomeScreen.tsx b/guard_app/src/screen/HomeScreen.tsx index 350e7c240..952614bef 100644 --- a/guard_app/src/screen/HomeScreen.tsx +++ b/guard_app/src/screen/HomeScreen.tsx @@ -5,6 +5,8 @@ import { useFocusEffect, useNavigation } from '@react-navigation/native'; import { NativeStackNavigationProp } from '@react-navigation/native-stack'; import { useCallback, useLayoutEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import { fetchGuardScore, GuardScore } from '../api/guardScore'; +import { getUserProfile } from '../api/profile'; import { Button, Dimensions, @@ -124,6 +126,7 @@ export default function HomeScreen() { const [todayShifts, setTodayShifts] = useState([]); const [upcomingShifts, setUpcomingShifts] = useState([]); const [refreshing, setRefreshing] = useState(false); + const [guardScore, setGuardScore] = useState(null); useLayoutEffect(() => { navigation.setOptions({ @@ -171,6 +174,16 @@ export default function HomeScreen() { try { const { data: u } = await http.get('/users/me'); setUser(u); + try { + const profile = await getUserProfile(); + const guardId = profile?._id; + const score = await fetchGuardScore(guardId); + if (score) { + setGuardScore(score); + } + } catch { + setGuardScore(null); + } const { data: myShifts } = await http.get('/shifts/myshifts'); @@ -253,7 +266,13 @@ export default function HomeScreen() { } label={t('home.currentRating')} - value={metrics.rating} + value={ + guardScore?.rating + ? guardScore.rating.toFixed(1) + : guardScore?.score + ? guardScore.score.toFixed(1) + : '0.0' + } extraStyle={styles.tintPurple} colors={colors} /> diff --git a/guard_app/src/screen/ProfileScreen.tsx b/guard_app/src/screen/ProfileScreen.tsx index 879ae80fc..0d741d7eb 100644 --- a/guard_app/src/screen/ProfileScreen.tsx +++ b/guard_app/src/screen/ProfileScreen.tsx @@ -16,6 +16,7 @@ import { } from 'react-native'; import { getUserProfile } from '../api/profile'; +import { fetchGuardScore, GuardScore } from '../api/guardScore'; import { LocalStorage } from '../lib/localStorage'; import { LicenseStatus } from '../models/License'; import { UserProfile } from '../models/UserProfile'; @@ -31,6 +32,7 @@ export default function ProfileScreen({ navigation, route }: any) { const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [profileImage, setProfileImage] = useState(null); + const [guardScore, setGuardScore] = useState(null); const handleEditProfile = () => { navigation.navigate('EditProfile', { userProfile: data }); @@ -53,6 +55,14 @@ export default function ProfileScreen({ navigation, route }: any) { const profile = await getUserProfile(); setData(profile); + + const guardId = profile?._id; + + const score = await fetchGuardScore(guardId); + + if (score) { + setGuardScore(score); + } } catch (e: any) { setError(e?.message || 'Failed to load profile'); } finally { @@ -153,12 +163,18 @@ export default function ProfileScreen({ navigation, route }: any) { - 140 + + {guardScore?.totalShifts ?? 0} + {t('profile.totalShifts')} - {data?.rating ? data.rating.toFixed(1) : '0.0'} + {guardScore?.rating + ? guardScore.rating.toFixed(1) + : guardScore?.score + ? guardScore.score.toFixed(1) + : '0.0'} {t('profile.rating')}