refactor: move status filter from per-tab pills to global search bar
- Remove FilterTabs from inside each booking tab - Add compact status chips (Все/Новая/Связались/Подтверждено/Отказ) below the search bar — one global filter for all tabs - Filter chips hidden during active text search - Status filter toggles on click (click again to deselect) - GenericBookingsList accepts filter as prop instead of managing internally
This commit is contained in:
@@ -4,7 +4,7 @@ import { useState, useEffect, useMemo, useCallback, useRef } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Phone, Instagram, Send, ChevronDown, ChevronRight, Bell, CheckCircle2, XCircle, Clock, Star, Calendar, DoorOpen, X, Plus } from "lucide-react";
|
||||
import { adminFetch } from "@/lib/csrf";
|
||||
import { type BookingStatus, type SearchResult, BOOKING_STATUSES, SHORT_DAYS, fmtDate } from "./types";
|
||||
import { type BookingStatus, type BookingFilter, type SearchResult, BOOKING_STATUSES, SHORT_DAYS, fmtDate } from "./types";
|
||||
import { LoadingSpinner, ContactLinks, BookingCard, StatusBadge, StatusActions, DeleteBtn } from "./BookingComponents";
|
||||
import { GenericBookingsList } from "./GenericBookingsList";
|
||||
import { AddBookingModal } from "./AddBookingModal";
|
||||
@@ -230,7 +230,7 @@ function ConfirmModal({
|
||||
interface ScheduleClassInfo { type: string; trainer: string; time: string; day: string; hall: string; address: string; groupId?: string }
|
||||
interface ScheduleLocation { name: string; address: string; days: { day: string; classes: { time: string; trainer: string; type: string; groupId?: string }[] }[] }
|
||||
|
||||
function GroupBookingsTab() {
|
||||
function GroupBookingsTab({ filter }: { filter: BookingFilter }) {
|
||||
const [bookings, setBookings] = useState<GroupBooking[]>([]);
|
||||
const [allClasses, setAllClasses] = useState<ScheduleClassInfo[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -294,6 +294,7 @@ function GroupBookingsTab() {
|
||||
<GenericBookingsList<GroupBooking>
|
||||
items={bookings}
|
||||
endpoint="/api/admin/group-bookings"
|
||||
filter={filter}
|
||||
onItemsChange={setBookings}
|
||||
onConfirm={(id) => setConfirmingId(id)}
|
||||
renderExtra={(b) => (
|
||||
@@ -696,6 +697,7 @@ function BookingsPageInner() {
|
||||
const [tab, setTab] = useState<Tab>("reminders");
|
||||
const [addOpen, setAddOpen] = useState(false);
|
||||
const [searchResults, setSearchResults] = useState<SearchResult[] | null>(null);
|
||||
const [statusFilter, setStatusFilter] = useState<BookingFilter>("all");
|
||||
const [newBookingsBanner, setNewBookingsBanner] = useState(false);
|
||||
const lastTotalRef = useRef<number | null>(null);
|
||||
const { showError } = useToast();
|
||||
@@ -782,6 +784,8 @@ function BookingsPageInner() {
|
||||
{/* Search */}
|
||||
<div className="mt-3">
|
||||
<SearchBar
|
||||
filter={statusFilter}
|
||||
onFilterChange={setStatusFilter}
|
||||
onResults={setSearchResults}
|
||||
onClear={() => setSearchResults(null)}
|
||||
/>
|
||||
@@ -844,9 +848,9 @@ function BookingsPageInner() {
|
||||
{/* Tab content — no key={refreshKey}, banner handles new data */}
|
||||
<div className="mt-4">
|
||||
{tab === "reminders" && <RemindersTab />}
|
||||
{tab === "classes" && <GroupBookingsTab />}
|
||||
{tab === "master-classes" && <McRegistrationsTab />}
|
||||
{tab === "open-day" && <OpenDayBookingsTab />}
|
||||
{tab === "classes" && <GroupBookingsTab filter={statusFilter} />}
|
||||
{tab === "master-classes" && <McRegistrationsTab filter={statusFilter} />}
|
||||
{tab === "open-day" && <OpenDayBookingsTab filter={statusFilter} />}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user