Update meeting page controls with new icons and search functionality

Replaces existing edit and search controls with icon-based components, introducing a collapsible search input.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: ea995ab4-f97a-4789-a4b5-9635490a7ce0
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/jwG0a8d
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
riyadhafraa
2026-05-04 16:22:41 +00:00
parent ce4d2f7340
commit 1ee3f9a55f
2 changed files with 75 additions and 38 deletions
@@ -41,6 +41,7 @@ import {
MoreVertical,
ChevronLeft,
ChevronRight,
Search,
} from "lucide-react";
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible";
import { Button } from "@/components/ui/button";
@@ -2462,54 +2463,27 @@ function ScheduleSection({
}
data-testid="em-edit-mode-toggle"
className={
"inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1 text-sm font-medium transition-colors focus:outline-none focus:ring-2 focus:ring-[#0B1E3F]/40 " +
"inline-flex items-center justify-center rounded-md border w-8 h-8 transition-colors focus:outline-none focus:ring-2 focus:ring-[#0B1E3F]/40 " +
(editMode
? "bg-[#0B1E3F] text-white border-[#0B1E3F] hover:bg-[#0B1E3F]/90"
: "bg-white text-[#0B1E3F] border-gray-300 hover:bg-gray-50")
}
>
{editMode ? (
<Check className="w-3.5 h-3.5" />
<Check className="w-4 h-4" />
) : (
<Pencil className="w-3.5 h-3.5" />
<Pencil className="w-4 h-4" />
)}
<span>
{editMode
? t("executiveMeetings.schedule.saveToggle")
: t("executiveMeetings.schedule.editToggle")}
</span>
</button>
)}
{/* #329: in-day search box. Sits next to the date picker so
the user finds a meeting in the currently visible day
without having to scroll. Hidden in print so PDFs still
show the full schedule. */}
<div className="relative print:hidden">
<Input
type="search"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder={t("executiveMeetings.schedule.searchPlaceholder")}
aria-label={t("executiveMeetings.schedule.searchAria")}
data-testid="em-schedule-search"
className="h-8 w-44 sm:w-56 text-sm bg-white"
/>
{searchQuery && (
<button
type="button"
onClick={() => setSearchQuery("")}
aria-label={t("executiveMeetings.schedule.searchClear")}
title={t("executiveMeetings.schedule.searchClear")}
data-testid="em-schedule-search-clear"
className={
"absolute top-1/2 -translate-y-1/2 text-muted-foreground hover:text-[#0B1E3F] " +
(isRtl ? "left-1.5" : "right-1.5")
}
>
<X className="w-3.5 h-3.5" />
</button>
)}
</div>
<SearchToggle
searchQuery={searchQuery}
onSearchChange={setSearchQuery}
placeholder={t("executiveMeetings.schedule.searchPlaceholder")}
ariaLabel={t("executiveMeetings.schedule.searchAria")}
clearLabel={t("executiveMeetings.schedule.searchClear")}
isRtl={isRtl}
/>
<label className="flex items-center gap-2 text-sm">
<span className="text-muted-foreground">{t("executiveMeetings.date")}</span>
<input
@@ -6554,6 +6528,69 @@ function MeetingFormDialog({
);
}
function SearchToggle({
searchQuery,
onSearchChange,
placeholder,
ariaLabel,
clearLabel,
isRtl,
}: {
searchQuery: string;
onSearchChange: (v: string) => void;
placeholder: string;
ariaLabel: string;
clearLabel: string;
isRtl: boolean;
}) {
const [open, setOpen] = useState(false);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (open) inputRef.current?.focus();
}, [open]);
if (!open && !searchQuery) {
return (
<button
type="button"
onClick={() => setOpen(true)}
aria-label={ariaLabel}
title={ariaLabel}
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white text-[#0B1E3F] w-8 h-8 hover:bg-gray-50 transition-colors focus:outline-none focus:ring-2 focus:ring-[#0B1E3F]/40 print:hidden"
>
<Search className="w-4 h-4" />
</button>
);
}
return (
<div className="relative print:hidden flex items-center gap-1">
<Search className="w-4 h-4 text-muted-foreground shrink-0" />
<Input
ref={inputRef}
type="search"
value={searchQuery}
onChange={(e) => onSearchChange(e.target.value)}
placeholder={placeholder}
aria-label={ariaLabel}
data-testid="em-schedule-search"
className="h-8 w-36 sm:w-48 text-sm bg-white"
/>
<button
type="button"
onClick={() => { onSearchChange(""); setOpen(false); }}
aria-label={clearLabel}
title={clearLabel}
data-testid="em-schedule-search-clear"
className="text-muted-foreground hover:text-[#0B1E3F]"
>
<X className="w-3.5 h-3.5" />
</button>
</div>
);
}
function FormRow({
label,
children,
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB