91 lines
3.0 KiB
TypeScript
91 lines
3.0 KiB
TypeScript
"use client"
|
|
|
|
import { useState, useRef, useEffect, useCallback } from "react"
|
|
import { Menu, Search, X, ChevronLeft, Pencil } from "lucide-react"
|
|
import { Button } from "@/components/ui/button"
|
|
import { useCompose } from "@/lib/compose-context"
|
|
|
|
interface MobileBottomBarProps {
|
|
sidebarOpen: boolean
|
|
onToggleSidebar: () => void
|
|
}
|
|
|
|
export function MobileBottomBar({
|
|
sidebarOpen,
|
|
onToggleSidebar,
|
|
}: MobileBottomBarProps) {
|
|
const [searchValue, setSearchValue] = useState("")
|
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
const { openCompose } = useCompose()
|
|
|
|
const hasSearch = searchValue.length > 0
|
|
|
|
const handleClear = useCallback(() => {
|
|
setSearchValue("")
|
|
inputRef.current?.focus()
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
if (sidebarOpen) {
|
|
inputRef.current?.blur()
|
|
}
|
|
}, [sidebarOpen])
|
|
|
|
return (
|
|
<div className="fixed inset-x-0 bottom-0 z-50 flex flex-col items-center pb-[env(safe-area-inset-bottom)] sm:hidden">
|
|
<div className="pointer-events-none absolute inset-0 bg-gradient-to-t from-white/95 via-white/70 to-transparent" />
|
|
|
|
<div className="relative z-10 flex w-full items-center gap-2 px-3 pb-3 pt-2">
|
|
{/* Burger / back-caret */}
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="size-11 shrink-0 rounded-full border border-gray-200 bg-white/80 shadow-md backdrop-blur"
|
|
onClick={onToggleSidebar}
|
|
aria-label={sidebarOpen ? "Fermer le menu" : "Ouvrir le menu"}
|
|
>
|
|
{sidebarOpen ? (
|
|
<ChevronLeft className="size-5" />
|
|
) : (
|
|
<Menu className="size-5" />
|
|
)}
|
|
</Button>
|
|
|
|
{/* Search bar — hidden when sidebar open */}
|
|
{!sidebarOpen && (
|
|
<div className="relative flex min-w-0 flex-1 items-center">
|
|
<div className="pointer-events-none absolute left-3 z-10 flex items-center text-gray-500">
|
|
<Search className="size-5" />
|
|
</div>
|
|
<input
|
|
ref={inputRef}
|
|
type="text"
|
|
value={searchValue}
|
|
onChange={(e) => setSearchValue(e.target.value)}
|
|
placeholder="Rechercher"
|
|
className="h-11 w-full rounded-full border border-gray-200 bg-white/80 pl-10 pr-4 text-sm shadow-md backdrop-blur outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-blue-500/40"
|
|
/>
|
|
</div>
|
|
)}
|
|
|
|
{/* New-message / clear-search — hidden when sidebar open */}
|
|
{!sidebarOpen && (
|
|
<Button
|
|
variant="ghost"
|
|
size="icon"
|
|
className="size-11 shrink-0 rounded-full border border-gray-200 bg-white/80 shadow-md backdrop-blur"
|
|
onClick={hasSearch ? handleClear : openCompose}
|
|
aria-label={hasSearch ? "Effacer la recherche" : "Nouveau message"}
|
|
>
|
|
{hasSearch ? (
|
|
<X className="size-5" />
|
|
) : (
|
|
<Pencil className="size-5" />
|
|
)}
|
|
</Button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|