'use client' import { useState } from 'react' import { t2d, d2s, getNow, isSameDate } from '@/lib/utils' import { Button } from '@/components/ui/button' import { FormattedNumber } from '@/components/FormattedNumber' import { History, Pencil } from 'lucide-react' import EmptyState from './EmptyState' import { Input } from '@/components/ui/input' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { settingsAtom } from '@/lib/atoms' import Link from 'next/link' import { useAtom } from 'jotai' import { useCoins } from '@/hooks/useCoins' import { TransactionNoteEditor } from './TransactionNoteEditor' export default function CoinsManager() { const { add, remove, updateNote, balance, transactions, coinsEarnedToday, totalEarned, totalSpent, coinsSpentToday, transactionsToday } = useCoins() const [settings] = useAtom(settingsAtom) const DEFAULT_AMOUNT = '0' const [amount, setAmount] = useState(DEFAULT_AMOUNT) const [pageSize, setPageSize] = useState(50) const [currentPage, setCurrentPage] = useState(1) const [note, setNote] = useState('') const handleSaveNote = async (transactionId: string, note: string) => { await updateNote(transactionId, note) } const handleDeleteNote = async (transactionId: string) => { await updateNote(transactionId, '') } const handleAddRemoveCoins = async () => { const numAmount = Number(amount) if (numAmount > 0) { await add(numAmount, "Manual addition", note) setAmount(DEFAULT_AMOUNT) setNote('') } else if (numAmount < 0) { await remove(Math.abs(numAmount), "Manual removal", note) setAmount(DEFAULT_AMOUNT) setNote('') } } return (

Coins Management

๐Ÿ’ฐ
Current Balance
coins
setAmount(e.target.value)} className="text-center text-xl font-medium h-12" />
๐Ÿช™
Statistics
{/* Top Row - Totals */}
Total Earned
๐Ÿช™
Total Spent
๐Ÿ’ธ
Total Transactions
{transactions.length} ๐Ÿ“ˆ
{/* Bottom Row - Today */}
Today's Earned
๐Ÿช™
Today's Spent
๐Ÿ’ธ
Today's Transactions
{transactionsToday} ๐Ÿ“Š
Transaction History
Show: entries
Showing {Math.min((currentPage - 1) * pageSize + 1, transactions.length)} to {Math.min(currentPage * pageSize, transactions.length)} of {transactions.length} entries
{transactions.length === 0 ? ( ) : ( <> {transactions .slice((currentPage - 1) * pageSize, currentPage * pageSize) .map((transaction) => { const getBadgeStyles = () => { switch (transaction.type) { case 'HABIT_COMPLETION': return 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100' case 'HABIT_UNDO': return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-100' case 'WISH_REDEMPTION': return 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-100' case 'MANUAL_ADJUSTMENT': return 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-100' default: return 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-100' } } return (
{transaction.relatedItemId ? ( {transaction.description} ) : (

{transaction.description}

)} {transaction.type.split('_').join(' ')}

{d2s({ dateTime: t2d({ timestamp: transaction.timestamp, timezone: settings.system.timezone }), timezone: settings.system.timezone })}

= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400' }`} > {transaction.amount >= 0 ? '+' : ''}{transaction.amount}
) })}
Page {currentPage} of {Math.ceil(transactions.length / pageSize)}
)}
) }