← back to Handbag Auth Nextjs

src/app/admin/page.tsx

423 lines

'use client'

import { useState, useEffect } from 'react'
import { LineChart, Line, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'

export default function AdminDashboard() {
  const [stats, setStats] = useState<any>(null)
  const [gmvData, setGmvData] = useState<any[]>([])
  const [activeTab, setActiveTab] = useState('overview')

  useEffect(() => {
    fetchDashboardData()
    // Real-time updates every 0.9 seconds
    const interval = setInterval(fetchDashboardData, 900)
    return () => clearInterval(interval)
  }, [])

  const fetchDashboardData = async () => {
    try {
      const res = await fetch('/api/admin/dashboard')
      const data = await res.json()
      if (data.success) {
        setStats(data.stats)
        setGmvData(data.gmvHistory)
      }
    } catch (error) {
      console.error('Failed to fetch dashboard data:', error)
    }
  }

  // Mock data for demonstration
  const mockStats = {
    totalGMV: 247500,
    monthlyGMV: 45000,
    totalUsers: 5234,
    activeInvestors: 523,
    premiumSubscribers: 78,
    totalRevenue: 12750,
    affiliateRevenue: 5250,
    fractionalRevenue: 4500,
    subscriptionRevenue: 3000,
    avgLTV: 485,
    avgCAC: 127,
    ltvcac: 3.82
  }

  const gmvHistory = [
    { month: 'Jan', gmv: 12500, revenue: 875 },
    { month: 'Feb', gmv: 18700, revenue: 1309 },
    { month: 'Mar', gmv: 25300, revenue: 1771 },
    { month: 'Apr', gmv: 32100, revenue: 2247 },
    { month: 'May', gmv: 45000, revenue: 3150 },
    { month: 'Jun (Proj)', gmv: 62000, revenue: 4340 }
  ]

  const assetsByBrand = [
    { name: 'Hermès', value: 35, color: '#DC2626' },
    { name: 'Chanel', value: 28, color: '#000000' },
    { name: 'Louis Vuitton', value: 22, color: '#92400E' },
    { name: 'Dior', value: 10, color: '#1E40AF' },
    { name: 'Others', value: 5, color: '#6B7280' }
  ]

  const recentInvestments = [
    { id: 1, user: 'Emma S.', asset: 'Hermès Birkin 30 Togo', amount: 2500, shares: 100, time: '2 min ago' },
    { id: 2, user: 'Michael R.', asset: 'Chanel Classic Flap Medium', amount: 1200, shares: 80, time: '8 min ago' },
    { id: 3, user: 'Sarah T.', asset: 'Louis Vuitton Neverfull MM', amount: 450, shares: 45, time: '15 min ago' },
    { id: 4, user: 'James K.', asset: 'Dior Lady Dior Medium', amount: 3200, shares: 160, time: '23 min ago' }
  ]

  const activeFractionalAssets = [
    { id: 1, name: 'Hermès Birkin 30 Togo Gold', totalValue: 42000, fractionsSold: 650, fractionsTotal: 1000, performance: '+12.4%' },
    { id: 2, name: 'Chanel Classic Flap Medium Caviar', totalValue: 12500, fractionsSold: 420, fractionsTotal: 500, performance: '+8.7%' },
    { id: 3, name: 'Louis Vuitton Neverfull MM Monogram', totalValue: 2800, fractionsSold: 180, fractionsTotal: 280, performance: '+3.2%' },
    { id: 4, name: 'Hermès Kelly 28 Epsom Black', totalValue: 38000, fractionsSold: 890, fractionsTotal: 1000, performance: '+15.1%' }
  ]

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-900 via-black to-gray-900 text-white">
      {/* Header */}
      <header className="border-b border-gray-800 bg-black/50 backdrop-blur-xl">
        <div className="max-w-7xl mx-auto px-6 py-4">
          <div className="flex items-center justify-between">
            <div>
              <h1 className="text-2xl font-bold bg-gradient-to-r from-amber-400 to-orange-500 bg-clip-text text-transparent">
                LUXVAULT Admin
              </h1>
              <p className="text-sm text-gray-400 mt-1">Fractional Luxury Investment Platform</p>
            </div>
            <div className="flex items-center space-x-4">
              <div className="px-4 py-2 bg-green-500/20 rounded-lg border border-green-500/30">
                <div className="flex items-center space-x-2">
                  <div className="w-2 h-2 bg-green-400 rounded-full animate-pulse"></div>
                  <span className="text-sm font-semibold text-green-400">Live (0.9s refresh)</span>
                </div>
              </div>
              <button className="px-4 py-2 bg-white/10 hover:bg-white/20 rounded-lg transition-all">
                <span className="text-sm font-semibold">Steve</span>
              </button>
            </div>
          </div>
        </div>
      </header>

      {/* Tab Navigation */}
      <div className="border-b border-gray-800">
        <div className="max-w-7xl mx-auto px-6">
          <div className="flex space-x-8">
            {['overview', 'assets', 'investors', 'automation', 'analytics'].map((tab) => (
              <button
                key={tab}
                onClick={() => setActiveTab(tab)}
                className={`px-4 py-4 text-sm font-semibold border-b-2 transition-all capitalize ${
                  activeTab === tab
                    ? 'border-amber-500 text-amber-400'
                    : 'border-transparent text-gray-400 hover:text-white'
                }`}
              >
                {tab}
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Main Content */}
      <main className="max-w-7xl mx-auto px-6 py-8">
        {activeTab === 'overview' && (
          <div className="space-y-8">
            {/* Key Metrics Grid */}
            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
              {/* Total GMV */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <div className="flex items-center justify-between mb-4">
                  <span className="text-gray-400 text-sm font-medium">Total GMV</span>
                  <div className="w-10 h-10 bg-green-500/20 rounded-lg flex items-center justify-center">
                    <span className="text-xl">💰</span>
                  </div>
                </div>
                <div className="text-3xl font-bold text-white mb-2">
                  ${mockStats.totalGMV.toLocaleString()}
                </div>
                <div className="text-sm text-green-400 font-semibold">
                  +${mockStats.monthlyGMV.toLocaleString()} this month
                </div>
              </div>

              {/* Total Users */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <div className="flex items-center justify-between mb-4">
                  <span className="text-gray-400 text-sm font-medium">Total Users</span>
                  <div className="w-10 h-10 bg-blue-500/20 rounded-lg flex items-center justify-center">
                    <span className="text-xl">👥</span>
                  </div>
                </div>
                <div className="text-3xl font-bold text-white mb-2">
                  {mockStats.totalUsers.toLocaleString()}
                </div>
                <div className="text-sm text-blue-400 font-semibold">
                  {mockStats.activeInvestors} active investors (10%)
                </div>
              </div>

              {/* Total Revenue */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <div className="flex items-center justify-between mb-4">
                  <span className="text-gray-400 text-sm font-medium">Total Revenue</span>
                  <div className="w-10 h-10 bg-amber-500/20 rounded-lg flex items-center justify-center">
                    <span className="text-xl">📈</span>
                  </div>
                </div>
                <div className="text-3xl font-bold text-white mb-2">
                  ${mockStats.totalRevenue.toLocaleString()}
                </div>
                <div className="text-sm text-amber-400 font-semibold">
                  7.2% effective take rate
                </div>
              </div>

              {/* LTV/CAC Ratio */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <div className="flex items-center justify-between mb-4">
                  <span className="text-gray-400 text-sm font-medium">LTV / CAC</span>
                  <div className="w-10 h-10 bg-purple-500/20 rounded-lg flex items-center justify-center">
                    <span className="text-xl">🎯</span>
                  </div>
                </div>
                <div className="text-3xl font-bold text-white mb-2">
                  {mockStats.ltvcac.toFixed(2)}x
                </div>
                <div className="text-sm text-purple-400 font-semibold">
                  ${mockStats.avgLTV} LTV / ${mockStats.avgCAC} CAC
                </div>
              </div>
            </div>

            {/* GMV Growth Chart */}
            <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
              <h2 className="text-xl font-bold mb-6">GMV & Revenue Growth</h2>
              <ResponsiveContainer width="100%" height={300}>
                <LineChart data={gmvHistory}>
                  <CartesianGrid strokeDasharray="3 3" stroke="#374151" />
                  <XAxis dataKey="month" stroke="#9CA3AF" />
                  <YAxis stroke="#9CA3AF" />
                  <Tooltip
                    contentStyle={{
                      backgroundColor: '#1F2937',
                      border: '1px solid #374151',
                      borderRadius: '8px'
                    }}
                  />
                  <Line type="monotone" dataKey="gmv" stroke="#F59E0B" strokeWidth={3} name="GMV ($)" />
                  <Line type="monotone" dataKey="revenue" stroke="#10B981" strokeWidth={3} name="Revenue ($)" />
                </LineChart>
              </ResponsiveContainer>
            </div>

            {/* Revenue Breakdown & Assets by Brand */}
            <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
              {/* Revenue Breakdown */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <h2 className="text-xl font-bold mb-6">Revenue Breakdown</h2>
                <div className="space-y-4">
                  <div>
                    <div className="flex items-center justify-between mb-2">
                      <span className="text-gray-400">Affiliate Commissions</span>
                      <span className="font-bold text-white">${mockStats.affiliateRevenue.toLocaleString()}</span>
                    </div>
                    <div className="w-full h-3 bg-gray-700 rounded-full overflow-hidden">
                      <div className="h-full bg-gradient-to-r from-blue-500 to-cyan-400" style={{ width: '41%' }}></div>
                    </div>
                  </div>
                  <div>
                    <div className="flex items-center justify-between mb-2">
                      <span className="text-gray-400">Fractional Trading Fees</span>
                      <span className="font-bold text-white">${mockStats.fractionalRevenue.toLocaleString()}</span>
                    </div>
                    <div className="w-full h-3 bg-gray-700 rounded-full overflow-hidden">
                      <div className="h-full bg-gradient-to-r from-purple-500 to-pink-400" style={{ width: '35%' }}></div>
                    </div>
                  </div>
                  <div>
                    <div className="flex items-center justify-between mb-2">
                      <span className="text-gray-400">Premium Subscriptions</span>
                      <span className="font-bold text-white">${mockStats.subscriptionRevenue.toLocaleString()}</span>
                    </div>
                    <div className="w-full h-3 bg-gray-700 rounded-full overflow-hidden">
                      <div className="h-full bg-gradient-to-r from-amber-500 to-orange-400" style={{ width: '24%' }}></div>
                    </div>
                  </div>
                </div>
              </div>

              {/* Assets by Brand */}
              <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
                <h2 className="text-xl font-bold mb-6">Fractionalized Assets by Brand</h2>
                <ResponsiveContainer width="100%" height={200}>
                  <PieChart>
                    <Pie
                      data={assetsByBrand}
                      cx="50%"
                      cy="50%"
                      labelLine={false}
                      label={(entry) => entry.name}
                      outerRadius={80}
                      fill="#8884d8"
                      dataKey="value"
                    >
                      {assetsByBrand.map((entry, index) => (
                        <Cell key={`cell-${index}`} fill={entry.color} />
                      ))}
                    </Pie>
                    <Tooltip />
                  </PieChart>
                </ResponsiveContainer>
              </div>
            </div>

            {/* Recent Investments */}
            <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
              <h2 className="text-xl font-bold mb-6">Recent Investments (Live Feed)</h2>
              <div className="space-y-3">
                {recentInvestments.map((investment) => (
                  <div
                    key={investment.id}
                    className="flex items-center justify-between p-4 bg-gray-900/50 rounded-lg border border-gray-700 hover:border-amber-500/50 transition-all"
                  >
                    <div className="flex-1">
                      <div className="font-semibold text-white mb-1">{investment.user}</div>
                      <div className="text-sm text-gray-400">{investment.asset}</div>
                    </div>
                    <div className="text-right">
                      <div className="font-bold text-green-400">${investment.amount.toLocaleString()}</div>
                      <div className="text-sm text-gray-500">{investment.shares} shares · {investment.time}</div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {activeTab === 'assets' && (
          <div className="space-y-6">
            <div className="flex items-center justify-between">
              <h2 className="text-2xl font-bold">Active Fractional Assets</h2>
              <button className="px-6 py-3 bg-gradient-to-r from-amber-500 to-orange-600 rounded-xl font-bold hover:shadow-2xl hover:shadow-amber-500/50 transition-all">
                + Add New Asset
              </button>
            </div>

            <div className="grid grid-cols-1 gap-4">
              {activeFractionalAssets.map((asset) => (
                <div
                  key={asset.id}
                  className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700 hover:border-amber-500/50 transition-all"
                >
                  <div className="flex items-center justify-between mb-4">
                    <div className="flex-1">
                      <h3 className="text-lg font-bold text-white mb-2">{asset.name}</h3>
                      <div className="text-sm text-gray-400">
                        Total Value: <span className="font-semibold text-white">${asset.totalValue.toLocaleString()}</span>
                      </div>
                    </div>
                    <div className="text-right">
                      <div className={`text-2xl font-bold ${asset.performance.startsWith('+') ? 'text-green-400' : 'text-red-400'}`}>
                        {asset.performance}
                      </div>
                      <div className="text-sm text-gray-500">Performance</div>
                    </div>
                  </div>

                  <div className="mb-4">
                    <div className="flex items-center justify-between mb-2">
                      <span className="text-sm text-gray-400">
                        Fractions Sold: {asset.fractionsSold} / {asset.fractionsTotal}
                      </span>
                      <span className="text-sm font-bold text-white">
                        {((asset.fractionsSold / asset.fractionsTotal) * 100).toFixed(1)}%
                      </span>
                    </div>
                    <div className="w-full h-3 bg-gray-700 rounded-full overflow-hidden">
                      <div
                        className="h-full bg-gradient-to-r from-amber-500 to-orange-500"
                        style={{ width: `${(asset.fractionsSold / asset.fractionsTotal) * 100}%` }}
                      ></div>
                    </div>
                  </div>

                  <div className="flex items-center space-x-3">
                    <button className="flex-1 px-4 py-2 bg-blue-500/20 hover:bg-blue-500/30 rounded-lg text-blue-400 font-semibold transition-all">
                      View Details
                    </button>
                    <button className="flex-1 px-4 py-2 bg-green-500/20 hover:bg-green-500/30 rounded-lg text-green-400 font-semibold transition-all">
                      Manage Fractions
                    </button>
                    <button className="flex-1 px-4 py-2 bg-purple-500/20 hover:bg-purple-500/30 rounded-lg text-purple-400 font-semibold transition-all">
                      Analytics
                    </button>
                  </div>
                </div>
              ))}
            </div>
          </div>
        )}

        {activeTab === 'automation' && (
          <div className="space-y-6">
            <h2 className="text-2xl font-bold">Claude Code Automation Status</h2>

            <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
              {[
                { name: 'Handbag Ingestion', status: 'running', lastRun: '0.2s ago', success: '99.97%' },
                { name: 'Deal Detection', status: 'running', lastRun: '0.5s ago', success: '100%' },
                { name: 'UX Feedback Parser', status: 'running', lastRun: '0.8s ago', success: '98.5%' },
                { name: 'Affiliate Link Checker', status: 'running', lastRun: '0.3s ago', success: '99.2%' },
                { name: 'Slack Notifications', status: 'running', lastRun: 'real-time', success: '100%' },
                { name: 'Smart Contract Generator', status: 'ready', lastRun: 'on-demand', success: '100%' },
                { name: 'AR Try-On Processor', status: 'running', lastRun: '0.6s ago', success: '96.8%' },
                { name: 'System Health Monitor', status: 'running', lastRun: '0.1s ago', success: '100%' }
              ].map((automation, index) => (
                <div
                  key={index}
                  className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700"
                >
                  <div className="flex items-center justify-between mb-4">
                    <h3 className="font-bold text-white">{automation.name}</h3>
                    <div className={`px-3 py-1 rounded-full text-xs font-bold ${
                      automation.status === 'running' ? 'bg-green-500/20 text-green-400' : 'bg-blue-500/20 text-blue-400'
                    }`}>
                      {automation.status.toUpperCase()}
                    </div>
                  </div>
                  <div className="space-y-2">
                    <div className="text-sm text-gray-400">
                      Last Run: <span className="font-semibold text-white">{automation.lastRun}</span>
                    </div>
                    <div className="text-sm text-gray-400">
                      Success Rate: <span className="font-semibold text-green-400">{automation.success}</span>
                    </div>
                  </div>
                </div>
              ))}
            </div>

            <div className="bg-gradient-to-br from-gray-800 to-gray-900 rounded-2xl p-6 border border-gray-700">
              <h3 className="text-xl font-bold mb-4">Recent Automation Logs</h3>
              <div className="space-y-2 font-mono text-sm">
                <div className="text-green-400">[0.2s ago] ✓ Ingested 400 SKUs from 5 sources</div>
                <div className="text-green-400">[0.5s ago] ✓ Detected 3 new deals ({'>'}20% discount)</div>
                <div className="text-blue-400">[0.8s ago] ℹ Processed 12 user feedback items</div>
                <div className="text-green-400">[1.1s ago] ✓ All 200 affiliate links verified</div>
                <div className="text-amber-400">[2.3s ago] ⚠ Flagged Hermès listing for legal review</div>
                <div className="text-green-400">[3.5s ago] ✓ Database backup completed (320ms)</div>
              </div>
            </div>
          </div>
        )}
      </main>
    </div>
  )
}