Files
CU_Points/frontend/components/TransactionList.tsx
T
emilandClaude Sonnet 4.6 50b3c4198a feat: initial commit — backend API + student cabinet frontend
- Go backend: auth (JWT), points earn/spend, QR token generation,
  partners, admin grant/stats endpoints with chi router
- Next.js 14 frontend: login, student dashboard, transaction history,
  QR display, partners list
- PostgreSQL migrations (4 tables), Redis cache, Docker Compose
- CORS middleware, role-based route protection, Zustand auth store

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 10:03:27 +03:00

46 lines
1.4 KiB
TypeScript

import type { Transaction } from '@/lib/types';
import { Badge, Spinner } from '@/components/ui';
import { formatDate, formatTransactionAmount } from '@/lib/utils';
interface TransactionListProps {
transactions: Transaction[];
isLoading: boolean;
}
export function TransactionList({ transactions, isLoading }: TransactionListProps) {
if (isLoading) {
return (
<div className="flex justify-center py-10">
<Spinner />
</div>
);
}
if (transactions.length === 0) {
return (
<p className="py-8 text-center text-sm text-gray-500">Пока нет операций</p>
);
}
return (
<ul className="divide-y divide-gray-700">
{transactions.map((tx) => (
<li key={tx.id} className="flex items-center gap-3 py-3">
<Badge type={tx.type} />
<div className="min-w-0 flex-1">
<p className="truncate text-sm font-medium text-gray-100">
{tx.description || (tx.type === 'spend' ? 'Оплата у партнёра' : 'Начисление поинтов')}
</p>
<p className="text-xs text-gray-500">{formatDate(tx.created_at)}</p>
</div>
<span
className={`shrink-0 text-sm font-semibold tabular-nums ${tx.amount >= 0 ? 'text-green-400' : 'text-red-400'}`}
>
{formatTransactionAmount(tx.amount)}
</span>
</li>
))}
</ul>
);
}