Last active
July 25, 2024 15:09
-
-
Save MohammadHarisZia/a3ddb60aea8fe8d990d90fcd0b95bcbd to your computer and use it in GitHub Desktop.
Exercise Progress and Total Progress
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable max-lines-per-function */ | |
import { getUser } from '@/core/auth/utils'; | |
import { getSupabaseMobileClient } from '../common'; | |
type ExerciseLimit = { | |
lesson_type: string; | |
level: number; | |
num_exercises: number; | |
}; | |
type UserLevels = { | |
rapid_speech_level: number | null; | |
speech_in_noise_level: number | null; | |
speech_reading_level: number | null; | |
user_id: string; | |
working_memory_level: number | null; | |
}; | |
type ExerciseProgress = { | |
type: string; | |
level: number | null; | |
progress: number; | |
}; | |
const calculateLevelProgress = ( | |
exerciseScores: number, | |
limits: ExerciseLimit[], | |
level: number | |
): number => { | |
const currentLevelLimit = limits.find((limit) => limit.level === level); | |
const previousLevelLimit = limits.find((limit) => limit.level === level - 1); | |
if (!currentLevelLimit) return 0; | |
const startLimit = previousLevelLimit ? previousLevelLimit.num_exercises : 0; | |
const endLimit = currentLevelLimit.num_exercises; | |
const exercisesForLevel = Math.min(exerciseScores, endLimit) - startLimit; | |
if (exercisesForLevel < 0) return 0; | |
const totalExercisesForLevel = endLimit - startLimit; | |
return exercisesForLevel / totalExercisesForLevel; | |
}; | |
export const fetchUserExerciseProgress = async () => { | |
try { | |
const client = getSupabaseMobileClient(); | |
const user = await getUser(); | |
// Fetch user exercise levels | |
const { data: userLevelsData, error: userLevelsError } = await client | |
.from('user_exercise_levels') | |
.select('*') | |
.eq('user_id', user.id); | |
if (userLevelsError || !userLevelsData || userLevelsData.length === 0) { | |
throw new Error('Error fetching user exercise levels'); | |
} | |
const userLevels = userLevelsData[0] as UserLevels; | |
// Fetch exercise limits | |
const { data: exerciseLimitsData, error: exerciseLimitsError } = | |
await client.from('exercise_limits').select('*'); | |
if (exerciseLimitsError || !exerciseLimitsData) { | |
throw new Error('Error fetching exercise limits'); | |
} | |
const exerciseLimits = exerciseLimitsData as ExerciseLimit[]; | |
const exerciseTypes = [ | |
'rapid_speech', | |
'speech_in_noise', | |
'speech_reading', | |
'working_memory', | |
]; | |
const exerciseProgressPromises = exerciseTypes.map(async (type) => { | |
const key = `${type}_level` as keyof UserLevels; | |
// Fetch training exercise scores count | |
const { count: exerciseScoresCount, error: exerciseScoresError } = | |
await client | |
.from('training_exercise_scores') | |
.select('*', { count: 'exact' }) | |
.eq('user_id', user.id) | |
.eq('lesson_type', type); | |
if (exerciseScoresError) { | |
console.error( | |
'Error fetching exercise scores count:', | |
exerciseScoresError | |
); | |
return null; | |
} | |
const userLevel = userLevels[key]; | |
const limitsForType = exerciseLimits.filter( | |
(limit) => limit.lesson_type.toLowerCase().replaceAll(' ', '_') === type | |
); | |
const progressCal = | |
userLevel !== null && exerciseScoresCount | |
? calculateLevelProgress( | |
exerciseScoresCount, | |
limitsForType, | |
Number(userLevel) | |
) | |
: 0; | |
return { | |
type, | |
level: userLevel, | |
progress: progressCal, | |
}; | |
}); | |
const exerciseProgress = ( | |
await Promise.all(exerciseProgressPromises) | |
).filter((item): item is ExerciseProgress => item !== null); | |
// Fetch total exercise scores count | |
const { count: totalExerciseScoresCount, error: totalExerciseScoresError } = | |
await client | |
.from('training_exercise_scores') | |
.select('*', { count: 'exact' }) | |
.eq('user_id', user.id); | |
if (totalExerciseScoresError) { | |
throw new Error('Error fetching total exercise scores count'); | |
} | |
// Fetch total exercise limit | |
const { data: totalExerciseLimitData, error: totalExerciseLimitError } = | |
await client.from('exercise_limits_total').select('*'); | |
if ( | |
totalExerciseLimitError || | |
!totalExerciseLimitData || | |
totalExerciseLimitData.length === 0 | |
) { | |
throw new Error('Error fetching total exercise limit'); | |
} | |
const totalExercise = totalExerciseLimitData[0].num_exercises; | |
return { | |
exerciseProgress, | |
totalProgress: totalExerciseScoresCount | |
? totalExerciseScoresCount / totalExercise | |
: 0, | |
}; | |
} catch (error) { | |
console.error('Error in fetchUserExerciseProgress:', error); | |
return null; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment