Notiflow / dashboard /src /react.tsx
Dipan04's picture
sab kam khatam guys heehe
4b7573c
import React, { useState, useRef } from 'react';
import {
MessageSquare,
ShoppingCart,
IndianRupee,
Cpu,
Database,
FileSpreadsheet,
Bell,
ArrowRight,
CheckCircle2,
Clock,
ExternalLink,
ShieldCheck,
Search,
Zap,
Layers,
Activity,
Server,
Terminal
} from 'lucide-react';
import { apiClient } from './api';
interface Entity {
item?: string;
qty?: string;
customer?: string;
amount?: string;
}
interface AppEvent {
id?: string;
source: string;
icon: React.ReactNode;
title: string;
message: string;
type: string;
entity: Entity;
timestamp?: string;
}
interface SheetRow {
id?: string;
[key: string]: string | undefined;
}
interface SheetsState {
[key: string]: SheetRow[];
}
const VyaparFlow = () => {
// --- State Management ---
const [notifications, setNotifications] = useState<AppEvent[]>([]);
const [activeEvent, setActiveEvent] = useState<AppEvent | null>(null);
const [backendResult, setBackendResult] = useState<any>(null);
const [processingStep, setProcessingStep] = useState(0); // 0: idle, 1: API Request, 2: Reasoning, 3: Completed, 4: Error
const [pipelineError, setPipelineError] = useState<string | null>(null);
const [view, setView] = useState('dashboard');
const [activeSheet, setActiveSheet] = useState('Orders');
// Ref to track processing to avoid race conditions
const isProcessingRef = useRef(false);
// --- Mock Data ---
const [sheets, setSheets] = useState<SheetsState>({
Orders: [
{ id: 'ORD-882', source: 'Amazon', customer: 'Suresh K.', item: 'Kurti (XL)', qty: '2', status: 'Delivered' },
{ id: 'ORD-881', source: 'WhatsApp', customer: 'Anjali', item: 'Aata', qty: '5kg', status: 'Paid' },
],
Ledger: [
{ customer: 'Rahul Sharma', type: 'Credit', amount: '₹12,400', date: '14 Mar', status: 'Settled' },
{ customer: 'Mohit', type: 'Debit', amount: '₹1,200', date: '15 Mar', status: 'Pending' },
],
Inventory: [
{ item: 'Aata (Premium)', stock: '142kg', alert: 'Normal' },
{ item: 'Silk Kurti', stock: '8', alert: 'Low' },
]
});
// --- Generate Random Notification ---
const products = ["Silk Kurti", "Cotton Saree", "Jeans", "T-shirt", "Leather Jacket"];
const groceryItems = ["aata", "chawal", "dal", "cheeni", "tel"];
const customers = ["Rahul", "Amit Kumar", "Suresh", "Pooja", "Neha"];
const sources = ["whatsapp", "gpay", "amazon seller"];
const generateNotification = () => {
const source = sources[Math.floor(Math.random() * sources.length)];
if (source === "whatsapp") {
const qty = Math.floor(Math.random() * 5) + 1;
const item = groceryItems[Math.floor(Math.random() * groceryItems.length)];
return {
source: "whatsapp",
message: `bhaiya ${qty} kilo ${item} bhej dena kal tak`
};
}
if (source === "gpay") {
const amount = Math.floor(Math.random() * 15000) + 500;
const customer = customers[Math.floor(Math.random() * customers.length)];
return {
source: "gpay",
message: `₹${amount} received from ${customer}`
};
}
const product = products[Math.floor(Math.random() * products.length)];
const qty = Math.floor(Math.random() * 3) + 1;
const total = Math.floor(Math.random() * 3000) + 500;
return {
source: "amazon seller",
message: `Product: ${product}. Qty: ${qty}. Total: ₹${total}`
};
};
const handleGenerateNotification = async () => {
// Prevent double-click or multiple rapid requests
if (isProcessingRef.current) return;
isProcessingRef.current = true;
try {
// Step 1: Generate random notification
const notification = generateNotification();
// Step 2: Map source to UI properties
const sourceMap: { [key: string]: { icon: React.ReactNode; title: string } } = {
'whatsapp': {
icon: <MessageSquare size={14} className="text-emerald-400" />,
title: 'WhatsApp Order'
},
'gpay': {
icon: <IndianRupee size={14} className="text-blue-400" />,
title: 'GPay Payment'
},
'amazon seller': {
icon: <ShoppingCart size={14} className="text-orange-400" />,
title: 'Amazon Order'
},
};
const sourceProps = sourceMap[notification.source] || {
icon: <MessageSquare size={14} className="text-slate-400" />,
title: 'New Notification'
};
// Step 3: Create AppEvent object
const uniqueId = `event-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
const newEvent: AppEvent = {
id: uniqueId,
source: notification.source.charAt(0).toUpperCase() + notification.source.slice(1),
icon: sourceProps.icon,
title: sourceProps.title,
message: notification.message,
type: notification.source === 'gpay' ? 'payment' : 'order',
entity: {},
timestamp: new Date().toLocaleTimeString()
};
// Step 4: Add to UI notifications list
setNotifications(prev => [newEvent, ...prev].slice(0, 5));
setActiveEvent(newEvent);
setBackendResult(null);
setProcessingStep(1); // Stage 1: API Endpoint hit
// Step 5: SINGLE API CALL (the ONLY place where backend is triggered)
const response = await apiClient.sendNotification({
source: notification.source.toLowerCase(),
message: notification.message
});
// Step 6: Store backend response
setBackendResult(response);
setProcessingStep(2); // Stage 2: Reasoning Phase (Nova 2 Lite)
// Simulate slight delay for visual feedback
await new Promise(r => setTimeout(r, 1000));
setProcessingStep(3); // Stage 3: Skill Execution / Record Completion
// Step 7: Update Sheets with the response data
setSheets(prev => {
const newSheets = { ...prev };
const rowId = `RECORD-${Date.now()}`;
// Extract entity info from API response
const entityData = response.data || {};
if (response.intent === 'payment') {
newSheets.Ledger = [{
id: rowId,
customer: entityData.customer || newEvent.entity.customer || 'Unknown',
type: 'Credit',
amount: entityData.amount || newEvent.entity.amount || '₹0',
date: 'Today',
status: 'Settled'
}, ...prev.Ledger].slice(0, 10);
} else {
newSheets.Orders = [{
id: `ORD-${Math.floor(Math.random()*900 + 100)}`,
source: newEvent.source,
customer: entityData.customer || newEvent.entity.customer || 'Unknown',
item: entityData.item || newEvent.entity.item || 'Item',
qty: entityData.quantity || newEvent.entity.qty || '1',
status: 'Confirmed'
}, ...prev.Orders].slice(0, 10);
}
return newSheets;
});
} catch (error: any) {
console.error('Backend error:', error);
const msg = error?.message || 'Both models unavailable';
setPipelineError(
msg.includes('quota') || msg.includes('429')
? 'Quota exceeded — wait ~1 min'
: msg.includes('unavailable') || msg.includes('500')
? 'Models unavailable — retry shortly'
: 'Request failed'
);
setProcessingStep(4); // Error state — shows red button
} finally {
// Reset lock after 5s so user clearly sees the error before re-enabling
setTimeout(() => {
setProcessingStep(0);
setPipelineError(null);
isProcessingRef.current = false;
}, 5000);
}
};
return (
<div className="flex h-screen bg-[#050505] text-slate-300 font-sans selection:bg-indigo-500/30 overflow-hidden">
{/* SIDEBAR */}
<div className="w-20 border-r border-white/5 flex flex-col items-center py-8 gap-8 bg-[#080808]">
<div className="w-10 h-10 bg-gradient-to-br from-indigo-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg shadow-indigo-500/20">
<Zap size={20} className="text-white" fill="white" />
</div>
<div className="flex flex-col gap-6 mt-12">
<button
onClick={() => setView('dashboard')}
className={`p-3 rounded-xl transition-all ${view === 'dashboard' ? 'bg-indigo-500/10 text-indigo-400 border border-indigo-500/20' : 'text-slate-600 hover:text-slate-400'}`}
>
<Activity size={22} />
</button>
<button
onClick={() => setView('sheets')}
className={`p-3 rounded-xl transition-all ${view === 'sheets' ? 'bg-indigo-500/10 text-indigo-400 border border-indigo-500/20' : 'text-slate-600 hover:text-slate-400'}`}
>
<FileSpreadsheet size={22} />
</button>
<div className="p-3 text-slate-600 hover:text-slate-400 cursor-pointer"><Layers size={22} /></div>
<div className="p-3 text-slate-600 hover:text-slate-400 cursor-pointer"><Database size={22} /></div>
</div>
</div>
{/* MOBILE SIMULATION PANEL */}
<div className="w-[420px] bg-[#080808] flex flex-col items-center justify-center p-8 relative border-r border-white/5">
<div className="absolute top-8 left-8 flex items-center gap-3">
<h1 className="text-lg font-bold tracking-tight text-white uppercase">NotiFlow</h1>
<div className="h-4 w-[1px] bg-white/10"></div>
<span className="text-[10px] text-indigo-400 font-black tracking-widest uppercase">Live Agent</span>
</div>
{/* Device Frame */}
<div className="relative w-72 h-[580px] bg-[#000] rounded-[3.5rem] p-3 border-[10px] border-[#1a1a1a] shadow-[0_0_50px_-12px_rgba(79,70,229,0.3)]">
<div className="absolute top-6 left-1/2 -translate-x-1/2 w-24 h-6 bg-[#1a1a1a] rounded-full z-20 flex items-center justify-center gap-1.5">
<div className="w-2 h-2 rounded-full bg-[#0a0a0a]"></div>
<div className="w-8 h-1 rounded-full bg-[#0a0a0a]"></div>
</div>
<div className="h-full w-full bg-[#0d0d0d] rounded-[2.5rem] overflow-hidden flex flex-col relative">
<div className="h-14 pt-8 px-6 flex justify-between items-center text-[11px] text-white/40 font-medium">
<span>9:41</span>
<div className="flex gap-1.5 items-center">
<Activity size={12} className="text-indigo-500" />
<div className="w-4 h-2 bg-white/20 rounded-sm"></div>
</div>
</div>
<div className="flex-1 px-3 py-4 space-y-3 overflow-y-auto custom-scrollbar">
<div className="flex items-center justify-between px-2 mb-2">
<span className="text-[10px] text-slate-500 font-bold tracking-tighter uppercase">Signal Stream</span>
<div className="flex gap-1">
<div className="w-1.5 h-1.5 bg-indigo-500 rounded-full animate-pulse"></div>
<div className="w-1.5 h-1.5 bg-indigo-500/50 rounded-full animate-pulse delay-75"></div>
</div>
</div>
{notifications.length === 0 && (
<div className="h-32 flex flex-col items-center justify-center text-center px-4">
<Clock size={20} className="text-slate-800 mb-2" />
<p className="text-[10px] text-slate-700 italic">Listening for business events...</p>
</div>
)}
{notifications.map((notif) => (
<div
key={notif.id}
className={`p-3 rounded-2xl border transition-all duration-700 animate-in slide-in-from-top-4 ${
activeEvent?.id === notif.id
? 'bg-indigo-600/10 border-indigo-500/50 scale-[1.02] shadow-xl'
: 'bg-white/[0.03] border-white/5 opacity-40'
}`}
>
<div className="flex items-center justify-between mb-1.5">
<div className="flex items-center gap-2">
<div className="w-5 h-5 rounded-md bg-black flex items-center justify-center border border-white/10">
{notif.icon}
</div>
<span className="text-[10px] font-bold text-white/80">{notif.source}</span>
</div>
<span className="text-[9px] text-white/30 uppercase tracking-tighter">Live</span>
</div>
<div className="text-[11px] font-bold text-white mb-0.5">{notif.title}</div>
<p className="text-[10px] text-slate-400 leading-snug line-clamp-2">{notif.message}</p>
{activeEvent?.id === notif.id && (
<div className="mt-2 pt-2 border-t border-white/5 flex items-center justify-between">
<div className="flex items-center gap-1.5">
<div className="w-1 h-1 bg-indigo-500 rounded-full animate-ping"></div>
<span className="text-[9px] text-indigo-400 font-black uppercase tracking-widest">Ingesting...</span>
</div>
<ArrowRight size={10} className="text-indigo-400 animate-bounce" />
</div>
)}
</div>
))}
</div>
<div className="h-10 flex items-center justify-center">
<div className="w-20 h-1 bg-white/10 rounded-full"></div>
</div>
</div>
</div>
<div className="mt-8 flex flex-col items-center gap-2">
<div className="flex items-center gap-2 text-[10px] font-bold text-slate-600 uppercase tracking-widest">
<Server size={14} className="text-indigo-500" /> Connection: Stable
</div>
</div>
</div>
{/* MAIN CONTENT AREA */}
<div className="flex-1 flex flex-col bg-[#050505]">
<header className="h-20 border-b border-white/5 px-10 flex items-center justify-between bg-[#080808]/50 backdrop-blur-xl sticky top-0 z-30">
<nav className="flex gap-1 bg-white/[0.02] p-1 rounded-xl border border-white/5">
<button
onClick={() => setView('dashboard')}
className={`px-8 py-2 rounded-lg text-xs font-bold transition-all ${view === 'dashboard' ? 'bg-indigo-600 text-white shadow-[0_0_20px_rgba(79,70,229,0.4)]' : 'text-slate-500 hover:text-slate-300'}`}
>
Reasoning Engine
</button>
<button
onClick={() => setView('sheets')}
className={`px-8 py-2 rounded-lg text-xs font-bold transition-all ${view === 'sheets' ? 'bg-indigo-600 text-white shadow-[0_0_20px_rgba(79,70,229,0.4)]' : 'text-slate-500 hover:text-slate-300'}`}
>
Business Ledger
</button>
</nav>
<div className="flex items-center gap-6">
<button
onClick={handleGenerateNotification}
disabled={processingStep > 0}
className={`px-4 py-2 rounded-lg text-xs font-bold border transition-all ${
processingStep === 4
? 'bg-red-900/30 text-red-400 border-red-500/40 cursor-not-allowed'
: processingStep > 0
? 'bg-slate-800/50 text-slate-500 border-slate-700/50 cursor-not-allowed'
: 'bg-emerald-600/20 text-emerald-400 border-emerald-500/30 hover:bg-emerald-600/30 hover:border-emerald-500/50'
}`}
title={pipelineError || ''}
>
{processingStep === 4
? `❌ ${pipelineError || 'Failed'}`
: processingStep > 0
? '⏳ Processing...'
: '⚡ Generate Notification'}
</button>
<div className="flex flex-col items-end">
<div className="flex items-center gap-2 text-[10px] font-black text-indigo-400 uppercase tracking-widest">
Nova-2-Lite <div className="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"></div>
</div>
<span className="text-[9px] text-slate-700 font-mono tracking-widest">V-ENGINE-BETA</span>
</div>
</div>
</header>
<main className="flex-1 overflow-y-auto p-10">
{view === 'dashboard' ? (
<div className="max-w-5xl mx-auto space-y-10">
<section className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-xl font-bold text-white tracking-tight flex items-center gap-3">
<Activity size={20} className="text-indigo-500" />
AI Processing Pipeline
</h2>
<div className="px-4 py-1.5 rounded-full border border-white/10 bg-white/[0.03] text-[9px] font-black text-slate-500 tracking-[0.2em] uppercase">
Realtime Trace
</div>
</div>
{!activeEvent ? (
<div className="h-[420px] border border-dashed border-white/5 rounded-[2.5rem] flex flex-col items-center justify-center text-center p-12 bg-white/[0.01]">
<div className="w-20 h-20 rounded-3xl bg-white/[0.03] flex items-center justify-center text-slate-800 mb-8 border border-white/5">
<Bell size={32} />
</div>
<h3 className="text-white/60 font-bold text-lg tracking-tight">System Polling Underway</h3>
<p className="text-slate-600 text-sm mt-3 max-w-xs leading-relaxed"> NotiFlow is continuously monitoring marketplace APIs and messaging webhooks.</p>
</div>
) : (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 animate-in fade-in slide-in-from-bottom-6 duration-700">
{/* Step 1 */}
<div className={`relative p-8 rounded-[2rem] border transition-all duration-700 ${processingStep >= 1 ? 'bg-white/[0.03] border-indigo-500/30 shadow-2xl' : 'bg-white/[0.01] border-white/5 opacity-40'}`}>
<div className="flex items-center gap-3 mb-8">
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-[10px] font-black ${processingStep >= 1 ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-500'}`}>01</div>
<span className="text-[10px] font-black text-white tracking-[0.2em] uppercase">POST /Ingest</span>
</div>
<div className="space-y-5">
<div className="p-4 bg-black/60 rounded-2xl border border-white/5 font-mono text-[11px] leading-relaxed">
<div className="text-indigo-400 mb-2 font-bold uppercase tracking-wider">Payload Received:</div>
<div className="text-slate-300">"{activeEvent.message}"</div>
</div>
<div className="flex items-center justify-between text-[10px] text-slate-500 font-bold uppercase px-1">
<span>Validation Check</span>
{processingStep >= 1 && <CheckCircle2 size={12} className="text-green-500" />}
</div>
</div>
{processingStep === 1 && <div className="absolute -right-3 top-1/2 -translate-y-1/2 z-10 text-indigo-500 animate-pulse"><ArrowRight size={24} /></div>}
</div>
{/* Step 2 */}
<div className={`relative p-8 rounded-[2rem] border transition-all duration-700 ${processingStep >= 2 ? 'bg-white/[0.03] border-indigo-500/30 shadow-2xl' : 'bg-white/[0.01] border-white/5 opacity-40'}`}>
<div className="flex items-center gap-3 mb-8">
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-[10px] font-black ${processingStep >= 2 ? 'bg-indigo-600 text-white' : 'bg-slate-800 text-slate-500'}`}>02</div>
<span className="text-[10px] font-black text-white tracking-[0.2em] uppercase">AI Reasoning</span>
</div>
<div className="space-y-4 min-h-[140px] relative">
{processingStep === 2 && (
<div className="absolute inset-0 flex flex-col items-center justify-center bg-black/40 backdrop-blur-sm rounded-2xl z-10">
<div className="w-10 h-10 border-2 border-indigo-500 border-t-transparent rounded-full animate-spin"></div>
<span className="text-[10px] mt-4 font-black text-indigo-400 uppercase tracking-[0.3em]">Processing...</span>
</div>
)}
<div className="bg-black/60 p-5 rounded-2xl border border-white/5 space-y-4">
<div>
<div className="text-[9px] text-slate-500 uppercase font-black mb-1.5 tracking-wider">Detected Intent</div>
<div className="text-xs text-indigo-400 font-bold capitalize">{(backendResult?.intent || activeEvent?.type || 'unknown').replace('_', ' ')} Pattern Matched</div>
</div>
<div className="h-[1px] bg-white/5"></div>
<div>
<div className="text-[9px] text-slate-500 uppercase font-black mb-2 tracking-wider">Extracted Entities</div>
<div className="flex flex-wrap gap-2">
{Object.entries(backendResult?.data || activeEvent?.entity || {}).map(([k, v]) => (
<span key={`${activeEvent?.id}-entity-${k}`} className="text-[10px] px-2.5 py-1 rounded bg-indigo-500/10 text-indigo-300 border border-indigo-500/20 font-bold">{k}: {String(v)}</span>
))}
</div>
</div>
</div>
</div>
{processingStep === 2 && <div className="absolute -right-3 top-1/2 -translate-y-1/2 z-10 text-indigo-500 animate-pulse"><ArrowRight size={24} /></div>}
</div>
{/* Step 3 */}
<div className={`relative p-8 rounded-[2rem] border transition-all duration-700 ${processingStep >= 3 ? 'bg-indigo-600/5 border-indigo-500/40 shadow-2xl' : 'bg-white/[0.01] border-white/5 opacity-40'}`}>
<div className="flex items-center gap-3 mb-8">
<div className={`w-8 h-8 rounded-full flex items-center justify-center text-[10px] font-black ${processingStep >= 3 ? 'bg-green-500 text-black' : 'bg-slate-800 text-slate-500'}`}>03</div>
<span className="text-[10px] font-black text-white tracking-[0.2em] uppercase">Skills Applied</span>
</div>
<div className="space-y-6">
<div className="flex items-center gap-4">
<div className="w-12 h-12 rounded-2xl bg-green-500/10 flex items-center justify-center text-green-500 border border-green-500/20 shadow-[0_0_20px_rgba(34,197,94,0.15)]">
<CheckCircle2 size={24} />
</div>
<div>
<div className="text-[11px] font-bold text-white uppercase tracking-wider">Record Finalized</div>
<div className="text-[10px] text-slate-500 mt-0.5">DB Synchronization: Success</div>
</div>
</div>
<button
onClick={() => setView('sheets')}
className="w-full py-3.5 rounded-2xl bg-white/[0.05] border border-white/5 text-[10px] font-black uppercase tracking-[0.25em] text-white hover:bg-white/10 transition-all flex items-center justify-center gap-2"
>
View Updates <ExternalLink size={12} />
</button>
</div>
</div>
</div>
)}
</section>
<section className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="p-8 rounded-[2rem] bg-white/[0.02] border border-white/5 flex flex-col gap-1 hover:bg-white/[0.03] transition-colors">
<span className="text-[10px] font-black text-slate-600 uppercase tracking-widest">Global Success Rate</span>
<span className="text-3xl font-bold text-white tracking-tighter">99.2%</span>
<div className="w-full h-1 bg-white/5 rounded-full mt-6 overflow-hidden">
<div className="w-[99%] h-full bg-gradient-to-r from-indigo-500 to-emerald-500"></div>
</div>
</div>
<div className="p-8 rounded-[2rem] bg-white/[0.02] border border-white/5 flex flex-col gap-1 hover:bg-white/[0.03] transition-colors">
<span className="text-[10px] font-black text-slate-600 uppercase tracking-widest">Active Connectors</span>
<span className="text-3xl font-bold text-white tracking-tighter">14</span>
<div className="flex gap-2 mt-6">
<div className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div>
<div className="w-2 h-2 rounded-full bg-orange-500 animate-pulse delay-75"></div>
<div className="w-2 h-2 rounded-full bg-blue-500 animate-pulse delay-150"></div>
<div className="w-2 h-2 rounded-full bg-purple-500 animate-pulse delay-200"></div>
</div>
</div>
<div className="p-8 rounded-[2rem] bg-[#0c0c12] border border-indigo-500/20 flex flex-col gap-1 shadow-inner shadow-indigo-500/5">
<span className="text-[10px] font-black text-indigo-400 uppercase tracking-widest">Model Performance</span>
<span className="text-3xl font-bold text-white tracking-tighter">Ultra-Low</span>
<span className="text-[10px] text-indigo-400/50 mt-6 font-mono font-bold tracking-widest uppercase">Nova-2-L-optimized</span>
</div>
</section>
</div>
) : (
<div className="max-w-6xl mx-auto space-y-10 animate-in fade-in slide-in-from-bottom-6 duration-700">
<div className="flex items-end justify-between">
<div className="space-y-1">
<h2 className="text-2xl font-bold text-white tracking-tight">Business Operations Console</h2>
<p className="text-slate-500 text-sm">Real-time structured business data extracted from the unified signal stream.</p>
</div>
<div className="flex bg-white/[0.03] p-1.5 rounded-2xl border border-white/5 shadow-2xl">
{['Orders', 'Ledger', 'Inventory'].map((s) => (
<button
key={`sheet-tab-${s}`}
onClick={() => setActiveSheet(s)}
className={`px-8 py-2.5 rounded-xl text-xs font-black tracking-widest uppercase transition-all ${activeSheet === s ? 'bg-indigo-600 text-white shadow-lg' : 'text-slate-500 hover:text-white hover:bg-white/5'}`}
>
{s}
</button>
))}
</div>
</div>
<div className="bg-[#080808] rounded-[2.5rem] border border-white/5 overflow-hidden shadow-[0_32px_64px_-16px_rgba(0,0,0,0.8)] relative">
<div className="overflow-x-auto">
<table className="w-full text-left text-sm border-collapse">
<thead>
<tr className="bg-white/[0.03] border-b border-white/5">
{sheets[activeSheet] && sheets[activeSheet].length > 0 && Object.keys(sheets[activeSheet][0]).filter(k => k !== 'id').map(key => (
<th key={`header-${activeSheet}-${key}`} className="px-10 py-6 font-black text-slate-500 uppercase text-[10px] tracking-[0.25em]">{key}</th>
))}
</tr>
</thead>
<tbody>
{sheets[activeSheet].map((row, i) => (
<tr key={`row-${activeSheet}-${row.id || i}`} className={`border-b border-white/[0.02] hover:bg-white/[0.03] transition-colors group ${i === 0 ? 'bg-indigo-600/5' : ''}`}>
{Object.entries(row).filter(([k]) => k !== 'id').map(([key, val = ''], j) => (
<td key={`cell-${activeSheet}-${i}-${j}`} className="px-10 py-6">
<span className={`
${val === 'Pending' || val === 'Low' ? 'text-orange-400 font-bold' : ''}
${val === 'Delivered' || val === 'Paid' || val === 'Settled' || val === 'Confirmed' ? 'text-emerald-400 font-bold' : ''}
${typeof val === 'string' && val.includes('₹') ? 'text-indigo-300 font-mono font-bold' : 'text-slate-300'}
`}>
{val}
</span>
{i === 0 && j === 0 && <span className="ml-3 px-2 py-0.5 rounded bg-indigo-500 text-[8px] font-black text-white uppercase tracking-tighter animate-pulse shadow-sm">Recent</span>}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
</div>
<div className="flex items-center justify-between p-8 rounded-[2rem] bg-white/[0.02] border border-white/5">
<div className="flex items-center gap-4">
<Terminal size={18} className="text-indigo-500" />
<span className="text-[11px] text-slate-500 font-mono font-bold tracking-tighter">Auto-sync with VyaparFlow Cloud v1.0.4 - Connection Secure</span>
</div>
<div className="flex gap-4">
<button className="px-6 py-2.5 rounded-xl bg-white/5 hover:bg-white/10 text-xs font-bold text-white border border-white/10 transition-all">Download .CSV</button>
<button className="px-6 py-2.5 rounded-xl bg-indigo-600 hover:bg-indigo-500 text-xs font-bold text-white transition-all shadow-lg shadow-indigo-600/20">Push to Tally / GST</button>
</div>
</div>
</div>
)}
</main>
<footer className="h-12 border-t border-white/5 bg-[#080808] px-10 flex items-center justify-between text-[10px] font-black uppercase tracking-[0.3em]">
<div className="flex gap-10 text-slate-600">
<div className="flex items-center gap-2.5"><div className="w-1.5 h-1.5 bg-green-500 rounded-full shadow-[0_0_8px_rgba(34,197,94,0.5)]"></div> Network: Online</div>
<span className="flex items-center gap-2.5"><Cpu size={12} className="text-indigo-400" /> Model: Nova-2-Lite</span>
<span className="flex items-center gap-2.5"><Database size={12} className="text-indigo-400" /> Storage: Cloud Active</span>
</div>
<div className="flex gap-6 text-slate-700">
<span>SES-ID: 771-VY-99</span>
<span>BUILD: 2024.MAR.PRO</span>
</div>
</footer>
</div>
</div>
);
};
export default VyaparFlow;