Files
paul 9819d8db0b
continuous-integration/drone/push Build is failing
feat: Notifications page, Sidebar layout fixes, and Achievements enhancements
- implemented /notifications page with overdue/upcoming alerts
- Fixed sidebar scrolling in collapsed mode
- Moved notification button to sidebar footer
- Enhanced Achievements page with streak stats and tooltips
- Improved XP history to show task titles
- Added missing translations (en/de)
- Removed top bar header
- Fixed Docker environment routing
2025-12-17 10:06:36 +01:00

79 lines
2.4 KiB
TypeScript

export const LEVEL_THRESHOLDS = [
0, // Level 1: 0-99
100, // Level 2: 100-249
250, // Level 3: 250-499
500, // Level 4: 500-999
1000, // Level 5: 1000-1999
2000, // Level 6: 2000-3499
3500, // Level 7: 3500-4999
5000, // Level 8: 5000-7499
7500, // Level 9: 7500-9999
10000, // Level 10: 10000-14999
15000, // Level 11: 15000-24999
25000, // Level 12: 25000-39999
40000, // Level 13: 40000-59999
60000, // Level 14: 60000-84999
85000, // Level 15: 85000-119999
120000, // Level 16: 120000-159999
160000, // Level 17: 160000-209999
210000, // Level 18: 210000-269999
270000, // Level 19: 270000-349999
350000 // Level 20: 350000+
];
export function getLevelFromXP(xp: number): number {
for (let i = LEVEL_THRESHOLDS.length - 1; i >= 0; i--) {
if (xp >= LEVEL_THRESHOLDS[i]) {
return i + 1;
}
}
return 1;
}
export function getNextLevelXP(level: number): number {
if (level >= LEVEL_THRESHOLDS.length) {
return LEVEL_THRESHOLDS[LEVEL_THRESHOLDS.length - 1] * 1.5; // Scale indefinitely
}
return LEVEL_THRESHOLDS[level];
}
export function getLevelProgress(xp: number): number {
const currentLevel = getLevelFromXP(xp);
const currentLevelStart = LEVEL_THRESHOLDS[currentLevel - 1];
const nextLevelStart = getNextLevelXP(currentLevel);
if (xp >= nextLevelStart) return 100;
const progress = ((xp - currentLevelStart) / (nextLevelStart - currentLevelStart)) * 100;
return Math.min(100, Math.max(0, progress));
}
export const RANK_KEYS = [
'novice', // Level 1
'apprentice', // Level 2
'journeyman', // Level 3
'artisan', // Level 4
'expert', // Level 5
'master', // Level 6
'grandmaster', // Level 7
'virtuoso', // Level 8
'legend', // Level 9
'mythic', // Level 10
'titan', // Level 11
'sentinel', // Level 12
'vanguard', // Level 13
'oracle', // Level 14
'ascendant', // Level 15
'ethereal', // Level 16
'celestial', // Level 17
'divine', // Level 18
'omnipotent', // Level 19
'eternal' // Level 20
];
export function getRankKey(level: number): string {
if (level <= 0) return 'novice';
if (level > RANK_KEYS.length) return RANK_KEYS[RANK_KEYS.length - 1];
return RANK_KEYS[level - 1];
}