Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 419 additions & 0 deletions docs/plans/2026-06-04-seekersai-site-architecture.md

Large diffs are not rendered by default.

99 changes: 95 additions & 4 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ describe("App", () => {
expect(screen.getByRole("navigation", { name: /primary/i })).toBeInTheDocument();
expect(screen.getByRole("link", { name: /quickfork home/i })).toBeInTheDocument();
expect(screen.getByRole("link", { name: /product/i })).toHaveAttribute("href", "#studio");
expect(screen.getByRole("link", { name: /pricing/i })).toHaveAttribute("href", "#pricing");
expect(within(screen.getByRole("navigation", { name: /primary/i })).getByRole("link", { name: /pricing/i })).toHaveAttribute(
"href",
"#pricing",
);
const footerNav = screen.getByRole("navigation", { name: /footer/i });
expect(within(footerNav).getByRole("link", { name: /^contact$/i })).toHaveAttribute("href", "/contact");
expect(within(footerNav).getByRole("link", { name: /^help$/i })).toHaveAttribute("href", "/help");
Expand Down Expand Up @@ -94,6 +97,90 @@ describe("App", () => {
expect(screen.getByRole("heading", { name: /From GitHub URL to multilingual launch package/i })).toBeInTheDocument();
}, 10000);

it("exposes the published growth architecture through header and footer navigation", () => {
render(<App />);

const primaryNav = screen.getByRole("navigation", { name: /primary/i });
expect(within(primaryNav).getByRole("link", { name: /^product/i })).toHaveAttribute("href", "#studio");
expect(within(primaryNav).getByRole("link", { name: /^use cases/i })).toHaveAttribute(
"href",
"/use-cases/open-source-launch",
);
expect(within(primaryNav).getByRole("link", { name: /^resources/i })).toHaveAttribute(
"href",
"/resources/open-source-launch-checklist",
);
expect(within(primaryNav).getByRole("link", { name: /^examples/i })).toHaveAttribute(
"href",
"/examples/qwenlm-flashqla-launch-card",
);
expect(within(primaryNav).getByRole("link", { name: /generate free repo brief/i })).toHaveAttribute("href", "#studio");

const productMenu = screen.getByLabelText(/quickfork product menu/i);
expect(within(productMenu).getByRole("link", { name: /repo to launch package/i })).toHaveAttribute(
"href",
"/product/github-repo-to-launch-package",
);
expect(within(productMenu).getByRole("link", { name: /source-backed launch assets/i })).toHaveAttribute(
"href",
"/product/source-backed-launch-assets",
);
expect(within(productMenu).getByRole("link", { name: /launch package pilot/i })).toHaveAttribute(
"href",
"/product/repository-launch-package-pilot",
);

const resourcesMenu = screen.getByLabelText(/quickfork resources menu/i);
expect(within(resourcesMenu).getByRole("link", { name: /launch readiness score/i })).toHaveAttribute(
"href",
"/tools/github-repo-launch-readiness-score",
);
expect(within(resourcesMenu).getByRole("link", { name: /launch announcement template/i })).toHaveAttribute(
"href",
"/templates/github-launch-announcement",
);

const footerNav = screen.getByRole("navigation", { name: /footer/i });
expect(within(footerNav).getByRole("heading", { name: /^product$/i })).toBeInTheDocument();
expect(within(footerNav).getByRole("heading", { name: /^resources$/i })).toBeInTheDocument();
expect(within(footerNav).getByRole("heading", { name: /^legal and ai discovery$/i })).toBeInTheDocument();
expect(within(footerNav).getByRole("link", { name: /repo to launch package/i })).toHaveAttribute(
"href",
"/product/github-repo-to-launch-package",
);
expect(within(footerNav).getByRole("link", { name: /launch demand map/i })).toHaveAttribute(
"href",
"/resources/github-repo-launch-demand-map",
);
expect(within(footerNav).getByRole("link", { name: /^llms\.txt$/i })).toHaveAttribute("href", "/llms.txt");
expect(within(footerNav).getByRole("link", { name: /^pricing\.md$/i })).toHaveAttribute("href", "/pricing.md");
});

it("renders marketing breadcrumbs and curated related routes for high-priority pages", () => {
window.history.replaceState({}, "", "/product/github-repo-to-launch-package");

render(<App />);

const breadcrumbs = screen.getByRole("navigation", { name: /breadcrumb/i });
expect(within(breadcrumbs).getByRole("link", { name: /^home$/i })).toHaveAttribute("href", "/");
expect(within(breadcrumbs).getByText(/^Product$/i)).toBeInTheDocument();
expect(within(breadcrumbs).getByText(/GitHub Repo To Launch Package/i)).toBeInTheDocument();

const relatedRoutes = screen.getByRole("region", { name: /related routes/i });
expect(within(relatedRoutes).getByRole("link", { name: /^use case: open source launch$/i })).toHaveAttribute(
"href",
"/use-cases/open-source-launch",
);
expect(within(relatedRoutes).getByRole("link", { name: /^resource: open source launch checklist$/i })).toHaveAttribute(
"href",
"/resources/open-source-launch-checklist",
);
expect(within(relatedRoutes).getByRole("link", { name: /^tool: github repo launch readiness score$/i })).toHaveAttribute(
"href",
"/tools/github-repo-launch-readiness-score",
);
});

it("keeps the generator studio inside the redesigned frontend", () => {
render(<App />);

Expand Down Expand Up @@ -1120,7 +1207,10 @@ describe("App", () => {
expect(screen.getByRole("heading", { name: /help center/i })).toBeInTheDocument();
expect(screen.getByRole("link", { name: /quickfork home/i })).toHaveAttribute("href", "/#hero");
expect(screen.getByRole("link", { name: /product/i })).toHaveAttribute("href", "/#studio");
expect(screen.getByRole("link", { name: /pricing/i })).toHaveAttribute("href", "/#pricing");
expect(within(screen.getByRole("navigation", { name: /primary/i })).getByRole("link", { name: /pricing/i })).toHaveAttribute(
"href",
"/#pricing",
);
expect(screen.getByRole("link", { name: /contact the team/i })).toHaveAttribute("href", "/contact");
expect(document.title).toBe("Help Center | QuickFork");
expect(document.querySelector('link[rel="canonical"]')).toHaveAttribute("href", "https://seekersai.com/help");
Expand Down Expand Up @@ -1617,7 +1707,8 @@ describe("App", () => {
it("shows auth state controls in the top navigation", () => {
render(<App />);

expect(screen.getByRole("link", { name: /sign in/i })).toHaveAttribute("href", "/sign-in");
expect(screen.getByRole("link", { name: /sign up/i })).toHaveAttribute("href", "/sign-up");
const banner = screen.getByRole("banner");
expect(within(banner).getByRole("link", { name: /sign in/i })).toHaveAttribute("href", "/sign-in");
expect(within(banner).getByRole("link", { name: /sign up/i })).toHaveAttribute("href", "/sign-up");
});
});
205 changes: 171 additions & 34 deletions src/components/landing/LandingNav.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,152 @@
import { ChevronDown, Layers3, PanelTop, Sparkles } from "lucide-react";
import { BookOpen, ChevronDown, FileText, Layers3, PanelTop, Route, Search, Sparkles, Target } from "lucide-react";
import { UserMenu } from "../auth/UserMenu";

const productMenuItems = [
const navMenus = [
{
label: "Product",
href: "#studio",
icon: PanelTop,
title: "Studio",
description: "Generate the QuickFork launch package",
ariaLabel: "Product, open QuickFork product studio",
menuLabel: "QuickFork product menu",
items: [
{
href: "#studio",
icon: PanelTop,
title: "Studio",
description: "Generate the QuickFork launch package",
},
{
href: "/product/github-repo-to-launch-package",
icon: Route,
title: "Repo to launch package",
description: "Source-backed story, copy, and visuals",
},
{
href: "/product/source-backed-launch-assets",
icon: Target,
title: "Source-backed launch assets",
description: "Keep generated claims reviewable",
},
{
href: "/product/cold-start-launch-materials",
icon: Sparkles,
title: "Cold-start launch materials",
description: "README, social, deck, and outreach drafts",
},
{
href: "/product/github-repo-launch-materials-map",
icon: Layers3,
title: "Launch materials map",
description: "Plan every launch artifact by evidence",
},
{
href: "/product/repository-launch-package-pilot",
icon: FileText,
title: "Launch package pilot",
description: "Request a fuller founder-led package",
},
],
},
{
href: "#how-to",
icon: Layers3,
title: "Launch Flow",
description: "From GitHub repo to output package",
label: "Use Cases",
href: "/use-cases/open-source-launch",
ariaLabel: "Use Cases, browse QuickFork launch use cases",
menuLabel: "QuickFork use cases menu",
items: [
{
href: "/use-cases/open-source-launch",
icon: BookOpen,
title: "Open-source launch",
description: "Package a public repository for launch",
},
{
href: "/use-cases/ai-project-launch",
icon: Sparkles,
title: "AI project launch",
description: "Explain AI repos for builders and users",
},
{
href: "/use-cases/devrel-launch-workflow",
icon: Route,
title: "DevRel launch workflow",
description: "Repeat launch prep across many projects",
},
],
},
{
href: "#features",
icon: Sparkles,
title: "Prompt System",
description: "Copy, layout, and visual prompt planning",
label: "Resources",
href: "/resources/open-source-launch-checklist",
ariaLabel: "Resources, browse QuickFork launch resources",
menuLabel: "QuickFork resources menu",
items: [
{
href: "/resources/open-source-launch-checklist",
icon: FileText,
title: "Open-source launch checklist",
description: "Review launch basics before publishing",
},
{
href: "/resources/github-project-marketing-card-guide",
icon: BookOpen,
title: "Marketing card guide",
description: "Turn a repo into a visual card",
},
{
href: "/resources/github-repo-launch-demand-map",
icon: Search,
title: "Launch demand map",
description: "Prioritize launch pages and assets",
},
{
href: "/resources/readme-cover-prompt-guide",
icon: Sparkles,
title: "README cover prompt guide",
description: "Prompt safer README launch visuals",
},
{
href: "/tools/github-repo-launch-readiness-score",
icon: Target,
title: "Launch readiness score",
description: "Score what the repo needs next",
},
{
href: "/templates/github-launch-announcement",
icon: FileText,
title: "Launch announcement template",
description: "Draft a launch post from source evidence",
},
],
},
{
label: "Examples",
href: "/examples/qwenlm-flashqla-launch-card",
ariaLabel: "Examples, browse QuickFork examples and comparisons",
menuLabel: "QuickFork examples menu",
items: [
{
href: "/examples/qwenlm-flashqla-launch-card",
icon: PanelTop,
title: "QwenLM FlashQLA launch card",
description: "A source-backed launch example",
},
{
href: "/examples/deepseek-twvp-launch-card",
icon: PanelTop,
title: "DeepSeek TWVP launch card",
description: "A visual primitive project example",
},
{
href: "/compare/chatgpt-open-source-launch-copy",
icon: Search,
title: "ChatGPT comparison",
description: "Compare generic chat to repo evidence",
},
{
href: "/compare/canva-readme-banner-generator",
icon: Search,
title: "Canva comparison",
description: "Compare visual tools to source-backed assets",
},
],
},
];

Expand All @@ -35,32 +163,37 @@ export function LandingNav() {
<span>QuickFork</span>
</a>
<nav className="navLinks" aria-label="Primary product navigation">
<div className="productNavItem">
<a className="navLink productTrigger" href={studioHref} aria-label="Product, open QuickFork product studio">
Product
<ChevronDown className="productChevron" size={17} aria-hidden="true" />
</a>
<div className="productMenu" aria-label="QuickFork product menu">
{productMenuItems.map((item) => {
const Icon = item.icon;
{navMenus.map((menu) => (
<div className="productNavItem" key={menu.label}>
<a className="navLink productTrigger" href={getNavHref(menu.href)} aria-label={menu.ariaLabel}>
{menu.label}
<ChevronDown className="productChevron" size={17} aria-hidden="true" />
</a>
<div className="productMenu" aria-label={menu.menuLabel}>
{menu.items.map((item) => {
const Icon = item.icon;

return (
<a className="productMenuItem" href={getLandingAnchorHref(item.href)} key={item.href}>
<span className="productMenuIcon" aria-hidden="true">
<Icon size={20} />
</span>
<span>
<strong>{item.title}</strong>
<small>{item.description}</small>
</span>
</a>
);
})}
return (
<a className="productMenuItem" href={getNavHref(item.href)} key={item.href}>
<span className="productMenuIcon" aria-hidden="true">
<Icon size={20} />
</span>
<span>
<strong>{item.title}</strong>
<small>{item.description}</small>
</span>
</a>
);
})}
</div>
</div>
</div>
))}
<a className="navLink pricingLink" href={getLandingAnchorHref("#pricing")} aria-label="Pricing, view subscription options">
Pricing
</a>
<a className="navLink navBriefLink" href={studioHref} aria-label="Generate free repo brief">
Generate free repo brief
</a>
</nav>
<div className="navActions">
<UserMenu />
Expand All @@ -73,3 +206,7 @@ export function LandingNav() {
function getLandingAnchorHref(hash: string) {
return window.location.pathname === "/" ? hash : `/${hash}`;
}

function getNavHref(href: string) {
return href.startsWith("#") ? getLandingAnchorHref(href) : href;
}
Loading
Loading