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:
@@ -1,14 +1,18 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useRef } from "react";
|
||||
import { Search, X } from "lucide-react";
|
||||
import { Search, X, Filter } from "lucide-react";
|
||||
import { adminFetch } from "@/lib/csrf";
|
||||
import type { SearchResult } from "./types";
|
||||
import { type BookingFilter, type SearchResult, BOOKING_STATUSES } from "./types";
|
||||
|
||||
export function SearchBar({
|
||||
filter,
|
||||
onFilterChange,
|
||||
onResults,
|
||||
onClear,
|
||||
}: {
|
||||
filter: BookingFilter;
|
||||
onFilterChange: (f: BookingFilter) => void;
|
||||
onResults: (results: SearchResult[]) => void;
|
||||
onClear: () => void;
|
||||
}) {
|
||||
@@ -35,20 +39,48 @@ export function SearchBar({
|
||||
onClear();
|
||||
}
|
||||
|
||||
const isSearching = query.trim().length >= 2;
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-neutral-500" />
|
||||
<input
|
||||
type="text"
|
||||
value={query}
|
||||
onChange={(e) => handleChange(e.target.value)}
|
||||
placeholder="Поиск по имени или телефону..."
|
||||
className="w-full rounded-lg border border-white/[0.08] bg-white/[0.04] py-2 pl-9 pr-8 text-sm text-white placeholder-neutral-500 outline-none focus:border-gold/40"
|
||||
/>
|
||||
{query && (
|
||||
<button onClick={clear} className="absolute right-2 top-1/2 -translate-y-1/2 text-neutral-500 hover:text-white">
|
||||
<X size={14} />
|
||||
</button>
|
||||
<div className="space-y-2">
|
||||
<div className="relative">
|
||||
<Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-neutral-500" />
|
||||
<input
|
||||
type="text"
|
||||
value={query}
|
||||
onChange={(e) => handleChange(e.target.value)}
|
||||
placeholder="Поиск по имени или телефону..."
|
||||
className="w-full rounded-lg border border-white/[0.08] bg-white/[0.04] py-2 pl-9 pr-8 text-sm text-white placeholder-neutral-500 outline-none focus:border-gold/40"
|
||||
/>
|
||||
{query && (
|
||||
<button onClick={clear} className="absolute right-2 top-1/2 -translate-y-1/2 text-neutral-500 hover:text-white">
|
||||
<X size={14} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{!isSearching && (
|
||||
<div className="flex items-center gap-1.5">
|
||||
<Filter size={12} className="text-neutral-600 shrink-0" />
|
||||
<button
|
||||
onClick={() => onFilterChange("all")}
|
||||
className={`rounded-full px-2.5 py-1 text-[11px] font-medium transition-all ${
|
||||
filter === "all" ? "bg-gold/20 text-gold border border-gold/40" : "text-neutral-500 hover:text-neutral-300"
|
||||
}`}
|
||||
>
|
||||
Все
|
||||
</button>
|
||||
{BOOKING_STATUSES.map((s) => (
|
||||
<button
|
||||
key={s.key}
|
||||
onClick={() => onFilterChange(filter === s.key ? "all" : s.key)}
|
||||
className={`rounded-full px-2.5 py-1 text-[11px] font-medium transition-all ${
|
||||
filter === s.key ? `${s.bg} ${s.color} border ${s.border}` : "text-neutral-500 hover:text-neutral-300"
|
||||
}`}
|
||||
>
|
||||
{s.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user