From b620972bce05aa714e2ffa56cd24241e39d5a586 Mon Sep 17 00:00:00 2001 From: Georgy Butaev <41178744+g-but@users.noreply.github.com> Date: Wed, 22 Jul 2026 11:36:41 +0200 Subject: [PATCH] =?UTF-8?q?feat(changelog):=20public=20/changelog=20?= =?UTF-8?q?=E2=80=94=20what=20shipped,=20in=20the=20open?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A clean, x.ai-style public changelog (no login required): a curated, chronological record of what actually shipped to production, styled as a quiet timeline. Content SSOT in src/config/changelog.ts; entries seeded from real shipped history (discovery/search, two-sided market, Supporter checkout, P2P loans, Login-with-OrangeCat, self-host, …). Wired a CHANGELOG route + a footer link so it's discoverable. Co-Authored-By: Claude Opus 4.8 --- src/app/(public)/changelog/page.tsx | 107 ++++++++++++++++++++++++ src/config/changelog.ts | 122 ++++++++++++++++++++++++++++ src/config/navigation.ts | 1 + src/config/routes.ts | 1 + 4 files changed, 231 insertions(+) create mode 100644 src/app/(public)/changelog/page.tsx create mode 100644 src/config/changelog.ts diff --git a/src/app/(public)/changelog/page.tsx b/src/app/(public)/changelog/page.tsx new file mode 100644 index 000000000..6a2558806 --- /dev/null +++ b/src/app/(public)/changelog/page.tsx @@ -0,0 +1,107 @@ +import React from 'react'; +import { PageHeading } from '@/components/layout/PageHeading'; +import { CHANGELOG, CHANGELOG_TAGS, type ChangelogTag } from '@/config/changelog'; + +export const metadata = { + title: 'Changelog', + description: + 'What’s new on OrangeCat — every update that shipped, newest first. Bitcoin-native funding, discovery, and the sovereign personal economy, in the open.', +}; + +const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; + +/** Format 'YYYY-MM-DD' → 'Jul 22, 2026' deterministically (no TZ / hydration drift). */ +function formatDate(iso: string): string { + const [y, m, d] = iso.split('-').map(Number); + return `${MONTHS[(m ?? 1) - 1]} ${d}, ${y}`; +} + +// Warm accent for the notable tags (new features, platform), monochrome for the rest. +const TAG_CHIP: Record = { + feature: 'border-accent-warm text-accent-warm', + platform: 'border-accent-warm text-accent-warm', + improvement: 'border-default text-fg-secondary', + fix: 'border-default text-fg-tertiary', +}; +const TAG_DOT: Record = { + feature: 'bg-accent-warm', + platform: 'bg-accent-warm', + improvement: 'bg-strong', + fix: 'bg-strong', +}; + +/** + * /changelog — public product changelog (no login required). A curated, + * chronological record of what shipped, styled as a quiet timeline: date + + * tag on the left rail, the human-readable change on the right. Content SSOT + * lives in `src/config/changelog.ts`. + */ +export default function ChangelogPage() { + return ( +
+
+ {/* Hero */} +
+ Changelog +

+ What’s new on OrangeCat — building the Bitcoin-native personal economy in the open. + Newest first. +

+
+ + {/* Timeline */} +
    + {CHANGELOG.map((entry, i) => ( +
  1. + {/* Dot on the rail */} + + +
    + + + {CHANGELOG_TAGS[entry.tag].label} + +
    + +

    {entry.title}

    +

    {entry.summary}

    + + {entry.items && entry.items.length > 0 && ( +
      + {entry.items.map((item, j) => ( +
    • + + {item} +
    • + ))} +
    + )} +
  2. + ))} +
+ + {/* Foot note */} +

+ Everything here shipped to production. Follow along —{' '} + + explore what people are building + + . +

+
+
+ ); +} diff --git a/src/config/changelog.ts b/src/config/changelog.ts new file mode 100644 index 000000000..55cdfac6f --- /dev/null +++ b/src/config/changelog.ts @@ -0,0 +1,122 @@ +/** + * Public product changelog — SSOT. + * + * A curated, human-readable record of what shipped, newest first. Rendered at + * the public `/changelog` route (no login required). Keep entries user-facing: + * describe the change from the reader's side, not the commit. Every entry here + * corresponds to work that actually shipped to production. + */ + +export type ChangelogTag = 'feature' | 'improvement' | 'fix' | 'platform'; + +export interface ChangelogEntry { + /** ISO date the change shipped (YYYY-MM-DD). */ + date: string; + tag: ChangelogTag; + title: string; + summary: string; + /** Optional detail bullets. */ + items?: string[]; +} + +/** Display metadata for each tag (label + which token drives its chip). */ +export const CHANGELOG_TAGS: Record = { + feature: { label: 'New' }, + improvement: { label: 'Improved' }, + fix: { label: 'Fixed' }, + platform: { label: 'Platform' }, +}; + +/** Newest first. */ +export const CHANGELOG: ChangelogEntry[] = [ + { + date: '2026-07-22', + tag: 'feature', + title: 'Discover, sharper and searchable', + summary: + 'Find what matters by meaning, not just keywords — and let search engines find it too.', + items: [ + 'Public semantic search across the economy: projects, people, and offers, matched by intent.', + 'Discover now server-renders a crawlable content strip, so published work is indexable and shareable.', + ], + }, + { + date: '2026-07-21', + tag: 'feature', + title: 'A two-sided market', + summary: + 'The platform now indexes what people want, not only what they offer — and introduces the two sides.', + items: [ + 'A public open-demand feed: browse what the community is looking for.', + 'Two-sided introductions surface matches between demand and supply.', + ], + }, + { + date: '2026-07-21', + tag: 'feature', + title: 'Support in Bitcoin', + summary: + 'A Bitcoin-native Supporter checkout — back the platform directly, settled on Lightning or on-chain.', + }, + { + date: '2026-07-19', + tag: 'platform', + title: 'Wired to FleetCrown', + summary: 'OrangeCat is the economic layer for FleetCrown — and now the wiring runs both ways.', + items: [ + 'Settled funding on a project or cause signals the FleetCrown fleet automatically.', + 'Embedded the FleetCrown feedback widget — OrangeCat runs as its own second customer.', + ], + }, + { + date: '2026-07-14', + tag: 'improvement', + title: 'Cat Credits go-live plumbing + steadier sessions', + summary: + 'Groundwork for paid Cat Credits, and a fix so auth-gated pages resolve instead of spinning.', + items: [ + 'Cat Credits go-live is now environment-driven, with a wallet-verification step.', + 'Closed a hydration gap that could pin logged-in pages on a loading spinner.', + ], + }, + { + date: '2026-07-13', + tag: 'feature', + title: 'Cat-first, and payable on publish', + summary: + 'Your Cat is the front door, and publishing something payable is a guided, one-link step.', + items: [ + 'The dashboard routes everyone to the Cat hub.', + 'Publishing a payable entity nudges you to connect a wallet and hands you a payable public link.', + 'Hardened a public-profile data-exposure path.', + ], + }, + { + date: '2026-07-09', + tag: 'feature', + title: 'Peer-to-peer Bitcoin loans', + summary: + 'Lend and borrow directly: offers, obligations, and payment handoffs — no bank in the middle.', + }, + { + date: '2026-07-08', + tag: 'improvement', + title: 'Funding transparency you control', + summary: + 'Per-entity controls over how much of your funding picture is public — transparency by choice.', + }, + { + date: '2026-06-17', + tag: 'platform', + title: 'Log in with OrangeCat', + summary: + 'OrangeCat became an OpenID Connect provider — one identity you can carry across the ecosystem.', + }, + { + date: '2026-06-12', + tag: 'platform', + title: 'Self-hosted and sovereign', + summary: + 'Moved to fully self-hosted infrastructure — the platform runs on hardware we control.', + }, +]; diff --git a/src/config/navigation.ts b/src/config/navigation.ts index b0609f1a5..25a71ca52 100644 --- a/src/config/navigation.ts +++ b/src/config/navigation.ts @@ -296,6 +296,7 @@ export const footerNavigation = { product: [ { name: 'Documentation', href: ROUTES.DOCS }, { name: 'How It Works', href: ROUTES.HOW_IT_WORKS }, + { name: 'Changelog', href: ROUTES.CHANGELOG }, { name: 'Status', href: ROUTES.STATUS }, ], company: [ diff --git a/src/config/routes.ts b/src/config/routes.ts index e634128a7..4183dbdb2 100644 --- a/src/config/routes.ts +++ b/src/config/routes.ts @@ -280,6 +280,7 @@ export const ROUTES = { ABOUT: '/about', HOW_IT_WORKS: '/how-it-works', BLOG: '/blog', + CHANGELOG: '/changelog', DOCS: '/docs', FAQ: '/faq', PRICING: '/pricing',