74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
/**
|
||
* Calculates percentage of savings target met
|
||
* Formula: savings ÷ (savings_target_months × monthly burn)
|
||
*/
|
||
export const useReserveProgress = () => {
|
||
const calculateReserveProgress = (
|
||
currentSavings: number,
|
||
savingsTargetMonths: number,
|
||
monthlyBurn: number
|
||
): number => {
|
||
const targetAmount = savingsTargetMonths * monthlyBurn
|
||
if (targetAmount <= 0) return 100
|
||
return Math.min((currentSavings / targetAmount) * 100, 100)
|
||
}
|
||
|
||
const getReserveProgressStatus = (progressPct: number): 'green' | 'yellow' | 'red' => {
|
||
if (progressPct >= 80) return 'green'
|
||
if (progressPct >= 50) return 'yellow'
|
||
return 'red'
|
||
}
|
||
|
||
const getReserveProgressMessage = (status: 'green' | 'yellow' | 'red'): string => {
|
||
switch (status) {
|
||
case 'red':
|
||
return 'Build savings to your target before increasing paid hours.'
|
||
case 'yellow':
|
||
return 'Savings progress is moderate. Continue building reserves.'
|
||
case 'green':
|
||
return 'Savings target nearly reached or exceeded.'
|
||
}
|
||
}
|
||
|
||
const calculateTargetAmount = (savingsTargetMonths: number, monthlyBurn: number): number => {
|
||
return savingsTargetMonths * monthlyBurn
|
||
}
|
||
|
||
const calculateShortfall = (
|
||
currentSavings: number,
|
||
savingsTargetMonths: number,
|
||
monthlyBurn: number
|
||
): number => {
|
||
const targetAmount = calculateTargetAmount(savingsTargetMonths, monthlyBurn)
|
||
return Math.max(0, targetAmount - currentSavings)
|
||
}
|
||
|
||
const analyzeReserveProgress = (
|
||
currentSavings: number,
|
||
savingsTargetMonths: number,
|
||
monthlyBurn: number
|
||
) => {
|
||
const progressPct = calculateReserveProgress(currentSavings, savingsTargetMonths, monthlyBurn)
|
||
const status = getReserveProgressStatus(progressPct)
|
||
const targetAmount = calculateTargetAmount(savingsTargetMonths, monthlyBurn)
|
||
const shortfall = calculateShortfall(currentSavings, savingsTargetMonths, monthlyBurn)
|
||
|
||
return {
|
||
progressPct: Math.round(progressPct),
|
||
status,
|
||
message: getReserveProgressMessage(status),
|
||
currentSavings,
|
||
targetAmount,
|
||
shortfall
|
||
}
|
||
}
|
||
|
||
return {
|
||
calculateReserveProgress,
|
||
getReserveProgressStatus,
|
||
getReserveProgressMessage,
|
||
calculateTargetAmount,
|
||
calculateShortfall,
|
||
analyzeReserveProgress
|
||
}
|
||
}
|