import React, { useState } from 'react'; import { useHistory } from 'react-router-dom'; import { IonPage, IonContent, IonSpinner, useIonViewWillEnter, IonIcon, } from '@ionic/react'; import { documentTextOutline, addOutline, searchOutline } from 'ionicons/icons'; import { supabase } from '../supabase'; import { useProfile } from '../contexts/ProfileContext'; import { useAuth } from '../contexts/AuthContext'; import DashboardMetricCard from '../components/DashboardMetricCard'; import RecentActivityCard from '../components/RecentActivityCard'; import { Database } from '../database.types'; type RfqRow = Database['public']['Tables']['rfqs']['Row']; const Home: React.FC = () => { const history = useHistory(); const { user } = useAuth(); const { profile } = useProfile(); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [rfqSummary, setRfqSummary] = useState({ open: 0, quoted: 0, closed: 0, }); const [supplierSummary, setSupplierSummary] = useState({ assignedOpen: 0, myQuotes: 0, accepted: 0, }); const [recentItems, setRecentItems] = useState([]); useIonViewWillEnter(() => { loadDashboardData(); }); const loadDashboardData = async () => { if (!user || !profile) return; setLoading(true); setError(''); try { if (profile.role === 'buyer') { // Aggregate counts const { data: allRfqs, error: countErr } = await supabase .from('rfqs') .select('id, status') .eq('buyer_id', user.id); if (countErr) throw countErr; let open = 0, quoted = 0, closed = 0; allRfqs?.forEach((r) => { if (r.status === 'open') open++; else if (r.status === 'quoted') quoted++; else if (r.status === 'closed') closed++; }); setRfqSummary({ open, quoted, closed }); // Recent items const { data: recent, error: recentErr } = await supabase .from('rfqs') .select('*') .eq('buyer_id', user.id) .order('created_at', { ascending: false }) .limit(5); if (recentErr) throw recentErr; setRecentItems(recent || []); } else { // Supplier const { data: allRecipients, error: recErr } = await supabase .from('rfq_recipients') .select('id, rfqs!inner(id, status)') .eq('supplier_id', user.id); if (recErr) throw recErr; let assignedOpen = 0; allRecipients?.forEach((r: any) => { if (r.rfqs && r.rfqs.status === 'open') assignedOpen++; }); const { data: myQuotes, error: qErr } = await supabase .from('quotations') .select('id, status') .eq('supplier_id', user.id); if (qErr) throw qErr; let accepted = 0; myQuotes?.forEach((q) => { if (q.status === 'accepted') accepted++; }); setSupplierSummary({ assignedOpen, myQuotes: myQuotes?.length || 0, accepted, }); const { data: recent, error: recentErr } = await supabase .from('rfq_recipients') .select('id, rfqs!inner(*)') .eq('supplier_id', user.id) .order('created_at', { ascending: false }) .limit(5); if (recentErr) throw recentErr; // Map joined data const mapped = (recent || []).map((r: any) => r.rfqs); setRecentItems(mapped); } } catch (err: any) { console.error(err); setError('Failed to load dashboard data.'); } finally { setLoading(false); } }; const handlePrimaryAction = () => { if (profile?.role === 'buyer') { history.push('/rfq/new'); } else { history.push('/requests'); } }; const handleRecentItemTap = (item: RfqRow) => { history.push(`/rfq/${item.id}`); }; if (!profile) return null; return (
QuoteLink
Procurement made simpler
history.push('/profile')} style={{ width: '40px', height: '40px', borderRadius: '999px', background: 'var(--color-brand-medium)', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: 'var(--color-brand)', fontSize: '16px', fontWeight: '700', textTransform: 'uppercase', flexShrink: 0, }} > {profile.full_name.charAt(0)}
Good to see you,{' '} {profile.full_name.split(' ')[0]}
{profile.role === 'buyer' ? 'Track requests, review supplier pricing, and keep decisions moving.' : 'Review assigned RFQs, send pricing fast, and stay on top of wins.'}
{error && (
{error}
)}
{profile.role === 'buyer' ? 'Active Requests' : 'Assigned RFQs'} {profile.role === 'buyer' ? rfqSummary.open + rfqSummary.quoted : supplierSummary.assignedOpen}
{profile.role === 'buyer' ? 'Create new request →' : 'Browse requests →'}
{profile.role === 'buyer' ? ( <> ) : ( <> )}
Recent Activity
history.push('/requests')} style={{ fontSize: '13px', fontWeight: '600', color: 'var(--color-brand)', cursor: 'pointer', }} > See all
{loading ? (
) : recentItems.length > 0 ? ( recentItems.map((item) => ( handleRecentItemTap(item)} /> )) ) : (
No recent activity yet.
{profile.role === 'buyer' && ( )}
)}
); }; export default Home;