Compare commits
No commits in common. "652be41da4c988ab5b9cbf1808b62406d88b5496" and "bb5cbfa4b33ece32503692725eb61c9894ca9ebb" have entirely different histories.
652be41da4
...
bb5cbfa4b3
@ -291,19 +291,21 @@ export default function LocationsPage() {
|
|||||||
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
|
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
|
||||||
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Locations</h1>
|
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">Locations</h1>
|
||||||
|
|
||||||
<CategoryFilterBar
|
<div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none">
|
||||||
categories={orderedCategories}
|
<CategoryFilterBar
|
||||||
activeFilters={activeFilters}
|
categories={orderedCategories}
|
||||||
pinnedLabel="Frequent"
|
activeFilters={activeFilters}
|
||||||
showPinned={showPinned}
|
pinnedLabel="Frequent"
|
||||||
onToggleAll={() => setActiveFilters([])}
|
showPinned={showPinned}
|
||||||
onTogglePinned={() => setShowPinned((v) => !v)}
|
onToggleAll={() => setActiveFilters([])}
|
||||||
onToggleCategory={handleToggleCategory}
|
onTogglePinned={() => setShowPinned((v) => !v)}
|
||||||
onSelectAllCategories={selectAllCategories}
|
onToggleCategory={handleToggleCategory}
|
||||||
onReorderCategories={reorderCategories}
|
onSelectAllCategories={selectAllCategories}
|
||||||
searchValue={search}
|
onReorderCategories={reorderCategories}
|
||||||
onSearchChange={setSearch}
|
searchValue={search}
|
||||||
/>
|
onSearchChange={setSearch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button onClick={() => setShowForm(true)} size="sm" aria-label="Add location">
|
<Button onClick={() => setShowForm(true)} size="sm" aria-label="Add location">
|
||||||
<Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Location</span>
|
<Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Location</span>
|
||||||
|
|||||||
@ -560,26 +560,28 @@ export default function PeoplePage() {
|
|||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
|
<div className="border-b bg-card px-4 md:px-6 min-h-[4rem] flex items-center gap-2 md:gap-4 flex-wrap py-2 md:py-0 md:h-16 md:flex-nowrap shrink-0">
|
||||||
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">People</h1>
|
<h1 className="font-heading text-xl md:text-2xl font-bold tracking-tight">People</h1>
|
||||||
<CategoryFilterBar
|
<div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none">
|
||||||
activeFilters={activeFilters}
|
<CategoryFilterBar
|
||||||
pinnedLabel="Favourites"
|
activeFilters={activeFilters}
|
||||||
showPinned={showPinned}
|
pinnedLabel="Favourites"
|
||||||
categories={orderedCategories}
|
showPinned={showPinned}
|
||||||
onToggleAll={toggleAll}
|
categories={orderedCategories}
|
||||||
onTogglePinned={togglePinned}
|
onToggleAll={toggleAll}
|
||||||
onToggleCategory={toggleCategory}
|
onTogglePinned={togglePinned}
|
||||||
onSelectAllCategories={selectAllCategories}
|
onToggleCategory={toggleCategory}
|
||||||
onReorderCategories={reorderCategories}
|
onSelectAllCategories={selectAllCategories}
|
||||||
searchValue={search}
|
onReorderCategories={reorderCategories}
|
||||||
onSearchChange={setSearch}
|
searchValue={search}
|
||||||
extraPinnedFilters={[
|
onSearchChange={setSearch}
|
||||||
{
|
extraPinnedFilters={[
|
||||||
label: 'Umbral',
|
{
|
||||||
isActive: showUmbralOnly,
|
label: 'Umbral',
|
||||||
onToggle: () => setShowUmbralOnly((p) => !p),
|
isActive: showUmbralOnly,
|
||||||
},
|
onToggle: () => setShowUmbralOnly((p) => !p),
|
||||||
]}
|
},
|
||||||
/>
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="relative" ref={addDropdownRef}>
|
<div className="relative" ref={addDropdownRef}>
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@ -146,72 +146,90 @@ export default function CategoryFilterBar({
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center gap-2 overflow-x-auto min-w-0 flex-1">
|
<div className="flex flex-col gap-2 md:flex-row md:items-center md:gap-2">
|
||||||
{/* All pill */}
|
{/* Top row: pills + search */}
|
||||||
<button
|
<div className="flex items-center gap-2 overflow-x-auto min-w-0 flex-1">
|
||||||
type="button"
|
{/* All pill */}
|
||||||
onClick={onToggleAll}
|
|
||||||
aria-label="Show all"
|
|
||||||
className={pillBase}
|
|
||||||
style={isAllActive ? activePillStyle : undefined}
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
className={
|
|
||||||
isAllActive ? '' : 'text-muted-foreground hover:text-foreground hover:bg-card-elevated'
|
|
||||||
}
|
|
||||||
>
|
|
||||||
All
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Pinned pill */}
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={onTogglePinned}
|
|
||||||
aria-label={`Toggle ${pinnedLabel}`}
|
|
||||||
className={pillBase}
|
|
||||||
style={showPinned ? activePillStyle : undefined}
|
|
||||||
>
|
|
||||||
<span className={showPinned ? '' : 'text-muted-foreground hover:text-foreground'}>
|
|
||||||
{pinnedLabel}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
{/* Extra pinned filters (e.g. "Umbral") */}
|
|
||||||
{extraPinnedFilters.map((epf) => (
|
|
||||||
<button
|
|
||||||
key={epf.label}
|
|
||||||
type="button"
|
|
||||||
onClick={epf.onToggle}
|
|
||||||
aria-label={`Filter by ${epf.label}`}
|
|
||||||
className={pillBase}
|
|
||||||
style={epf.isActive ? activePillStyle : undefined}
|
|
||||||
>
|
|
||||||
<span className={epf.isActive ? '' : 'text-muted-foreground hover:text-foreground'}>
|
|
||||||
{epf.label}
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
))}
|
|
||||||
|
|
||||||
{/* Categories pill */}
|
|
||||||
{categories.length > 0 && (
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setOtherOpen((p) => !p)}
|
onClick={onToggleAll}
|
||||||
aria-label="Toggle category filters"
|
aria-label="Show all"
|
||||||
className={pillBase}
|
className={pillBase}
|
||||||
style={otherOpen ? activePillStyle : undefined}
|
style={isAllActive ? activePillStyle : undefined}
|
||||||
>
|
>
|
||||||
<span className={otherOpen ? '' : 'text-muted-foreground hover:text-foreground'}>
|
<span
|
||||||
Categories
|
className={
|
||||||
|
isAllActive ? '' : 'text-muted-foreground hover:text-foreground hover:bg-card-elevated'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
All
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Expanded category chips — inline after Categories pill */}
|
{/* Pinned pill */}
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={onTogglePinned}
|
||||||
|
aria-label={`Toggle ${pinnedLabel}`}
|
||||||
|
className={pillBase}
|
||||||
|
style={showPinned ? activePillStyle : undefined}
|
||||||
|
>
|
||||||
|
<span className={showPinned ? '' : 'text-muted-foreground hover:text-foreground'}>
|
||||||
|
{pinnedLabel}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{/* Extra pinned filters (e.g. "Umbral") */}
|
||||||
|
{extraPinnedFilters.map((epf) => (
|
||||||
|
<button
|
||||||
|
key={epf.label}
|
||||||
|
type="button"
|
||||||
|
onClick={epf.onToggle}
|
||||||
|
aria-label={`Filter by ${epf.label}`}
|
||||||
|
className={pillBase}
|
||||||
|
style={epf.isActive ? activePillStyle : undefined}
|
||||||
|
>
|
||||||
|
<span className={epf.isActive ? '' : 'text-muted-foreground hover:text-foreground'}>
|
||||||
|
{epf.label}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* Categories pill */}
|
||||||
|
{categories.length > 0 && (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setOtherOpen((p) => !p)}
|
||||||
|
aria-label="Toggle category filters"
|
||||||
|
className={pillBase}
|
||||||
|
style={otherOpen ? activePillStyle : undefined}
|
||||||
|
>
|
||||||
|
<span className={otherOpen ? '' : 'text-muted-foreground hover:text-foreground'}>
|
||||||
|
Categories
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Search */}
|
||||||
|
<div className="flex-1" />
|
||||||
|
<div className="relative shrink-0">
|
||||||
|
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
|
||||||
|
<Input
|
||||||
|
ref={searchInputRef}
|
||||||
|
type="search"
|
||||||
|
placeholder="Search..."
|
||||||
|
value={searchValue}
|
||||||
|
onChange={(e) => onSearchChange(e.target.value)}
|
||||||
|
className="w-28 sm:w-52 h-8 pl-8 text-sm ring-inset"
|
||||||
|
aria-label="Search"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Expanded categories row — shows below on mobile, inline on desktop */}
|
||||||
{categories.length > 0 && otherOpen && (
|
{categories.length > 0 && otherOpen && (
|
||||||
<>
|
<div className="flex items-center gap-1.5 overflow-x-auto pb-1 md:pb-0">
|
||||||
<div className="w-px h-5 bg-border shrink-0" />
|
{/* "All" chip inside categories — non-draggable */}
|
||||||
{onSelectAllCategories && (
|
{onSelectAllCategories && (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
@ -232,6 +250,8 @@ export default function CategoryFilterBar({
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Draggable category chips */}
|
||||||
<DndContext
|
<DndContext
|
||||||
sensors={sensors}
|
sensors={sensors}
|
||||||
collisionDetection={closestCenter}
|
collisionDetection={closestCenter}
|
||||||
@ -252,23 +272,8 @@ export default function CategoryFilterBar({
|
|||||||
))}
|
))}
|
||||||
</SortableContext>
|
</SortableContext>
|
||||||
</DndContext>
|
</DndContext>
|
||||||
</>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Search — pushed to the right */}
|
|
||||||
<div className="flex-1" />
|
|
||||||
<div className="relative shrink-0">
|
|
||||||
<Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground pointer-events-none" />
|
|
||||||
<Input
|
|
||||||
ref={searchInputRef}
|
|
||||||
type="search"
|
|
||||||
placeholder="Search..."
|
|
||||||
value={searchValue}
|
|
||||||
onChange={(e) => onSearchChange(e.target.value)}
|
|
||||||
className="w-28 sm:w-52 h-8 pl-8 text-sm ring-inset"
|
|
||||||
aria-label="Search"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -168,19 +168,21 @@ export default function TodosPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Category filter bar (All + Completed + Categories with drag) */}
|
{/* Category filter bar (All + Completed + Categories with drag) */}
|
||||||
<CategoryFilterBar
|
<div className="w-full md:flex-1 md:w-auto min-w-0 order-last md:order-none">
|
||||||
activeFilters={activeFilters}
|
<CategoryFilterBar
|
||||||
pinnedLabel="Completed"
|
activeFilters={activeFilters}
|
||||||
showPinned={showCompleted}
|
pinnedLabel="Completed"
|
||||||
categories={orderedCategories}
|
showPinned={showCompleted}
|
||||||
onToggleAll={toggleAll}
|
categories={orderedCategories}
|
||||||
onTogglePinned={toggleCompleted}
|
onToggleAll={toggleAll}
|
||||||
onToggleCategory={toggleCategory}
|
onTogglePinned={toggleCompleted}
|
||||||
onSelectAllCategories={selectAllCategories}
|
onToggleCategory={toggleCategory}
|
||||||
onReorderCategories={reorderCategories}
|
onSelectAllCategories={selectAllCategories}
|
||||||
searchValue={search}
|
onReorderCategories={reorderCategories}
|
||||||
onSearchChange={setSearch}
|
searchValue={search}
|
||||||
/>
|
onSearchChange={setSearch}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button onClick={handleCreateNew} size="sm">
|
<Button onClick={handleCreateNew} size="sm">
|
||||||
<Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Todo</span>
|
<Plus className="h-4 w-4 md:mr-2" /><span className="hidden md:inline">Add Todo</span>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user