humanizerx / src /hooks /useUserStats.ts
mmrwinston001's picture
Upload 32 files (#3)
6ce679b verified
// src/hooks/useUserStats.ts
import { useEffect, useState } from 'react';
import { doc, onSnapshot, updateDoc, increment } from 'firebase/firestore';
import { db, auth } from '../firebase';
import { UserStats } from '../types/user';
export const useUserStats = () => {
const [stats, setStats] = useState<UserStats | undefined>(undefined);
useEffect(() => {
if (!auth.currentUser) return;
const userRef = doc(db, 'users', auth.currentUser.uid);
const unsubscribe = onSnapshot(userRef, async (docSnap) => {
if (docSnap.exists()) {
const data = docSnap.data();
// Ensure stats exist
let userStats: UserStats = data.stats || {
textsHumanized: 0,
wordsProcessed: 0,
gptAverage: 0,
totalSessions: 0,
totalDuration: 0,
averageSessionTime: 0,
};
// Backfill totalDuration if missing
if (userStats.totalDuration === undefined) {
const estimatedDuration =
(userStats.averageSessionTime ?? 0) * (userStats.totalSessions ?? 1);
await updateDoc(userRef, { 'stats.totalDuration': estimatedDuration });
userStats.totalDuration = estimatedDuration;
}
// Always recalc averageSessionTime
const avgTime =
(userStats.totalSessions && userStats.totalDuration)
? userStats.totalDuration / userStats.totalSessions
: 0;
userStats.averageSessionTime = avgTime;
setStats(userStats);
}
});
return () => unsubscribe();
}, []);
const updateStats = async (newStats: Partial<UserStats>) => {
if (!auth.currentUser || !stats) return;
const userRef = doc(db, 'users', auth.currentUser.uid);
// Calculate new totalDuration if averageSessionTime or totalSessions are updated
let updatedTotalDuration = stats.totalDuration;
let updatedTotalSessions = stats.totalSessions;
if (newStats.totalSessions !== undefined) {
updatedTotalSessions += newStats.totalSessions;
}
if (newStats.averageSessionTime !== undefined) {
updatedTotalDuration = updatedTotalSessions * newStats.averageSessionTime;
} else if (newStats.totalDuration !== undefined) {
updatedTotalDuration = stats.totalDuration + newStats.totalDuration;
}
const newAvgSessionTime =
updatedTotalSessions > 0 ? updatedTotalDuration / updatedTotalSessions : 0;
await updateDoc(userRef, {
'stats.textsHumanized':
newStats.textsHumanized !== undefined
? increment(newStats.textsHumanized)
: increment(0),
'stats.wordsProcessed':
newStats.wordsProcessed !== undefined
? increment(newStats.wordsProcessed)
: increment(0),
'stats.totalSessions':
newStats.totalSessions !== undefined
? increment(newStats.totalSessions)
: increment(0),
'stats.gptAverage':
newStats.gptAverage !== undefined ? newStats.gptAverage : stats.gptAverage,
'stats.totalDuration': updatedTotalDuration,
'stats.averageSessionTime': newAvgSessionTime,
});
};
return { stats, updateStats };
};