feat: add initial application structure with configuration, UI components, and state management
This commit is contained in:
parent
fadf94002c
commit
0af6b17792
56 changed files with 6137 additions and 129 deletions
74
composables/useReserveProgress.ts
Normal file
74
composables/useReserveProgress.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* 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
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue