mirror of
https://github.com/ManInDark/HabitTrove.git
synced 2026-03-09 20:09:50 +01:00
fix: remove FormattedNumber
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user