72 lines
2.2 KiB
TypeScript
72 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useTransition } from "react";
|
|
import { useRouter } from "next/navigation";
|
|
|
|
import { BandView } from "@/components/roadmap/band-view";
|
|
import { TimelineView } from "@/components/roadmap/timeline-view";
|
|
import { rescheduleCardAction } from "@/app/actions/reschedule";
|
|
import type { RoadmapCard as Card } from "@/lib/roadmap/load";
|
|
|
|
export function RoadmapTabs({
|
|
cards,
|
|
inboxCount,
|
|
canReschedule,
|
|
}: {
|
|
cards: Card[];
|
|
inboxCount: number;
|
|
canReschedule: boolean;
|
|
}) {
|
|
const router = useRouter();
|
|
const [tab, setTab] = useState<"bands" | "timeline">("bands");
|
|
const [, startTransition] = useTransition();
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
// Bands exclude Inbox and Done; the timeline shows everything schedulable.
|
|
const banded = cards.filter((card) => card.band !== null);
|
|
|
|
return (
|
|
<div className="space-y-5">
|
|
<div className="inline-flex rounded-lg border border-border-subtle bg-surface p-0.5">
|
|
{(["bands", "timeline"] as const).map((key) => (
|
|
<button
|
|
key={key}
|
|
type="button"
|
|
aria-pressed={tab === key}
|
|
onClick={() => setTab(key)}
|
|
className={`rounded-md px-3 py-1.5 text-xs font-medium transition-colors ${
|
|
tab === key
|
|
? "bg-panel text-text-primary shadow-[var(--shadow-tile)]"
|
|
: "text-text-muted hover:text-text-secondary"
|
|
}`}
|
|
>
|
|
{key === "bands" ? "Now / Next / Later" : "Timeline"}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
{error && (
|
|
<p role="alert" className="text-xs text-accent">
|
|
{error}
|
|
</p>
|
|
)}
|
|
|
|
{tab === "bands" ? (
|
|
<BandView cards={banded} inboxCount={inboxCount} />
|
|
) : (
|
|
<TimelineView
|
|
cards={banded}
|
|
canReschedule={canReschedule}
|
|
onReschedule={(cardId, date) =>
|
|
startTransition(async () => {
|
|
setError(null);
|
|
const result = await rescheduleCardAction({ cardId, date });
|
|
if (!result.ok) setError(result.message ?? "Could not move that card");
|
|
else router.refresh();
|
|
})
|
|
}
|
|
/>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|