import { useState, useEffect } from 'react'; import { supabase } from '@/lib/supabase'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Progress } from '@/components/ui/progress'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter } from '@/components/ui/dialog'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { toast } from 'sonner'; import { MerchantTierBadge, type MerchantTier } from './MerchantTierBadge'; import { ArrowRight, Check, CheckCircle2, Clock, Crown, Diamond, Info, Loader2, Lock, Shield, Star, TrendingUp } from 'lucide-react'; // Tier requirements interface interface TierRequirements { tier: MerchantTier; min_trades: number; min_completion_rate: number; min_volume_30d: number; deposit_required: number; deposit_token: string; max_pending_orders: number; max_order_amount: number; featured_ads_allowed: number; description: string; } // User stats interface interface UserStats { completed_trades: number; completion_rate: number; volume_30d: number; } // Current tier info interface CurrentTierInfo { tier: MerchantTier; application_status: string | null; applied_for_tier: string | null; } // Default tier requirements const DEFAULT_REQUIREMENTS: TierRequirements[] = [ { tier: 'lite', min_trades: 0, min_completion_rate: 0, min_volume_30d: 0, deposit_required: 0, deposit_token: 'HEZ', max_pending_orders: 5, max_order_amount: 10000, featured_ads_allowed: 0, description: 'Basic tier for all verified users' }, { tier: 'super', min_trades: 20, min_completion_rate: 90, min_volume_30d: 5000, deposit_required: 10000, deposit_token: 'HEZ', max_pending_orders: 20, max_order_amount: 100000, featured_ads_allowed: 3, description: 'Professional trader tier with higher limits' }, { tier: 'diamond', min_trades: 100, min_completion_rate: 95, min_volume_30d: 25000, deposit_required: 50000, deposit_token: 'HEZ', max_pending_orders: 50, max_order_amount: 150000, featured_ads_allowed: 10, description: 'Elite merchant tier with maximum privileges' } ]; // Tier icon mapping const TIER_ICONS = { lite: Shield, super: Star, diamond: Diamond }; // Tier colors const TIER_COLORS = { lite: 'text-gray-400', super: 'text-yellow-500', diamond: 'text-purple-500' }; export function MerchantApplication() { const [loading, setLoading] = useState(true); const [requirements, setRequirements] = useState(DEFAULT_REQUIREMENTS); const [userStats, setUserStats] = useState({ completed_trades: 0, completion_rate: 0, volume_30d: 0 }); const [currentTier, setCurrentTier] = useState({ tier: 'lite', application_status: null, applied_for_tier: null }); const [applyModalOpen, setApplyModalOpen] = useState(false); const [selectedTier, setSelectedTier] = useState(null); const [applying, setApplying] = useState(false); // Fetch data useEffect(() => { fetchData(); }, []); const fetchData = async () => { setLoading(true); try { const { data: { user } } = await supabase.auth.getUser(); if (!user) return; // Fetch tier requirements const { data: reqData } = await supabase .from('p2p_tier_requirements') .select('*') .order('min_trades', { ascending: true }); if (reqData && reqData.length > 0) { setRequirements(reqData as TierRequirements[]); } // Fetch user reputation const { data: repData } = await supabase .from('p2p_reputation') .select('completed_trades') .eq('user_id', user.id) .single(); // Fetch merchant stats const { data: statsData } = await supabase .from('p2p_merchant_stats') .select('completion_rate_30d, total_volume_30d') .eq('user_id', user.id) .single(); // Fetch current tier const { data: tierData } = await supabase .from('p2p_merchant_tiers') .select('tier, application_status, applied_for_tier') .eq('user_id', user.id) .single(); setUserStats({ completed_trades: repData?.completed_trades || 0, completion_rate: statsData?.completion_rate_30d || 0, volume_30d: statsData?.total_volume_30d || 0 }); if (tierData) { setCurrentTier(tierData as CurrentTierInfo); } } catch (error) { console.error('Error fetching merchant data:', error); } finally { setLoading(false); } }; // Calculate progress for a requirement const calculateProgress = (current: number, required: number): number => { if (required === 0) return 100; return Math.min((current / required) * 100, 100); }; // Check if tier is unlocked const isTierUnlocked = (tier: TierRequirements): boolean => { return ( userStats.completed_trades >= tier.min_trades && userStats.completion_rate >= tier.min_completion_rate && userStats.volume_30d >= tier.min_volume_30d ); }; // Get tier index for comparison const getTierIndex = (tier: MerchantTier): number => { return requirements.findIndex(r => r.tier === tier); }; // Check if can apply for tier const canApplyForTier = (tier: TierRequirements): boolean => { if (!isTierUnlocked(tier)) return false; if (getTierIndex(currentTier.tier) >= getTierIndex(tier.tier)) return false; if (currentTier.application_status === 'pending') return false; return true; }; // Apply for tier const applyForTier = async () => { if (!selectedTier) return; setApplying(true); try { const { data: { user } } = await supabase.auth.getUser(); if (!user) throw new Error('Not authenticated'); const { data, error } = await supabase.rpc('apply_for_tier_upgrade', { p_user_id: user.id, p_target_tier: selectedTier }); if (error) throw error; if (data && data[0]) { if (data[0].success) { toast.success('Application submitted successfully!'); setApplyModalOpen(false); fetchData(); } else { toast.error(data[0].message || 'Application failed'); } } } catch (error) { console.error('Error applying for tier:', error); toast.error('Failed to submit application'); } finally { setApplying(false); } }; // Open apply modal const openApplyModal = (tier: MerchantTier) => { setSelectedTier(tier); setApplyModalOpen(true); }; if (loading) { return ( ); } return (
{/* Current Tier Card */}
Your Merchant Status Current tier and application status

{userStats.completed_trades}

Completed Trades

{userStats.completion_rate.toFixed(1)}%

Completion Rate

${userStats.volume_30d.toLocaleString()}

30-Day Volume

{currentTier.application_status === 'pending' && ( Your application for {currentTier.applied_for_tier?.toUpperCase()} tier is pending review. )}
{/* Tier Progression */}
{requirements.map((tier) => { const TierIcon = TIER_ICONS[tier.tier]; const isCurrentTier = tier.tier === currentTier.tier; const isUnlocked = isTierUnlocked(tier); const canApply = canApplyForTier(tier); const isPastTier = getTierIndex(tier.tier) < getTierIndex(currentTier.tier); return ( {/* Current tier indicator */} {isCurrentTier && (
Current
)} {isPastTier && (
)}
{tier.tier} {tier.description}
{/* Requirements */}
{/* Trades */}
Completed Trades {userStats.completed_trades} / {tier.min_trades}
{/* Completion Rate */} {tier.min_completion_rate > 0 && (
Completion Rate {userStats.completion_rate.toFixed(1)}% / {tier.min_completion_rate}%
)} {/* Volume */} {tier.min_volume_30d > 0 && (
30-Day Volume ${userStats.volume_30d.toLocaleString()} / ${tier.min_volume_30d.toLocaleString()}
)}
{/* Benefits */}

Benefits:

Up to {tier.max_pending_orders} pending orders
Max ${tier.max_order_amount.toLocaleString()} per trade
{tier.featured_ads_allowed > 0 && (
{tier.featured_ads_allowed} featured ads
)}
{/* Deposit requirement */} {tier.deposit_required > 0 && (
Requires {tier.deposit_required.toLocaleString()} {tier.deposit_token} deposit
)} {/* Action button */} {canApply && ( )}
); })}
{/* Apply Modal */} Apply for {selectedTier?.toUpperCase()} Tier Submit your application for tier upgrade. Our team will review it shortly. {selectedTier && (
{/* Requirements check */}

Requirements Met:

{requirements.find(r => r.tier === selectedTier) && ( <>
Completed trades requirement
Completion rate requirement
30-day volume requirement
)}
{/* Deposit info */} {(requirements.find(r => r.tier === selectedTier)?.deposit_required ?? 0) > 0 && ( This tier requires a deposit of{' '} {requirements.find(r => r.tier === selectedTier)?.deposit_required.toLocaleString()}{' '} {requirements.find(r => r.tier === selectedTier)?.deposit_token} . You will be prompted to complete the deposit after approval. )}
)}
); } export default MerchantApplication;