| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- "use client";
- import React from "react";
- import { AlertCircleIcon } from "lucide-react";
- import { SEARCH_SCOPE } from "@/lib/frontend/search/urlState";
- import SearchQueryBox from "@/components/search/form/SearchQueryBox";
- import SearchScopeSelect from "@/components/search/form/SearchScopeSelect";
- import SearchLimitSelect from "@/components/search/form/SearchLimitSelect";
- import SearchSingleBranchCombobox from "@/components/search/form/SearchSingleBranchCombobox";
- import SearchMultiBranchPicker from "@/components/search/form/SearchMultiBranchPicker";
- import SearchDateRangePicker from "@/components/search/form/SearchDateRangePicker";
- import SearchDateFilterChip from "@/components/search/form/SearchDateFilterChip";
- import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert";
- export default function SearchForm({
- branch,
- qDraft,
- onQDraftChange,
- onSubmit,
- currentQuery,
- isSubmitting,
- isAdminDev,
- scope,
- onScopeChange,
- onSingleBranchChange,
- availableBranches,
- branchesStatus,
- selectedBranches,
- onToggleBranch,
- onClearAllBranches,
- limit,
- onLimitChange,
- from,
- to,
- onDateRangeChange,
- validationError,
- }) {
- const canSearch = typeof qDraft === "string" && qDraft.trim().length > 0;
- // SINGLE scope (admin/dev only) shows an extra branch combobox.
- const showSingleBranchCombobox = Boolean(
- isAdminDev && scope === SEARCH_SCOPE.SINGLE
- );
- const hasDateFilter = Boolean(from || to);
- return (
- <div className="space-y-4">
- <form
- onSubmit={(e) => {
- e.preventDefault();
- if (!canSearch) return;
- onSubmit();
- }}
- className="space-y-4"
- >
- {/* Row 1: query full-width */}
- <div className="w-full">
- <SearchQueryBox
- qDraft={qDraft}
- onQDraftChange={onQDraftChange}
- onSubmit={onSubmit}
- currentQuery={currentQuery}
- isSubmitting={isSubmitting}
- canSearch={canSearch}
- />
- </div>
- {/* Row 2: left controls + spacer + limit on the right */}
- <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
- {/* Left group: scope (+ optional single branch combobox) + date range */}
- <div className="flex flex-col gap-3 sm:flex-row sm:items-end">
- {isAdminDev ? (
- <div className="flex items-end gap-3">
- <SearchScopeSelect
- branch={branch}
- scope={scope}
- onScopeChange={onScopeChange}
- isSubmitting={isSubmitting}
- />
- {/* Animated presence (kept for smoothness when SINGLE shows the extra combobox) */}
- <div
- className={[
- "overflow-hidden transition-all duration-200 ease-in-out",
- showSingleBranchCombobox
- ? "max-w-44 max-h-24 opacity-100"
- : "max-w-0 max-h-0 opacity-0 pointer-events-none",
- ].join(" ")}
- aria-hidden={showSingleBranchCombobox ? "false" : "true"}
- >
- <SearchSingleBranchCombobox
- branch={branch}
- branchesStatus={branchesStatus}
- availableBranches={availableBranches}
- onSingleBranchChange={onSingleBranchChange}
- isSubmitting={isSubmitting || !showSingleBranchCombobox}
- />
- </div>
- </div>
- ) : null}
- <div className="shrink-0 flex items-end gap-4">
- <SearchDateRangePicker
- from={from}
- to={to}
- onDateRangeChange={onDateRangeChange}
- isSubmitting={isSubmitting}
- />
- {/* Active date filter chip (quick clear) */}
- {hasDateFilter ? (
- <div className="flex flex-wrap items-center gap-2 mb-2">
- <span className="text-xs text-muted-foreground">
- Aktive Filter:
- </span>
- <SearchDateFilterChip
- from={from}
- to={to}
- isSubmitting={isSubmitting}
- onClear={() => {
- if (typeof onDateRangeChange !== "function") return;
- onDateRangeChange({ from: null, to: null });
- }}
- />
- </div>
- ) : null}
- </div>
- </div>
- {/* Right group: limit aligned right */}
- <div className="shrink-0">
- <SearchLimitSelect
- limit={limit}
- onLimitChange={onLimitChange}
- isSubmitting={isSubmitting}
- />
- </div>
- </div>
- </form>
- {/* Validation feedback belongs near the inputs (not in results). */}
- {validationError ? (
- <Alert variant="destructive">
- <AlertCircleIcon />
- <AlertTitle>{validationError.title}</AlertTitle>
- <AlertDescription>{validationError.description}</AlertDescription>
- </Alert>
- ) : null}
- {/* Multi scope branch picker remains below */}
- {isAdminDev && scope === SEARCH_SCOPE.MULTI ? (
- <SearchMultiBranchPicker
- branchesStatus={branchesStatus}
- availableBranches={availableBranches}
- selectedBranches={selectedBranches}
- onToggleBranch={onToggleBranch}
- onClearAllBranches={onClearAllBranches}
- isSubmitting={isSubmitting}
- />
- ) : null}
- </div>
- );
- }
|