Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .github/workflows/stack127-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:
cache: npm
- run: npm ci
- run: npm run test:core
- name: Check ad-network data and report behavior
run: npm run test:focused -- tests/pages/ad-networks/*.test.mjs
- name: Check page publishing and recovery
run: npm run test:focused -- tests/stack127/page-publishing.test.mjs tests/stack127/page-publishing-database.test.mjs tests/stack127/frontend-content-queue.test.mjs tests/stack127/frontend-static.test.mjs tests/stack127/cache-process-hosting.test.mjs

Expand Down
2 changes: 2 additions & 0 deletions app/(site)/(components-ui)/components-ui/[section]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { notFound } from "next/navigation";
import { ActionsAndFormsExamples } from "../examples/actions-and-forms";
import { CardsExamples } from "../examples/cards";
import { ContentExamples } from "../examples/content";
import { DataVisualsExamples } from "../examples/data-visuals";
import { FeedbackAndDialogsExamples } from "../examples/feedback-and-dialogs";
import { FileUploadsExamples } from "../examples/file-uploads";
import { FiltersAndSortingExamples } from "../examples/filters-and-sorting";
Expand All @@ -26,6 +27,7 @@ const examples: Record<string, ComponentType> = {
"filters-and-sorting": FiltersAndSortingExamples,
results: ResultsExamples,
tables: TablesExamples,
"data-visuals": DataVisualsExamples,
cards: CardsExamples,
content: ContentExamples,
prose: ProseExamples,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"use client";

import { useState } from "react";
import type { AdNetworkSitesResponse } from "@/lib/ad-networks-types";
import { SitesTable } from "@/app/ui/ad-networks/sites-table";
import { TableToolbar, ToolbarSearch, ToolbarSelect, ToolbarSwitch } from "@/app/ui/table-toolbar";

// Working demos for the gallery. The sites table's first page is sample data; searching or
// paging asks the real development API.

export function ToolbarDemo() {
const [hero, setHero] = useState("");
const [query, setQuery] = useState("");
const [sort, setSort] = useState("sites");
const [niche, setNiche] = useState("");
const [order, setOrder] = useState("used");
return (
<div style={{ display: "grid", gap: 24 }}>
<div style={{ maxWidth: 760 }}>
<ToolbarSearch label="Search ad networks, sites, and niches" onChange={setHero} placeholder="Network, site, or niche" size="large" value={hero} />
</div>
<TableToolbar label="Search and sort the example list">
<ToolbarSearch label="Search sites" onChange={setQuery} placeholder="Search sites" value={query} />
<ToolbarSelect label="Niche" onChange={setNiche} options={[{ value: "", label: "All" }, { value: "food", label: "Food" }, { value: "travel", label: "Travel" }, { value: "gaming", label: "Gaming" }]} value={niche} />
<ToolbarSelect label="Sort" onChange={setSort} options={[{ value: "sites", label: "Most sites" }, { value: "join", label: "Easiest to join" }, { value: "niche", label: "By niche" }]} value={sort} />
</TableToolbar>
<ToolbarSwitch label="Order" onChange={setOrder} options={[{ value: "used", label: "Most used" }, { value: "join", label: "Easiest to join" }]} value={order} />
</div>
);
}

const sample: AdNetworkSitesResponse = {
page: 1,
pageSize: 30,
total: 3,
totalPages: 1,
effectiveSort: "traffic",
availableColumns: ["domain", "niche", "traffic", "domain_age", "platform", "manager", "checked", "publisher"],
availableSorts: ["traffic", "oldest", "newest"],
availableFilters: ["niche"],
filters: { niches: [], networks: [] },
rows: [
{ domain: "tinykitchenlab.com", publisher_name: "Tiny Kitchen Lab LLC", niche: "food", traffic_group: "top-10k", domain_created_on: "2014-03-02", platform: "WordPress", managed_by: { slug: "mediavine", name: "Mediavine" }, manager_domain: "mediavine.com", last_checked_at: "2026-10-12T08:00:00Z", favicon: null, networks: [{ slug: "mediavine", name: "Mediavine" }] },
{ domain: "wanderwithmara.com", publisher_name: null, niche: "travel", traffic_group: "top-100k", domain_created_on: "2016-07-21", platform: "WordPress", managed_by: { slug: "mediavine", name: "Mediavine" }, manager_domain: "mediavine.com", last_checked_at: "2026-10-11T08:00:00Z", favicon: null, networks: [{ slug: "mediavine", name: "Mediavine" }] },
{ domain: "budgetpantry.net", publisher_name: "Pantry Press Ltd", niche: "food", traffic_group: "top-1m", domain_created_on: "2012-01-10", platform: "Next.js", managed_by: null, manager_domain: null, last_checked_at: "2026-10-10T08:00:00Z", favicon: null, networks: [{ slug: "mediavine", name: "Mediavine" }] },
],
};

export function SitesTableDemo() {
return (
<SitesTable
columns={["niche", "traffic", "age", "platform", "manager", "checked"]}
defaultSort="traffic"
heading="Sites using Mediavine"
headingId="sites-demo"
initial={sample}
nicheFilter
route="/components-ui/tables"
scope={{ network: "mediavine" }}
sorts={["traffic", "oldest", "newest"]}
/>
);
}
33 changes: 33 additions & 0 deletions app/(site)/(components-ui)/components-ui/examples/cards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ToolCard } from "@/app/ui/cards/tool-card";
import { DirectoryAppCard } from "@/app/ui/directories/directory-app-card";
import { HardwareFactCardContent, hardwareFactCardClassName } from "@/app/ui/directories/hardware-fact-card";
import type { DirectoryAppCardData } from "@/lib/apps-card";
import { NetworkCard, NetworkGrid, SortNote } from "@/app/ui/ad-networks/network-card";
import { NetworkLogo } from "@/app/ui/ad-networks/network-logo";
import { Example } from "../gallery";
import styles from "../components-ui.module.css";

Expand Down Expand Up @@ -78,6 +80,37 @@ export function CardsExamples() {
</Link>
</div>
</Example>
<Example
components={["NetworkLogo", "networkLogo"]}
note="An ad network's square icon on a white tile, so any icon reads in both themes. card is the 32px tile for cards and table rows; title sits in an h1 in place of the title icon. Without a logo file the tile shows the name's first letter. networkLogo(slug) finds public/ad-networks/logos/<slug>.png on the server."
source="app/ui/ad-networks/network-logo.tsx, app/ui/ad-networks/network-logo-src.ts"
title="Network logo"
>
<div style={{ alignItems: "center", display: "flex", flexWrap: "wrap", gap: 16 }}>
<NetworkLogo logo={{ src: "/ad-networks/logos/mediavine.png" }} name="Mediavine" />
<NetworkLogo logo={{ src: "/ad-networks/logos/raptive.png" }} name="Raptive" />
<NetworkLogo logo={{ src: "/ad-networks/logos/newor-media.png" }} name="Newor Media" />
<NetworkLogo logo={null} name="Sparteo" />
<span style={{ font: "var(--weight-bold) var(--text-h1) / var(--line-h1) var(--font-display)", letterSpacing: "var(--tracking-display)" }}>
<NetworkLogo logo={{ src: "/ad-networks/logos/mediavine.png" }} name="Mediavine" size="title" />Mediavine
</span>
</div>
</Example>
<Example
components={["NetworkCard", "NetworkGrid", "SortNote"]}
note="One ad network in the directory: logo, name, the confirmed-share ring, the site count, and what it takes to join. The whole card links to the network. Hover or focus the ring for its bubble; on touch screens a tap opens it. Leave join out to hide the footer. The grid goes four, three, two, then one across."
source="app/ui/ad-networks/network-card.tsx, app/ui/ad-networks/confirmed-ring.tsx"
title="Network card"
>
<SortNote>Sorted by how many <b>Food</b> sites use each network.</SortNote>
<NetworkGrid>
<NetworkCard confirmed={7492} href="/components-ui/cards" join="No traffic minimum" logo={{ src: "/ad-networks/logos/ezoic.png" }} name="Ezoic" sites={8144} />
<NetworkCard confirmed={7459} href="/components-ui/cards" join="50,000 sessions a month" logo={{ src: "/ad-networks/logos/mediavine.png" }} name="Mediavine" sites={7852} />
<NetworkCard confirmed={6437} href="/components-ui/cards" join="100,000 pageviews a month" logo={{ src: "/ad-networks/logos/raptive.png" }} name="Raptive" sites={7152} />
<NetworkCard confirmed={6119} href="/components-ui/cards" join="1,000 sessions a month" logo={{ src: "/ad-networks/logos/journey-by-mediavine.png" }} name="Journey by Mediavine" sites={6953} />
<NetworkCard confirmed={1} href="/components-ui/cards" logo={null} name="Publir" sites={1} />
</NetworkGrid>
</Example>
</>
);
}
Loading
Loading