import React,{useState,useMemo,useTransition,useEffect}from'react';interface Approval{id:string;recordName:string;type:string;submittedBy:string;submittedDate:string;status:'Pending'|'Approved'|'Rejected'}const useDebounce=<T,>(value:T,delay:number):T=>{const[debouncedValue,setDebouncedValue]=useState(value);useEffect(()=>{const handler=setTimeout(()=>setDebouncedValue(value),delay);return()=>clearTimeout(handler)},[value,delay]);return debouncedValue};const useToast=()=>{const[toasts,setToasts]=useState<Array<{id:number;message:string}>>([]);const show=(message:string)=>{const id=Date.now();setToasts(prev=>[...prev,{id,message}]);setTimeout(()=>setToasts(prev=>prev.filter(t=>t.id!==id)),3000)};return{toasts,show}};const mockApprovals:Approval[]=[{id:'ap001',recordName:'Discount Request - Acme Corp',type:'Opportunity',submittedBy:'Jane Smith',submittedDate:'2025-02-13',status:'Pending'},{id:'ap002',recordName:'Price Override - Global Inc',type:'Quote',submittedBy:'John Doe',submittedDate:'2025-02-12',status:'Pending'},{id:'ap003',recordName:'Contract Amendment',type:'Contract',submittedBy:'Alice Johnson',submittedDate:'2025-02-11',status:'Approved'},{id:'ap004',recordName:'Budget Increase',type:'Campaign',submittedBy:'Bob Wilson',submittedDate:'2025-02-10',status:'Rejected'}];const App:React.FC=()=>{const[searchQuery,setSearchQuery]=useState('');const[statusFilter,setStatusFilter]=useState<string>('Pending');const[isPending,startTransition]=useTransition();const{toasts,show}=useToast();const debouncedSearch=useDebounce(searchQuery,300);const filteredApprovals=useMemo(()=>{return mockApprovals.filter(a=>{const matchesSearch=a.recordName.toLowerCase().includes(debouncedSearch.toLowerCase());const matchesStatus=statusFilter==='All'||a.status===statusFilter;return matchesSearch&&matchesStatus})},[debouncedSearch,statusFilter]);const stats=useMemo(()=>({total:mockApprovals.filter(a=>a.status==='Pending').length,approved:mockApprovals.filter(a=>a.status==='Approved').length,rejected:mockApprovals.filter(a=>a.status==='Rejected').length,all:mockApprovals.length}),[]);const handleSearch=(e:React.ChangeEvent<HTMLInputElement>)=>{startTransition(()=>{setSearchQuery(e.target.value)})};const handleApprove=(approval:Approval)=>{show(`Approved: ${approval.recordName}`)};const handleReject=(approval:Approval)=>{show(`Rejected: ${approval.recordName}`)};return(<div className="app-container"><header className="app-header"><h1>Approval Center</h1><p>Pending approvals, approve/reject</p></header><div className="stats-grid"><div className="stat-card"><div className="stat-label">Pending</div><div className="stat-value">{stats.total}</div></div><div className="stat-card"><div className="stat-label">Approved</div><div className="stat-value">{stats.approved}</div></div><div className="stat-card"><div className="stat-label">Rejected</div><div className="stat-value">{stats.rejected}</div></div><div className="stat-card"><div className="stat-label">All</div><div className="stat-value">{stats.all}</div></div></div><div className="controls"><input type="text" placeholder="Search approvals..." value={searchQuery} onChange={handleSearch} className="search-input"/><select value={statusFilter} onChange={e=>setStatusFilter(e.target.value)} className="filter-select"><option value="All">All Status</option><option value="Pending">Pending</option><option value="Approved">Approved</option><option value="Rejected">Rejected</option></select></div>{filteredApprovals.length===0?(<div className="empty-state"><div className="empty-icon">✓</div><h3>No approvals found</h3><p>Try adjusting your filters</p></div>):(<div className="data-grid"><table><thead><tr><th>Record Name</th><th>Type</th><th>Submitted By</th><th>Date</th><th>Status</th><th>Actions</th></tr></thead><tbody className={isPending?'loading':''}>{filteredApprovals.map(a=>(<tr key={a.id}><td><strong>{a.recordName}</strong></td><td>{a.type}</td><td>{a.submittedBy}</td><td>{a.submittedDate}</td><td><span className={`badge badge-${a.status.toLowerCase()}`}>{a.status}</span></td><td>{a.status==='Pending'&&(<><button className="btn-primary" onClick={()=>handleApprove(a)} style={{marginRight:'0.5rem'}}>Approve</button><button className="btn-primary" onClick={()=>handleReject(a)}>Reject</button></>)}</td></tr>))}</tbody></table></div>)}<div className="toast-container">{toasts.map(toast=>(<div key={toast.id} className="toast">{toast.message}</div>))}</div></div>)};export default App;
