diff --git a/CHANGELOG.md b/CHANGELOG.md index f64cc8b..4876af5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Version 0.1.16 + +### Fixed + +- fix performance + ## Version 0.1.15 ### Fixed diff --git a/hooks/useCoins.tsx b/hooks/useCoins.tsx index 4ff69e2..f9b5b18 100644 --- a/hooks/useCoins.tsx +++ b/hooks/useCoins.tsx @@ -1,73 +1,24 @@ import { useAtom } from 'jotai' -import { coinsAtom, settingsAtom } from '@/lib/atoms' +import { + coinsAtom, + settingsAtom, + coinsEarnedTodayAtom, + totalEarnedAtom, + totalSpentAtom, + coinsSpentTodayAtom, + transactionsTodayAtom +} from '@/lib/atoms' import { addCoins, removeCoins } from '@/app/actions/data' import { toast } from '@/hooks/use-toast' -import { getTodayInTimezone, isSameDate, t2d } from '@/lib/utils' export function useCoins() { const [coins, setCoins] = useAtom(coinsAtom) const [settings] = useAtom(settingsAtom) - - const getTotalEarned = () => { - return coins.transactions - .filter(t => { - if (t.type === 'HABIT_COMPLETION' && t.relatedItemId) { - return !coins.transactions.some(undoT => - undoT.type === 'HABIT_UNDO' && - undoT.relatedItemId === t.relatedItemId - ) - } - return t.amount > 0 && t.type !== 'HABIT_UNDO' - }) - .reduce((sum, t) => sum + t.amount, 0) - } - - const getTotalSpent = () => { - return Math.abs( - coins.transactions - .filter(t => t.type === 'WISH_REDEMPTION' || t.type === 'MANUAL_ADJUSTMENT') - .reduce((sum, t) => sum + (t.amount < 0 ? t.amount : 0), 0) - ) - } - - const getCoinsEarnedToday = () => { - const today = getTodayInTimezone(settings.system.timezone) - return coins.transactions - .filter(transaction => - isSameDate(t2d({ timestamp: transaction.timestamp, timezone: settings.system.timezone }), - t2d({ timestamp: today, timezone: settings.system.timezone })) - ) - .reduce((sum, transaction) => { - if (transaction.type !== 'HABIT_UNDO' && transaction.amount > 0) { - return sum + transaction.amount - } - if (transaction.type === 'HABIT_UNDO') { - return sum - Math.abs(transaction.amount) - } - return sum - }, 0) - } - - const getCoinsSpentToday = () => { - const today = getTodayInTimezone(settings.system.timezone) - return Math.abs( - coins.transactions - .filter(t => - isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }), - t2d({ timestamp: today, timezone: settings.system.timezone })) && - t.amount < 0 - ) - .reduce((sum, t) => sum + t.amount, 0) - ) - } - - const getTransactionsToday = () => { - const today = getTodayInTimezone(settings.system.timezone) - return coins.transactions.filter(t => - isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }), - t2d({ timestamp: today, timezone: settings.system.timezone })) - ).length - } + const [coinsEarnedToday] = useAtom(coinsEarnedTodayAtom) + const [totalEarned] = useAtom(totalEarnedAtom) + const [totalSpent] = useAtom(totalSpentAtom) + const [coinsSpentToday] = useAtom(coinsSpentTodayAtom) + const [transactionsToday] = useAtom(transactionsTodayAtom) const add = async (amount: number, description: string) => { if (isNaN(amount) || amount <= 0) { @@ -105,10 +56,10 @@ export function useCoins() { remove, balance: coins.balance, transactions: coins.transactions, - coinsEarnedToday: getCoinsEarnedToday(), - totalEarned: getTotalEarned(), - totalSpent: getTotalSpent(), - coinsSpentToday: getCoinsSpentToday(), - transactionsToday: getTransactionsToday() + coinsEarnedToday, + totalEarned, + totalSpent, + coinsSpentToday, + transactionsToday } } diff --git a/lib/atoms.ts b/lib/atoms.ts index 14f89b7..09a99d7 100644 --- a/lib/atoms.ts +++ b/lib/atoms.ts @@ -5,8 +5,83 @@ import { getDefaultCoinsData, getDefaultWishlistData } from "./types"; +import { getTodayInTimezone, isSameDate, t2d } from "@/lib/utils"; export const settingsAtom = atom(getDefaultSettings()); export const habitsAtom = atom(getDefaultHabitsData()); export const coinsAtom = atom(getDefaultCoinsData()); export const wishlistAtom = atom(getDefaultWishlistData()); + +// Derived atom for coins earned today +export const coinsEarnedTodayAtom = atom((get) => { + const coins = get(coinsAtom); + const settings = get(settingsAtom); + const today = getTodayInTimezone(settings.system.timezone); + return coins.transactions + .filter(transaction => + isSameDate(t2d({ timestamp: transaction.timestamp, timezone: settings.system.timezone }), + t2d({ timestamp: today, timezone: settings.system.timezone })) + ) + .reduce((sum, transaction) => { + if (transaction.type !== 'HABIT_UNDO' && transaction.amount > 0) { + return sum + transaction.amount; + } + if (transaction.type === 'HABIT_UNDO') { + return sum - Math.abs(transaction.amount); + } + return sum; + }, 0); +}); + +// Derived atom for total earned +export const totalEarnedAtom = atom((get) => { + const coins = get(coinsAtom); + return coins.transactions + .filter(t => { + if (t.type === 'HABIT_COMPLETION' && t.relatedItemId) { + return !coins.transactions.some(undoT => + undoT.type === 'HABIT_UNDO' && + undoT.relatedItemId === t.relatedItemId + ); + } + return t.amount > 0 && t.type !== 'HABIT_UNDO'; + }) + .reduce((sum, t) => sum + t.amount, 0); +}); + +// Derived atom for total spent +export const totalSpentAtom = atom((get) => { + const coins = get(coinsAtom); + return Math.abs( + coins.transactions + .filter(t => t.type === 'WISH_REDEMPTION' || t.type === 'MANUAL_ADJUSTMENT') + .reduce((sum, t) => sum + (t.amount < 0 ? t.amount : 0), 0) + ); +}); + +// Derived atom for coins spent today +export const coinsSpentTodayAtom = atom((get) => { + const coins = get(coinsAtom); + const settings = get(settingsAtom); + const today = getTodayInTimezone(settings.system.timezone); + return Math.abs( + coins.transactions + .filter(t => + isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }), + t2d({ timestamp: today, timezone: settings.system.timezone })) && + t.amount < 0 + ) + .reduce((sum, t) => sum + t.amount, 0) + ); +}); + +// Derived atom for transactions today +export const transactionsTodayAtom = atom((get) => { + const coins = get(coinsAtom); + const settings = get(settingsAtom); + const today = getTodayInTimezone(settings.system.timezone); + return coins.transactions.filter(t => + isSameDate(t2d({ timestamp: t.timestamp, timezone: settings.system.timezone }), + t2d({ timestamp: today, timezone: settings.system.timezone })) + ).length; +}); diff --git a/package.json b/package.json index 99a0c78..a475bf8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "habittrove", - "version": "0.1.15", + "version": "0.1.16", "private": true, "scripts": { "dev": "next dev --turbopack",