Introduces XP awarding for post creation, daily logins, and profile completion, alongside enhanced level-up notifications and refactored profile data handling. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 9203795e-937a-4306-b81d-b4d5c78c240e Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: ca9f859b-1a66-40d5-a421-8de34f2805fd Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/7c94b7a0-29c7-4f2e-94ef-44b2153872b7/9203795e-937a-4306-b81d-b4d5c78c240e/MdI1YXa Replit-Helium-Checkpoint-Created: true
112 lines
3 KiB
TypeScript
112 lines
3 KiB
TypeScript
import { useCallback } from "react";
|
|
import { useAuth } from "@/contexts/AuthContext";
|
|
import {
|
|
aethexXPService,
|
|
XPEventType,
|
|
XPAwardResult,
|
|
calculateLevel,
|
|
levelProgress,
|
|
xpForNextLevel,
|
|
} from "@/lib/aethex-database-adapter";
|
|
import { aethexToast } from "@/lib/aethex-toast";
|
|
|
|
export interface UseXPReturn {
|
|
awardXP: (eventType: XPEventType, multiplier?: number) => Promise<XPAwardResult>;
|
|
awardCustomXP: (amount: number, reason?: string) => Promise<XPAwardResult>;
|
|
awardStreakBonus: (streakDays: number) => Promise<XPAwardResult>;
|
|
calculateLevel: typeof calculateLevel;
|
|
levelProgress: typeof levelProgress;
|
|
xpForNextLevel: typeof xpForNextLevel;
|
|
}
|
|
|
|
export function useXP(): UseXPReturn {
|
|
const { user } = useAuth();
|
|
|
|
const showLevelUpToast = useCallback((result: XPAwardResult) => {
|
|
if (result.leveledUp) {
|
|
aethexToast.aethex({
|
|
title: `Level Up! Level ${result.newLevel}`,
|
|
description: `You've earned ${result.xpAwarded} XP and reached level ${result.newLevel}!`,
|
|
duration: 6000,
|
|
});
|
|
} else if (result.success && result.xpAwarded > 0) {
|
|
aethexToast.success({
|
|
title: `+${result.xpAwarded} XP`,
|
|
description: `Total: ${result.newTotalXp} XP`,
|
|
duration: 3000,
|
|
});
|
|
}
|
|
}, []);
|
|
|
|
const awardXP = useCallback(
|
|
async (eventType: XPEventType, multiplier: number = 1): Promise<XPAwardResult> => {
|
|
if (!user?.id) {
|
|
return {
|
|
success: false,
|
|
xpAwarded: 0,
|
|
newTotalXp: 0,
|
|
previousLevel: 1,
|
|
newLevel: 1,
|
|
leveledUp: false,
|
|
error: "Not logged in",
|
|
};
|
|
}
|
|
|
|
const result = await aethexXPService.awardXP(user.id, eventType, multiplier);
|
|
showLevelUpToast(result);
|
|
return result;
|
|
},
|
|
[user?.id, showLevelUpToast]
|
|
);
|
|
|
|
const awardCustomXP = useCallback(
|
|
async (amount: number, reason?: string): Promise<XPAwardResult> => {
|
|
if (!user?.id) {
|
|
return {
|
|
success: false,
|
|
xpAwarded: 0,
|
|
newTotalXp: 0,
|
|
previousLevel: 1,
|
|
newLevel: 1,
|
|
leveledUp: false,
|
|
error: "Not logged in",
|
|
};
|
|
}
|
|
|
|
const result = await aethexXPService.awardCustomXP(user.id, amount, reason);
|
|
showLevelUpToast(result);
|
|
return result;
|
|
},
|
|
[user?.id, showLevelUpToast]
|
|
);
|
|
|
|
const awardStreakBonus = useCallback(
|
|
async (streakDays: number): Promise<XPAwardResult> => {
|
|
if (!user?.id) {
|
|
return {
|
|
success: false,
|
|
xpAwarded: 0,
|
|
newTotalXp: 0,
|
|
previousLevel: 1,
|
|
newLevel: 1,
|
|
leveledUp: false,
|
|
error: "Not logged in",
|
|
};
|
|
}
|
|
|
|
const result = await aethexXPService.awardStreakBonus(user.id, streakDays);
|
|
showLevelUpToast(result);
|
|
return result;
|
|
},
|
|
[user?.id, showLevelUpToast]
|
|
);
|
|
|
|
return {
|
|
awardXP,
|
|
awardCustomXP,
|
|
awardStreakBonus,
|
|
calculateLevel,
|
|
levelProgress,
|
|
xpForNextLevel,
|
|
};
|
|
}
|