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>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user