Tools page cards link to the tool detail page, not the program
ProgramCard/ProgramList take an optional linkBase (default /programs); the Tools page passes /tools so a tool tile opens /tools/<name> (its deployment detail), not /programs/<name>.
This commit is contained in:
@@ -5,9 +5,13 @@ import { StackBadge } from "./StackBadge"
|
|||||||
|
|
||||||
interface ProgramCardProps {
|
interface ProgramCardProps {
|
||||||
program: ProgramSummary
|
program: ProgramSummary
|
||||||
|
// Where the card links. Defaults to the program page; the Tools page passes
|
||||||
|
// "/tools" so a tool card opens its tool detail page (a tool is 1:1 with its
|
||||||
|
// program, same name).
|
||||||
|
linkBase?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProgramCard({ program }: ProgramCardProps) {
|
export function ProgramCard({ program, linkBase = "/programs" }: ProgramCardProps) {
|
||||||
// The dot reflects the uniform lifecycle state (a tool on PATH, a service
|
// The dot reflects the uniform lifecycle state (a tool on PATH, a service
|
||||||
// running, a static site served). Lifecycle controls live on the detail page's
|
// running, a static site served). Lifecycle controls live on the detail page's
|
||||||
// Deployment section, not here — a card just shows state and links through.
|
// Deployment section, not here — a card just shows state and links through.
|
||||||
@@ -26,7 +30,7 @@ export function ProgramCard({ program }: ProgramCardProps) {
|
|||||||
title={program.active === true ? "active" : program.active === false ? "inactive" : "no deployment"}
|
title={program.active === true ? "active" : program.active === false ? "inactive" : "no deployment"}
|
||||||
/>
|
/>
|
||||||
<Link
|
<Link
|
||||||
to={`/programs/${program.id}`}
|
to={`${linkBase}/${program.id}`}
|
||||||
className="text-base font-semibold hover:text-[var(--primary)] transition-colors after:absolute after:inset-0"
|
className="text-base font-semibold hover:text-[var(--primary)] transition-colors after:absolute after:inset-0"
|
||||||
>
|
>
|
||||||
{program.id}
|
{program.id}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import { ProgramCard } from "./ProgramCard"
|
|||||||
|
|
||||||
interface ProgramListProps {
|
interface ProgramListProps {
|
||||||
programs: ProgramSummary[]
|
programs: ProgramSummary[]
|
||||||
|
linkBase?: string // where each card links (default "/programs")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProgramList({ programs }: ProgramListProps) {
|
export function ProgramList({ programs, linkBase }: ProgramListProps) {
|
||||||
const [search, setSearch] = useState("")
|
const [search, setSearch] = useState("")
|
||||||
|
|
||||||
const filtered = useMemo(() => {
|
const filtered = useMemo(() => {
|
||||||
@@ -38,7 +39,7 @@ export function ProgramList({ programs }: ProgramListProps) {
|
|||||||
) : (
|
) : (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||||
{filtered.map((program) => (
|
{filtered.map((program) => (
|
||||||
<ProgramCard key={program.id} program={program} />
|
<ProgramCard key={program.id} program={program} linkBase={linkBase} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function Tools() {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<p className="text-[var(--muted)]">Loading...</p>
|
<p className="text-[var(--muted)]">Loading...</p>
|
||||||
) : programs && programs.length > 0 ? (
|
) : programs && programs.length > 0 ? (
|
||||||
<ProgramList programs={programs} />
|
<ProgramList programs={programs} linkBase="/tools" />
|
||||||
) : (
|
) : (
|
||||||
<p className="text-[var(--muted)]">No tools yet.</p>
|
<p className="text-[var(--muted)]">No tools yet.</p>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user