Files
dark-lord/components/forum/ForumFeedToolbar.tsx
drjones 78a071ba02 Harden onion boot flow and deepen site surfaces
Add persistent onion key backup and restore, improve startup resilience, and flesh out the major site verticals with richer navigation, search coverage, and operator documentation.

Made-with: Cursor
2026-04-07 21:35:52 -07:00

102 lines
3.5 KiB
TypeScript

"use client";
import type { ReactNode } from "react";
import Link from "next/link";
import { FORUM_RINGS } from "@/lib/forumRings";
import type { ForumSortMode } from "@/lib/forumSort";
type Props = {
sort: ForumSortMode;
onSortChange: (m: ForumSortMode) => void;
search: string;
onSearchChange: (q: string) => void;
/** When set, show ring chips + `null` = all rings. Omit `onRingChange` to hide chips (ring sub-page). */
ringFilter: string | null;
onRingChange?: (slug: string | null) => void;
extraRight?: ReactNode;
threadCount?: number;
hydrated?: boolean;
};
export default function ForumFeedToolbar({
sort,
onSortChange,
search,
onSearchChange,
ringFilter,
onRingChange,
extraRight,
threadCount,
hydrated,
}: Props) {
return (
<div className="space-y-4 border-b border-[#3d3228] pb-4">
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<label className="min-w-0 flex-1 font-mono text-[10px] uppercase tracking-wider text-[#8a7d6b]">
<span className="mb-1 block text-[#ff9a3c]/70">Search threads</span>
<input
value={search}
onChange={(e) => onSearchChange(e.target.value)}
placeholder="Title, body, author, ring…"
className="w-full rounded border border-[#3d3228] bg-[#0d0a07] px-3 py-2 font-mono text-sm text-[#e7d9c8] placeholder:text-[#5c5044] focus:border-[#ff9a3c]/60 focus:outline-none"
/>
</label>
<div className="flex shrink-0 flex-wrap items-center gap-2">
{(["hot", "new", "top"] as const).map((m) => (
<button
key={m}
type="button"
onClick={() => onSortChange(m)}
className={`rounded px-3 py-1.5 font-mono text-[11px] font-bold uppercase tracking-wider ${
sort === m ? "bg-[#c45c26]/40 text-[#ffcb8a]" : "text-[#8a7d6b] hover:text-[#ffcb8a]"
}`}
>
{m}
</button>
))}
</div>
</div>
{onRingChange ? (
<div className="flex flex-wrap items-center gap-2 font-mono text-[10px] uppercase tracking-wider">
<span className="text-[#5c5044]">Ring</span>
<button
type="button"
onClick={() => onRingChange(null)}
className={`rounded px-2.5 py-1 font-bold ${
ringFilter === null ? "bg-[#3d3228] text-[#ffcb8a]" : "text-[#8a7d6b] hover:text-[#ffcb8a]"
}`}
>
all
</button>
{FORUM_RINGS.map((r) => (
<button
key={r.slug}
type="button"
onClick={() => onRingChange(r.slug)}
className={`rounded px-2.5 py-1 font-bold ${
ringFilter === r.slug ? "bg-[#ff9a3c]/20 text-[#ffcb8a]" : "text-[#8a7d6b] hover:text-[#ffcb8a]"
}`}
>
r/{r.shortName}
</button>
))}
</div>
) : null}
<div className="flex flex-wrap items-center justify-between gap-2 font-mono text-[10px] text-[#5c5044]">
<span>{hydrated === false ? "…" : threadCount !== undefined ? `${threadCount} threads` : null}</span>
<div className="flex flex-wrap items-center gap-2">
{extraRight}
<Link
href="/forum/submit"
className="rounded border border-[#ff9a3c]/60 px-3 py-1 font-bold uppercase text-[#ffcb8a] hover:bg-[#ff9a3c]/15"
>
+ New post
</Link>
</div>
</div>
</div>
);
}