larxius commited on
Commit
0b13263
·
verified ·
1 Parent(s): e08e7fd

Update frontend/src/pages/SupportEngineerPanel.jsx

Browse files
frontend/src/pages/SupportEngineerPanel.jsx CHANGED
@@ -219,6 +219,23 @@ export const SupportEngineerPanel = () => {
219
  const [userRoleFilter, setUserRoleFilter] = useState('all');
220
  const [userOrgFilter, setUserOrgFilter] = useState('all');
221
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  // Pagination states
223
  const [orgPage, setOrgPage] = useState(1);
224
  const [orgPageSize, setOrgPageSize] = useState(25);
@@ -1182,12 +1199,67 @@ export const SupportEngineerPanel = () => {
1182
  {/* BOOKINGS TAB */}
1183
  {activeTab === 'bookings' && (
1184
  <div className="flex flex-col gap-md mb-xl animate-fade-in">
1185
- <h2 className="font-headline-sm font-bold text-on-surface flex items-center text-[18px] mb-md">
1186
- <Calendar className="w-5 h-5 text-primary mr-2" /> Demo Bookings & Leads
1187
- </h2>
 
 
 
 
 
 
1188
  <div className="bg-surface border border-outline-variant rounded-2xl overflow-hidden shadow-sm">
1189
- {demoBookings.length === 0 ? (
1190
- <div className="p-xl text-center text-on-surface-variant font-bold">No demo bookings found.</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1191
  ) : (
1192
  <>
1193
  <div className="overflow-x-auto">
@@ -1202,7 +1274,7 @@ export const SupportEngineerPanel = () => {
1202
  </tr>
1203
  </thead>
1204
  <tbody className="divide-y divide-outline-variant">
1205
- {demoBookings.slice((bookingPage - 1) * bookingPageSize, bookingPage * bookingPageSize).map(b => {
1206
  const statusStyle =
1207
  b.status === 'completed'
1208
  ? 'bg-green-500/10 text-green-600 border-green-500/30'
@@ -1278,7 +1350,7 @@ export const SupportEngineerPanel = () => {
1278
  </div>
1279
  <TablePagination
1280
  currentPage={bookingPage}
1281
- totalEntries={demoBookings.length}
1282
  pageSize={bookingPageSize}
1283
  onPageChange={setBookingPage}
1284
  onPageSizeChange={setBookingPageSize}
 
219
  const [userRoleFilter, setUserRoleFilter] = useState('all');
220
  const [userOrgFilter, setUserOrgFilter] = useState('all');
221
 
222
+ // Filter states for Bookings
223
+ const [bookingSearch, setBookingSearch] = useState('');
224
+ const [bookingStatusFilter, setBookingStatusFilter] = useState('all');
225
+
226
+ const getFilteredBookings = () => {
227
+ return (demoBookings || []).filter(b => {
228
+ const displayEmail = b.email || b.user_email || '';
229
+ const emailMatch = !bookingSearch ||
230
+ displayEmail.toLowerCase().includes(bookingSearch.toLowerCase()) ||
231
+ (b.company_size || '').toLowerCase().includes(bookingSearch.toLowerCase()) ||
232
+ (b.meeting_date || '').toLowerCase().includes(bookingSearch.toLowerCase());
233
+
234
+ const statusMatch = bookingStatusFilter === 'all' || (b.status || 'pending') === bookingStatusFilter;
235
+ return emailMatch && statusMatch;
236
+ });
237
+ };
238
+
239
  // Pagination states
240
  const [orgPage, setOrgPage] = useState(1);
241
  const [orgPageSize, setOrgPageSize] = useState(25);
 
1199
  {/* BOOKINGS TAB */}
1200
  {activeTab === 'bookings' && (
1201
  <div className="flex flex-col gap-md mb-xl animate-fade-in">
1202
+ <div className="flex flex-col md:flex-row md:items-center justify-between gap-md mb-xs">
1203
+ <h2 className="font-headline-sm font-bold text-on-surface flex items-center text-[18px]">
1204
+ <Calendar className="w-5 h-5 text-primary mr-2" /> Demo Bookings & Leads
1205
+ </h2>
1206
+ <div className="text-[12.5px] font-bold text-on-surface-variant">
1207
+ Total Leads: <span className="text-primary font-extrabold">{getFilteredBookings().length}</span>
1208
+ </div>
1209
+ </div>
1210
+
1211
  <div className="bg-surface border border-outline-variant rounded-2xl overflow-hidden shadow-sm">
1212
+ {/* Filter Controls Bar */}
1213
+ <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">
1214
+ <div className="flex items-center gap-sm flex-wrap w-full md:w-auto">
1215
+ <div className="relative flex-1 md:w-64">
1216
+ <Search className="w-4 h-4 absolute left-3 top-2.5 text-on-surface-variant" />
1217
+ <input
1218
+ type="text"
1219
+ placeholder="Search email, company size, date..."
1220
+ value={bookingSearch}
1221
+ onChange={(e) => { setBookingSearch(e.target.value); setBookingPage(1); }}
1222
+ 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"
1223
+ />
1224
+ {bookingSearch && (
1225
+ <button
1226
+ onClick={() => { setBookingSearch(''); setBookingPage(1); }}
1227
+ 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"
1228
+ >
1229
+ <X className="w-3.5 h-3.5" />
1230
+ </button>
1231
+ )}
1232
+ </div>
1233
+
1234
+ <div className="flex items-center gap-1.5">
1235
+ <span className="text-[11px] font-bold text-on-surface-variant uppercase tracking-wider shrink-0">Status:</span>
1236
+ <select
1237
+ value={bookingStatusFilter}
1238
+ onChange={(e) => { setBookingStatusFilter(e.target.value); setBookingPage(1); }}
1239
+ 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"
1240
+ >
1241
+ <option value="all">All Statuses</option>
1242
+ <option value="pending">Pending</option>
1243
+ <option value="completed">Completed</option>
1244
+ <option value="rescheduled">Rescheduled</option>
1245
+ <option value="cancelled">Cancelled</option>
1246
+ </select>
1247
+ </div>
1248
+
1249
+ {(bookingSearch || bookingStatusFilter !== 'all') && (
1250
+ <button
1251
+ onClick={() => { setBookingSearch(''); setBookingStatusFilter('all'); setBookingPage(1); }}
1252
+ 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"
1253
+ >
1254
+ <X className="w-4 h-4" />
1255
+ Reset Filters
1256
+ </button>
1257
+ )}
1258
+ </div>
1259
+ </div>
1260
+
1261
+ {getFilteredBookings().length === 0 ? (
1262
+ <div className="p-xl text-center text-on-surface-variant font-bold">No demo bookings match your filter criteria.</div>
1263
  ) : (
1264
  <>
1265
  <div className="overflow-x-auto">
 
1274
  </tr>
1275
  </thead>
1276
  <tbody className="divide-y divide-outline-variant">
1277
+ {getFilteredBookings().slice((bookingPage - 1) * bookingPageSize, bookingPage * bookingPageSize).map(b => {
1278
  const statusStyle =
1279
  b.status === 'completed'
1280
  ? 'bg-green-500/10 text-green-600 border-green-500/30'
 
1350
  </div>
1351
  <TablePagination
1352
  currentPage={bookingPage}
1353
+ totalEntries={getFilteredBookings().length}
1354
  pageSize={bookingPageSize}
1355
  onPageChange={setBookingPage}
1356
  onPageSizeChange={setBookingPageSize}