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 (

Firma Bulunamadı

Erişmeye çalıştığınız firma ID'si geçersiz veya yetkiniz yok.

Geri Dön
); } // Check Authentication const isAuth = cookieStore.get(`merchant_auth_${data.merchant.id}`) || cookieStore.get(`merchant_auth_${identifier}`); if (!isAuth) { redirect(`/merchant/${identifier}/login`); } const { merchant, transactions, totalRevenue, successfulCount, successRate, totalCount, chartData, balances } = data; const recentTransactions = transactions.slice(0, 8); return (
{/* Merchant Info Header */}
{merchant.name.substring(0, 1).toUpperCase()}

{merchant.name}

Firma Yönetim Paneli

Komisyon: %{merchant.fee_percent || '1.0'}

Durum

Aktif
{/* Balances & Vaults Section */}
{/* Crypto Balances */}

Mevcut Bakiyeleriniz

{balances && balances.length > 0 ? balances.map((b: any, i: number) => (

{b.network}

{b.token}

{b.amount.toFixed(4)}

Çekilebilir

)) : (

Henüz birikmiş bakiye yok

)}

Dönüşüm Özeti

{totalRevenue.toLocaleString('tr-TR', { minimumFractionDigits: 2 })}

{/* Vault Addresses */}

EVM Kasanız

Polygon / BSC / Ethereum Ödemeleri İçin

Adres

{merchant.evm_vault_address || 'Henüz Oluşturulmadı'}

Solana Kasanız

Solana / SPL Token Ödemeleri İçin

Adres

{merchant.sol_vault_address || 'Henüz Oluşturulmadı'}

{/* Stats Cards */}

Toplam Ciro

{totalRevenue.toLocaleString('tr-TR', { minimumFractionDigits: 2 })}

Başarılı İşlemlerden Gelen

İşlem Sayısı

{successfulCount} / {totalCount}

Ödeme Girişi Denemesi

Başarı Oranı

%{successRate.toFixed(1)}

{/* Chart */}

Günlük Gelir Grafiği

Son 30 günlük işlem hacmi

{/* Recent Transactions Table */}

Son İşlemler

Bütün İşlemleri Gör
{recentTransactions.map((t) => ( ))}
İş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'}
{recentTransactions.length === 0 && (

Henüz bir işlem bulunmuyor

)}
); }