import React from 'react'; import { db } from '@/lib/db'; import { TrendingUp, TrendingDown, Users, Wallet, CheckCircle2, Calendar, ArrowUpRight, Search, ShieldCheck } from 'lucide-react'; import { format } from 'date-fns'; import { tr } from 'date-fns/locale'; import Link from 'next/link'; import { cookies } from 'next/headers'; import { redirect } from 'next/navigation'; import TransactionChart from '@/components/admin/TransactionChart'; async function getMerchantData(identifier: string) { const isUUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(identifier); // Fetch merchant details const mQueryText = isUUID ? 'SELECT * FROM merchants WHERE id = $1 LIMIT 1' : 'SELECT * FROM merchants WHERE short_id = $1 LIMIT 1'; const mResult = await db.query(mQueryText, [identifier]); const merchant = mResult.rows[0]; if (!merchant) return null; const id = merchant.id; // Always use UUID for internal lookups // Fetch merchant transactions const tResult = await db.query( 'SELECT * FROM transactions WHERE merchant_id = $1 ORDER BY created_at DESC', [id] ); const transactions = tResult.rows; const successfulTransactions = transactions.filter(t => t.status === 'succeeded'); const totalRevenue = successfulTransactions.reduce((acc, t) => acc + Number(t.amount), 0); const successfulCount = successfulTransactions.length; const totalCount = transactions.length; const successRate = totalCount > 0 ? (successfulCount / totalCount) * 100 : 0; // Last 30 days chart data const chartData = Array.from({ length: 30 }, (_, i) => { const d = new Date(); d.setHours(0, 0, 0, 0); d.setDate(d.getDate() - (29 - i)); return { date: d.toISOString().split('T')[0], displayDate: format(d, 'd MMM', { locale: tr }), amount: 0 }; }); successfulTransactions.forEach(t => { const dateStr = new Date(t.created_at).toISOString().split('T')[0]; const dayMatch = chartData.find(d => d.date === dateStr); if (dayMatch) { dayMatch.amount += Number(t.amount); } }); // Fetch merchant balances const bResult = await db.query( 'SELECT network, token, balance, withdrawn FROM merchant_balances WHERE merchant_id = $1', [id] ); const balances = bResult.rows.map(r => ({ network: r.network, token: r.token, amount: parseFloat(r.balance) - parseFloat(r.withdrawn) })); return { merchant, transactions, totalRevenue, successfulCount, successRate, totalCount, chartData, balances }; } export default async function MerchantDashboardPage(props: { params: Promise<{ id: string }>; }) { const resolvedParams = await props.params; const identifier = resolvedParams.id; const data = await getMerchantData(identifier); const cookieStore = await cookies(); if (!data) { return (
Erişmeye çalıştığınız firma ID'si geçersiz veya yetkiniz yok.
Geri DönFirma Yönetim Paneli
Komisyon: %{merchant.fee_percent || '1.0'}Durum
{b.network}
{b.token}
{b.amount.toFixed(4)}
Çekilebilir
Henüz birikmiş bakiye yok
Dönüşüm Özeti
Polygon / BSC / Ethereum Ödemeleri İçin
Adres
{merchant.evm_vault_address || 'Henüz Oluşturulmadı'}
Solana / SPL Token Ödemeleri İçin
Adres
{merchant.sol_vault_address || 'Henüz Oluşturulmadı'}
Toplam Ciro
İşlem Sayısı
Ödeme Girişi Denemesi
Başarı Oranı
Son 30 günlük işlem hacmi
| İşlem No | Referans / Müşteri | Tarih | Tutar | Durum |
|---|---|---|---|---|
| #{t.stripe_pi_id?.slice(-8).toUpperCase() || 'EXT-' + t.id.slice(0, 4)} |
{t.customer_name || t.source_ref_id || 'SİSTEM'}
{t.customer_phone || 'İletişim Yok'}
|
{format(new Date(t.created_at), 'dd MMM yyyy, HH:mm', { locale: tr })} | {Number(t.amount).toLocaleString('tr-TR', { minimumFractionDigits: 2 })} ₺ | {t.status === 'succeeded' ? 'Başarılı' : t.status === 'failed' ? 'Hatalı' : 'Bekliyor'} |
Henüz bir işlem bulunmuyor