larxius commited on
Commit
e08e7fd
·
verified ·
1 Parent(s): 5beebae

Update frontend/src/pages/SuperAdminPanel.jsx

Browse files
frontend/src/pages/SuperAdminPanel.jsx CHANGED
@@ -331,6 +331,21 @@ const SuperAdminPanel = () => {
331
  const [emailPage, setEmailPage] = useState(1);
332
  const [emailPageSize, setEmailPageSize] = useState(25);
333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
  const handleOrgSort = (column) => {
335
  if (column === 'Quotas' || column === 'Actions') return;
336
  if (sortOrgCol === column) {
@@ -1716,10 +1731,65 @@ const SuperAdminPanel = () => {
1716
 
1717
  {activeTab === 'bookings' && (
1718
  <div className="flex flex-col gap-md mb-xl animate-fade-in">
1719
- <h2 className="font-headline-sm font-bold text-on-surface flex items-center text-[18px] mb-md"><span className="material-symbols-outlined text-primary mr-2">event</span> Demo Bookings & Leads</h2>
 
 
 
 
 
 
1720
  <div className="bg-surface border border-outline-variant rounded-2xl overflow-hidden shadow-sm">
1721
- {demoBookings.length === 0 ? (
1722
- <div className="p-xl text-center text-on-surface-variant font-bold">No demo bookings found.</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1723
  ) : (
1724
  <>
1725
  <div className="overflow-x-auto">
@@ -1734,7 +1804,7 @@ const SuperAdminPanel = () => {
1734
  </tr>
1735
  </thead>
1736
  <tbody className="divide-y divide-outline-variant">
1737
- {demoBookings.slice((bookingPage - 1) * bookingPageSize, bookingPage * bookingPageSize).map(b => {
1738
  const statusStyle =
1739
  b.status === 'completed'
1740
  ? 'bg-green-500/10 text-green-600 border-green-500/30'
@@ -1809,7 +1879,7 @@ const SuperAdminPanel = () => {
1809
  </div>
1810
  <TablePagination
1811
  currentPage={bookingPage}
1812
- totalEntries={demoBookings.length}
1813
  pageSize={bookingPageSize}
1814
  onPageChange={setBookingPage}
1815
  onPageSizeChange={setBookingPageSize}
 
331
  const [emailPage, setEmailPage] = useState(1);
332
  const [emailPageSize, setEmailPageSize] = useState(25);
333
 
334
+ const [bookingSearch, setBookingSearch] = useState('');
335
+ const [bookingStatusFilter, setBookingStatusFilter] = useState('all');
336
+
337
+ const getFilteredBookings = () => {
338
+ return (demoBookings || []).filter(b => {
339
+ const emailMatch = !bookingSearch ||
340
+ (b.email || '').toLowerCase().includes(bookingSearch.toLowerCase()) ||
341
+ (b.company_size || '').toLowerCase().includes(bookingSearch.toLowerCase()) ||
342
+ (b.meeting_date || '').toLowerCase().includes(bookingSearch.toLowerCase());
343
+
344
+ const statusMatch = bookingStatusFilter === 'all' || (b.status || 'pending') === bookingStatusFilter;
345
+ return emailMatch && statusMatch;
346
+ });
347
+ };
348
+
349
  const handleOrgSort = (column) => {
350
  if (column === 'Quotas' || column === 'Actions') return;
351
  if (sortOrgCol === column) {
 
1731
 
1732
  {activeTab === 'bookings' && (
1733
  <div className="flex flex-col gap-md mb-xl animate-fade-in">
1734
+ <div className="flex flex-col md:flex-row md:items-center justify-between gap-md mb-xs">
1735
+ <h2 className="font-headline-sm font-bold text-on-surface flex items-center text-[18px]"><span className="material-symbols-outlined text-primary mr-2">event</span> Demo Bookings & Leads</h2>
1736
+ <div className="text-[12.5px] font-bold text-on-surface-variant">
1737
+ Total Leads: <span className="text-primary font-extrabold">{getFilteredBookings().length}</span>
1738
+ </div>
1739
+ </div>
1740
+
1741
  <div className="bg-surface border border-outline-variant rounded-2xl overflow-hidden shadow-sm">
1742
+ {/* Filter Controls Bar */}
1743
+ <div className="p-md bg-surface-container-high/40 border-b border-outline-variant/60 flex flex-col md:flex-row justify-between items-start md:items-center gap-md">
1744
+ <div className="flex items-center gap-sm flex-wrap w-full md:w-auto">
1745
+ <div className="relative flex-1 md:w-64">
1746
+ <Search className="w-4 h-4 absolute left-3 top-2.5 text-on-surface-variant" />
1747
+ <input
1748
+ type="text"
1749
+ placeholder="Search email, company size, date..."
1750
+ value={bookingSearch}
1751
+ onChange={(e) => { setBookingSearch(e.target.value); setBookingPage(1); }}
1752
+ className="w-full bg-surface border border-outline-variant/60 rounded-lg pl-9 pr-8 py-1.5 text-[13px] outline-none focus:border-primary text-on-surface font-medium"
1753
+ />
1754
+ {bookingSearch && (
1755
+ <button
1756
+ onClick={() => { setBookingSearch(''); setBookingPage(1); }}
1757
+ className="absolute right-2.5 top-1/2 -translate-y-1/2 text-on-surface-variant hover:text-on-surface bg-transparent border-0 cursor-pointer p-0.5"
1758
+ >
1759
+ <X className="w-3.5 h-3.5" />
1760
+ </button>
1761
+ )}
1762
+ </div>
1763
+
1764
+ <div className="flex items-center gap-1.5">
1765
+ <span className="text-[11px] font-bold text-on-surface-variant uppercase tracking-wider shrink-0">Status:</span>
1766
+ <select
1767
+ value={bookingStatusFilter}
1768
+ onChange={(e) => { setBookingStatusFilter(e.target.value); setBookingPage(1); }}
1769
+ className="bg-surface border border-outline-variant/60 text-on-surface text-[13px] font-medium rounded-lg px-3 py-1.5 focus:outline-none focus:border-primary cursor-pointer"
1770
+ >
1771
+ <option value="all">All Statuses</option>
1772
+ <option value="pending">Pending</option>
1773
+ <option value="completed">Completed</option>
1774
+ <option value="rescheduled">Rescheduled</option>
1775
+ <option value="cancelled">Cancelled</option>
1776
+ </select>
1777
+ </div>
1778
+
1779
+ {(bookingSearch || bookingStatusFilter !== 'all') && (
1780
+ <button
1781
+ onClick={() => { setBookingSearch(''); setBookingStatusFilter('all'); setBookingPage(1); }}
1782
+ className="text-error hover:underline text-[12.5px] font-bold flex items-center gap-1 cursor-pointer bg-transparent border-0 px-1 ml-auto md:ml-0"
1783
+ >
1784
+ <X className="w-4 h-4" />
1785
+ Reset Filters
1786
+ </button>
1787
+ )}
1788
+ </div>
1789
+ </div>
1790
+
1791
+ {getFilteredBookings().length === 0 ? (
1792
+ <div className="p-xl text-center text-on-surface-variant font-bold">No demo bookings match your filter criteria.</div>
1793
  ) : (
1794
  <>
1795
  <div className="overflow-x-auto">
 
1804
  </tr>
1805
  </thead>
1806
  <tbody className="divide-y divide-outline-variant">
1807
+ {getFilteredBookings().slice((bookingPage - 1) * bookingPageSize, bookingPage * bookingPageSize).map(b => {
1808
  const statusStyle =
1809
  b.status === 'completed'
1810
  ? 'bg-green-500/10 text-green-600 border-green-500/30'
 
1879
  </div>
1880
  <TablePagination
1881
  currentPage={bookingPage}
1882
+ totalEntries={getFilteredBookings().length}
1883
  pageSize={bookingPageSize}
1884
  onPageChange={setBookingPage}
1885
  onPageSizeChange={setBookingPageSize}