Compare commits

..

1 Commits

Author SHA1 Message Date
8c9698c048 fix: remove FormattedNumber 2026-03-09 11:53:09 +01:00
7 changed files with 17 additions and 71 deletions

View File

@@ -1,9 +1,8 @@
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Coins } from 'lucide-react'
import { FormattedNumber } from '@/components/FormattedNumber'
import { useAtom } from 'jotai'
import { useTranslations } from 'next-intl'
import { settingsAtom } from '@/lib/atoms' import { settingsAtom } from '@/lib/atoms'
import { useAtom } from 'jotai'
import { Coins } from 'lucide-react'
import { useTranslations } from 'next-intl'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
const TodayEarnedCoins = dynamic(() => import('./TodayEarnedCoins'), { ssr: false }) const TodayEarnedCoins = dynamic(() => import('./TodayEarnedCoins'), { ssr: false })
@@ -21,9 +20,7 @@ export default function CoinBalance({ coinBalance }: { coinBalance: number }) {
<Coins className="h-12 w-12 text-yellow-400 mr-4" /> <Coins className="h-12 w-12 text-yellow-400 mr-4" />
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex flex-col"> <div className="flex flex-col">
<span className="text-4xl font-bold"> <span className="text-4xl font-bold">{coinBalance}</span>
<FormattedNumber amount={coinBalance} settings={settings} />
</span>
<div className="flex items-center gap-1"> <div className="flex items-center gap-1">
<TodayEarnedCoins longFormat={true} /> <TodayEarnedCoins longFormat={true} />
</div> </div>

View File

@@ -1,6 +1,5 @@
'use client' 'use client'
import { FormattedNumber } from '@/components/FormattedNumber'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
@@ -127,7 +126,7 @@ export default function CoinsManager() {
<span className="text-2xl animate-bounce hover:animate-none cursor-default">💰</span> <span className="text-2xl animate-bounce hover:animate-none cursor-default">💰</span>
<div> <div>
<div className="text-sm font-normal text-muted-foreground">{t('currentBalanceLabel')}</div> <div className="text-sm font-normal text-muted-foreground">{t('currentBalanceLabel')}</div>
<div className="text-3xl font-bold"><FormattedNumber amount={balance} settings={settings} /> {t('coinsSuffix')}</div> <div className="text-3xl font-bold">{balance} {t('coinsSuffix')}</div>
</div> </div>
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
@@ -214,16 +213,12 @@ export default function CoinsManager() {
{/* Top Row - Totals */} {/* Top Row - Totals */}
<div className="p-4 rounded-lg bg-green-100 dark:bg-green-900"> <div className="p-4 rounded-lg bg-green-100 dark:bg-green-900">
<div className="text-sm text-green-800 dark:text-green-100 mb-1">{t('totalEarnedLabel')}</div> <div className="text-sm text-green-800 dark:text-green-100 mb-1">{t('totalEarnedLabel')}</div>
<div className="text-2xl font-bold text-green-900 dark:text-green-50"> <div className="text-2xl font-bold text-green-900 dark:text-green-50">{totalEarned} 🪙</div>
<FormattedNumber amount={totalEarned} settings={settings} /> 🪙
</div>
</div> </div>
<div className="p-4 rounded-lg bg-red-100 dark:bg-red-900"> <div className="p-4 rounded-lg bg-red-100 dark:bg-red-900">
<div className="text-sm text-red-800 dark:text-red-100 mb-1">{t('totalSpentLabel')}</div> <div className="text-sm text-red-800 dark:text-red-100 mb-1">{t('totalSpentLabel')}</div>
<div className="text-2xl font-bold text-red-900 dark:text-red-50"> <div className="text-2xl font-bold text-red-900 dark:text-red-50">{totalSpent} 💸</div>
<FormattedNumber amount={totalSpent} settings={settings} /> 💸
</div>
</div> </div>
<div className="p-4 rounded-lg bg-pink-100 dark:bg-pink-900"> <div className="p-4 rounded-lg bg-pink-100 dark:bg-pink-900">
@@ -236,16 +231,12 @@ export default function CoinsManager() {
{/* Bottom Row - Today */} {/* Bottom Row - Today */}
<div className="p-4 rounded-lg bg-blue-100 dark:bg-blue-900"> <div className="p-4 rounded-lg bg-blue-100 dark:bg-blue-900">
<div className="text-sm text-blue-800 dark:text-blue-100 mb-1">{t('todaysEarnedLabel')}</div> <div className="text-sm text-blue-800 dark:text-blue-100 mb-1">{t('todaysEarnedLabel')}</div>
<div className="text-2xl font-bold text-blue-900 dark:text-blue-50"> <div className="text-2xl font-bold text-blue-900 dark:text-blue-50">{coinsEarnedToday} 🪙</div>
<FormattedNumber amount={coinsEarnedToday} settings={settings} /> 🪙
</div>
</div> </div>
<div className="p-4 rounded-lg bg-purple-100 dark:bg-purple-900"> <div className="p-4 rounded-lg bg-purple-100 dark:bg-purple-900">
<div className="text-sm text-purple-800 dark:text-purple-100 mb-1">{t('todaysSpentLabel')}</div> <div className="text-sm text-purple-800 dark:text-purple-100 mb-1">{t('todaysSpentLabel')}</div>
<div className="text-2xl font-bold text-purple-900 dark:text-purple-50"> <div className="text-2xl font-bold text-purple-900 dark:text-purple-50">{coinsSpentToday} 💸</div>
<FormattedNumber amount={coinsSpentToday} settings={settings} /> 💸
</div>
</div> </div>
<div className="p-4 rounded-lg bg-orange-100 dark:bg-orange-900"> <div className="p-4 rounded-lg bg-orange-100 dark:bg-orange-900">

View File

@@ -1,16 +0,0 @@
import { formatNumber } from '@/lib/utils/formatNumber'
import { Settings } from '@/lib/types'
interface FormattedNumberProps {
amount: number
settings: Settings
className?: string
}
export function FormattedNumber({ amount, settings, className }: FormattedNumberProps) {
return (
<span className={`break-all ${className || ''}`}>
{formatNumber({ amount, settings })}
</span>
)
}

View File

@@ -1,13 +1,12 @@
'use client' 'use client'
import Link from 'next/link'
import { useAtom } from 'jotai'
import { settingsAtom } from '@/lib/atoms'
import { useCoins } from '@/hooks/useCoins' import { useCoins } from '@/hooks/useCoins'
import { FormattedNumber } from '@/components/FormattedNumber' import { settingsAtom } from '@/lib/atoms'
import { useAtom } from 'jotai'
import { Coins } from 'lucide-react' import { Coins } from 'lucide-react'
import NotificationBell from './NotificationBell'
import dynamic from 'next/dynamic' import dynamic from 'next/dynamic'
import Link from 'next/link'
import NotificationBell from './NotificationBell'
import { Profile } from './Profile' import { Profile } from './Profile'
const TodayEarnedCoins = dynamic(() => import('./TodayEarnedCoins'), { ssr: false }) const TodayEarnedCoins = dynamic(() => import('./TodayEarnedCoins'), { ssr: false })
@@ -21,11 +20,7 @@ export default function HeaderActions() {
<Link href="/coins" className="flex items-center gap-1 sm:gap-2 px-3 py-1.5 bg-white hover:bg-gray-50 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-full transition-colors border border-gray-200 dark:border-gray-600"> <Link href="/coins" className="flex items-center gap-1 sm:gap-2 px-3 py-1.5 bg-white hover:bg-gray-50 dark:bg-gray-700 dark:hover:bg-gray-600 rounded-full transition-colors border border-gray-200 dark:border-gray-600">
<Coins className="h-5 w-5 text-yellow-500 dark:text-yellow-400" /> <Coins className="h-5 w-5 text-yellow-500 dark:text-yellow-400" />
<div className="flex items-baseline gap-1 sm:gap-2"> <div className="flex items-baseline gap-1 sm:gap-2">
<FormattedNumber <span className="text-gray-800 dark:text-gray-100 font-medium text-lg">{balance}</span>
amount={balance}
settings={settings}
className="text-gray-800 dark:text-gray-100 font-medium text-lg"
/>
<div className="hidden sm:block"> <div className="hidden sm:block">
<TodayEarnedCoins /> <TodayEarnedCoins />
</div> </div>

View File

@@ -1,20 +1,15 @@
import { useAtom } from 'jotai'
import { useTranslations } from 'next-intl'
import { settingsAtom } from '@/lib/atoms'
import { useCoins } from '@/hooks/useCoins' import { useCoins } from '@/hooks/useCoins'
import { FormattedNumber } from '@/components/FormattedNumber' import { useTranslations } from 'next-intl'
export default function TodayEarnedCoins({ longFormat }: { longFormat?: boolean }) { export default function TodayEarnedCoins({ longFormat }: { longFormat?: boolean }) {
const t = useTranslations('TodayEarnedCoins') const t = useTranslations('TodayEarnedCoins')
const [settings] = useAtom(settingsAtom)
const { coinsEarnedToday } = useCoins() const { coinsEarnedToday } = useCoins()
if (coinsEarnedToday <= 0) return <></>; if (coinsEarnedToday <= 0) return <></>;
return ( return (
<span className="text-md text-green-600 dark:text-green-400 font-medium mt-1"> <span className="text-md text-green-600 dark:text-green-400 font-medium mt-1">
{"+"} {"+"}{coinsEarnedToday}
<FormattedNumber amount={coinsEarnedToday} settings={settings} />
{longFormat ? {longFormat ?
<span className="text-sm text-muted-foreground"> {t('todaySuffix')}</span> <span className="text-sm text-muted-foreground"> {t('todaySuffix')}</span>
: null} : null}

View File

@@ -8,7 +8,6 @@ import {
currentUserIdAtom, currentUserIdAtom,
settingsAtom, settingsAtom,
totalEarnedAtom, totalEarnedAtom,
totalSpentAtom,
usersAtom usersAtom
} from '@/lib/atoms'; } from '@/lib/atoms';
import { MAX_COIN_LIMIT } from '@/lib/constants'; import { MAX_COIN_LIMIT } from '@/lib/constants';
@@ -30,7 +29,6 @@ export function useCoins(options?: { selectedUser?: string }) {
const loggedInUserBalance = loggedInUserId ? coins.transactions.filter(transaction => transaction.userId === loggedInUserId).reduce((sum, transaction) => sum + transaction.amount, 0) : 0; const loggedInUserBalance = loggedInUserId ? coins.transactions.filter(transaction => transaction.userId === loggedInUserId).reduce((sum, transaction) => sum + transaction.amount, 0) : 0;
const [atomCoinsEarnedToday] = useAtom(coinsEarnedTodayAtom); const [atomCoinsEarnedToday] = useAtom(coinsEarnedTodayAtom);
const [atomTotalEarned] = useAtom(totalEarnedAtom) const [atomTotalEarned] = useAtom(totalEarnedAtom)
const [atomTotalSpent] = useAtom(totalSpentAtom)
const [atomCoinsSpentToday] = useAtom(coinsSpentTodayAtom); const [atomCoinsSpentToday] = useAtom(coinsSpentTodayAtom);
const targetUser = options?.selectedUser ? users.find(u => u.id === options.selectedUser) : currentUser const targetUser = options?.selectedUser ? users.find(u => u.id === options.selectedUser) : currentUser
@@ -41,7 +39,6 @@ export function useCoins(options?: { selectedUser?: string }) {
const timezone = settings.system.timezone; const timezone = settings.system.timezone;
const [coinsEarnedToday, setCoinsEarnedToday] = useState(0); const [coinsEarnedToday, setCoinsEarnedToday] = useState(0);
const [totalEarned, setTotalEarned] = useState(0); const [totalEarned, setTotalEarned] = useState(0);
const [totalSpent, setTotalSpent] = useState(0);
const [coinsSpentToday, setCoinsSpentToday] = useState(0); const [coinsSpentToday, setCoinsSpentToday] = useState(0);
const [balance, setBalance] = useState(0); const [balance, setBalance] = useState(0);
@@ -51,7 +48,6 @@ export function useCoins(options?: { selectedUser?: string }) {
// If the target user is the currently logged-in user, use the derived atom's value // If the target user is the currently logged-in user, use the derived atom's value
setCoinsEarnedToday(atomCoinsEarnedToday); setCoinsEarnedToday(atomCoinsEarnedToday);
setTotalEarned(atomTotalEarned); setTotalEarned(atomTotalEarned);
setTotalSpent(atomTotalSpent);
setCoinsSpentToday(atomCoinsSpentToday); setCoinsSpentToday(atomCoinsSpentToday);
setBalance(loggedInUserBalance); setBalance(loggedInUserBalance);
} else if (targetUser?.id) { } else if (targetUser?.id) {
@@ -62,9 +58,6 @@ export function useCoins(options?: { selectedUser?: string }) {
const totalEarnedVal = calculateTotalEarned(transactions); const totalEarnedVal = calculateTotalEarned(transactions);
setTotalEarned(roundToInteger(totalEarnedVal)); setTotalEarned(roundToInteger(totalEarnedVal));
const totalSpentVal = calculateTotalSpent(transactions);
setTotalSpent(roundToInteger(totalSpentVal));
const spentToday = calculateCoinsSpentToday(transactions, timezone); const spentToday = calculateCoinsSpentToday(transactions, timezone);
setCoinsSpentToday(roundToInteger(spentToday)); setCoinsSpentToday(roundToInteger(spentToday));
@@ -79,7 +72,6 @@ export function useCoins(options?: { selectedUser?: string }) {
loggedInUserBalance, loggedInUserBalance,
atomCoinsEarnedToday, atomCoinsEarnedToday,
atomTotalEarned, atomTotalEarned,
atomTotalSpent,
atomCoinsSpentToday atomCoinsSpentToday
]); ]);
@@ -180,7 +172,7 @@ export function useCoins(options?: { selectedUser?: string }) {
transactions: transactions, transactions: transactions,
coinsEarnedToday, coinsEarnedToday,
totalEarned, totalEarned,
totalSpent, totalSpent: calculateTotalSpent(coins.transactions),
coinsSpentToday coinsSpentToday
} }
} }

View File

@@ -2,7 +2,6 @@ import {
calculateCoinsEarnedToday, calculateCoinsEarnedToday,
calculateCoinsSpentToday, calculateCoinsSpentToday,
calculateTotalEarned, calculateTotalEarned,
calculateTotalSpent,
generateCryptoHash, generateCryptoHash,
isHabitDue, isHabitDue,
prepareDataForHashing, prepareDataForHashing,
@@ -70,13 +69,6 @@ export const totalEarnedAtom = atom((get) => {
return roundToInteger(value); return roundToInteger(value);
}); });
// Derived atom for total spent
export const totalSpentAtom = atom((get) => {
const coins = get(coinsAtom);
const value = calculateTotalSpent(coins.transactions);
return roundToInteger(value);
});
// Derived atom for coins spent today // Derived atom for coins spent today
export const coinsSpentTodayAtom = atom((get) => { export const coinsSpentTodayAtom = atom((get) => {
const coins = get(coinsAtom); const coins = get(coinsAtom);