9e45780ba0
First commit of the Next.js community site that powers deepseek-tui.com, deployed via Cloudflare Workers / OpenNext. This commit lands the scaffold and applies the visual + correctness pass requested by community feedback: - Palette: drop the cream/Anthropic-feel paper (#F4F1E8) for a DeepSeek-aligned cool white + soft gray (#FFFFFF / #F4F6FB), with indigo accents kept. Soften default hairlines so a pure-white background reads clean instead of harsh. - Mobile: add a hamburger menu (mobile-menu.tsx) so phones can reach Install / Docs / Activity / Roadmap / Contribute — previously the link list was hidden on phones with no replacement. Tighter hero, flexible button row, viewport-safe code blocks, columnar grids collapse cleanly under 768px, and the printed-almanac center rule is desktop-only now (it sliced through narrow viewports). - "How it works" diagram: replace the hand-rolled ASCII art (which misaligned under CJK monospace because Han characters take 2 columns vs Latin's 1, per dhh's note in WeChat) with a real mermaid diagram rendered client-side via dynamic import. Uses the mermaid.live standard syntax 庄表伟 recommended. - Issue #1104: the docs listed a `deepseek-cn` provider that the v0.8.16 binary doesn't accept (`ProviderArg` in crates/cli only has 9 variants; the 10th lives only in the legacy tui/config.rs). derive-facts.mjs now omits `deepseek-cn` until that variant is wired through the shared ProviderKind, and the install page's China-network recipe uses `base_url` / `DEEPSEEK_BASE_URL` (which actually works on v0.8.16) instead of the unsupported provider. Auto-deploys via .github/workflows/deploy-web.yml on push to main. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import { useRouter, usePathname } from "next/navigation";
|
|
import { locales, type Locale } from "@/lib/i18n/config";
|
|
|
|
const LABELS: Record<Locale, string> = { en: "EN", zh: "中文" };
|
|
|
|
export function LocaleSwitcher({ current }: { current: string }) {
|
|
const router = useRouter();
|
|
const pathname = usePathname();
|
|
|
|
const switchTo = current === "zh" ? "en" : "zh";
|
|
const other = LABELS[switchTo as Locale];
|
|
|
|
const handleClick = () => {
|
|
// Replace locale segment in path
|
|
const segments = pathname.split("/");
|
|
if (locales.includes(segments[1] as Locale)) {
|
|
segments[1] = switchTo;
|
|
} else {
|
|
segments.splice(1, 0, switchTo);
|
|
}
|
|
const newPath = segments.join("/") || `/${switchTo}`;
|
|
document.cookie = `NEXT_LOCALE=${switchTo};path=/;max-age=${60 * 60 * 24 * 365}`;
|
|
router.push(newPath);
|
|
};
|
|
|
|
return (
|
|
<button
|
|
onClick={handleClick}
|
|
className="inline-flex items-center gap-1.5 px-2.5 py-1 hairline-t hairline-b hairline-l hairline-r font-mono text-[0.7rem] uppercase tracking-wider hover:bg-paper-deep transition-colors"
|
|
title={current === "zh" ? "Switch to English" : "切换到中文"}
|
|
>
|
|
<span className="font-cjk normal-case tracking-normal">{other}</span>
|
|
</button>
|
|
);
|
|
}
|