website: add /cloud design partners page and shared shell
- New /cloud page with signup form (email, name, company, role, message) posting to a Discord webhook via a TanStack Start server function on the Cloudflare Worker. Webhook URL read from DISCORD_WEBHOOK_URL secret. - Extract SiteShell, SiteFooter, FAQItem from landing-page. - Migrate /privacy, /download, /blog, /changelog, /cloud to SiteShell so they share header + footer with consistent width. - Add /cloud to header and footer nav. - Make /docs sidebar full-width; bump footer text from xs to sm. - Add Cloudflare Workers types and ignore .dev.vars.
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
export function FAQItem({ question, children }: { question: string; children: ReactNode }) {
|
||||
return (
|
||||
<details className="group">
|
||||
<summary className="font-medium text-sm cursor-pointer list-none flex items-start gap-2 -ml-4">
|
||||
<span className="font-mono text-white/40 flex-shrink-0 group-open:hidden">+</span>
|
||||
<span className="font-mono text-white/40 flex-shrink-0 hidden group-open:inline">−</span>
|
||||
{question}
|
||||
</summary>
|
||||
<div className="text-sm text-muted-foreground space-y-2 mt-2 prose">{children}</div>
|
||||
</details>
|
||||
);
|
||||
}
|
||||
@@ -48,6 +48,8 @@ import { useRelease } from "~/routes/__root";
|
||||
import { Mic } from "lucide-react";
|
||||
import { HeroMockup } from "~/components/hero-mockup";
|
||||
import { ClaudeIcon } from "~/components/mockup";
|
||||
import { FAQItem } from "~/components/faq-item";
|
||||
import { SiteFooter } from "~/components/site-footer";
|
||||
import { SiteHeader } from "~/components/site-header";
|
||||
import "~/styles.css";
|
||||
|
||||
@@ -97,126 +99,7 @@ export function LandingPage({ title, subtitle }: LandingPageProps) {
|
||||
<SponsorCTA />
|
||||
</div>
|
||||
</main>
|
||||
<footer className="p-6 md:p-20 md:pt-0 max-w-5xl mx-auto">
|
||||
<div className="border-t border-white/10 pt-8 pb-4 grid grid-cols-2 sm:grid-cols-4 gap-8 text-xs">
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Product</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href="/blog"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Blog
|
||||
</a>
|
||||
<a
|
||||
href="/docs"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Docs
|
||||
</a>
|
||||
<a
|
||||
href="/changelog"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Changelog
|
||||
</a>
|
||||
<a
|
||||
href="/docs/cli"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
CLI
|
||||
</a>
|
||||
<a
|
||||
href="/privacy"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Agents</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href="/claude-code"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Claude Code
|
||||
</a>
|
||||
<a
|
||||
href="/codex"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Codex
|
||||
</a>
|
||||
<a
|
||||
href="/opencode"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
OpenCode
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Community</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href="https://discord.gg/jz8T2uahpH"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/getpaseo/paseo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Download</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href={appStoreUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
App Store
|
||||
</a>
|
||||
<a
|
||||
href={playStoreUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Google Play
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/getpaseo/paseo/releases"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Desktop
|
||||
</a>
|
||||
<a
|
||||
href={webAppUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Web App
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<SiteFooter />
|
||||
</div>
|
||||
</CursorFieldProvider>
|
||||
);
|
||||
@@ -1685,16 +1568,3 @@ function SponsorCTA() {
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
function FAQItem({ question, children }: { question: string; children: React.ReactNode }) {
|
||||
return (
|
||||
<details className="group">
|
||||
<summary className="font-medium text-sm cursor-pointer list-none flex items-start gap-2 -ml-4">
|
||||
<span className="font-mono text-white/40 flex-shrink-0 group-open:hidden">+</span>
|
||||
<span className="font-mono text-white/40 flex-shrink-0 hidden group-open:inline">−</span>
|
||||
{question}
|
||||
</summary>
|
||||
<div className="text-sm text-muted-foreground space-y-2 mt-2 prose">{children}</div>
|
||||
</details>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { appStoreUrl, playStoreUrl, webAppUrl } from "~/downloads";
|
||||
|
||||
interface SiteFooterProps {
|
||||
width?: "default" | "prose";
|
||||
}
|
||||
|
||||
export function SiteFooter({ width = "default" }: SiteFooterProps) {
|
||||
const widthClasses =
|
||||
width === "prose" ? "max-w-prose p-6 md:p-12 md:pt-0" : "max-w-5xl p-6 md:p-20 md:pt-0";
|
||||
return (
|
||||
<footer className={`${widthClasses} mx-auto`}>
|
||||
<div className="border-t border-white/10 pt-8 pb-4 grid grid-cols-2 sm:grid-cols-4 gap-8 text-sm">
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Product</p>
|
||||
<div className="space-y-2">
|
||||
<a href="/blog" className="block text-white/40 hover:text-white/60 transition-colors">
|
||||
Blog
|
||||
</a>
|
||||
<a href="/docs" className="block text-white/40 hover:text-white/60 transition-colors">
|
||||
Docs
|
||||
</a>
|
||||
<a
|
||||
href="/changelog"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Changelog
|
||||
</a>
|
||||
<a href="/cloud" className="block text-white/40 hover:text-white/60 transition-colors">
|
||||
Cloud
|
||||
</a>
|
||||
<a
|
||||
href="/docs/cli"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
CLI
|
||||
</a>
|
||||
<a
|
||||
href="/privacy"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Privacy
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Agents</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href="/claude-code"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Claude Code
|
||||
</a>
|
||||
<a href="/codex" className="block text-white/40 hover:text-white/60 transition-colors">
|
||||
Codex
|
||||
</a>
|
||||
<a
|
||||
href="/opencode"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
OpenCode
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Community</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href="https://discord.gg/jz8T2uahpH"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Discord
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/getpaseo/paseo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<p className="text-white/60 font-medium">Download</p>
|
||||
<div className="space-y-2">
|
||||
<a
|
||||
href={appStoreUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
App Store
|
||||
</a>
|
||||
<a
|
||||
href={playStoreUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Google Play
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/getpaseo/paseo/releases"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Desktop
|
||||
</a>
|
||||
<a
|
||||
href={webAppUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block text-white/40 hover:text-white/60 transition-colors"
|
||||
>
|
||||
Web App
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -28,6 +28,12 @@ export function SiteHeader() {
|
||||
>
|
||||
Changelog
|
||||
</a>
|
||||
<a
|
||||
href="/cloud"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
>
|
||||
Cloud
|
||||
</a>
|
||||
<a
|
||||
href="/download"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { SiteFooter } from "~/components/site-footer";
|
||||
import { SiteHeader } from "~/components/site-header";
|
||||
|
||||
interface SiteShellProps {
|
||||
children: ReactNode;
|
||||
width?: "default" | "prose";
|
||||
}
|
||||
|
||||
export function SiteShell({ children, width = "default" }: SiteShellProps) {
|
||||
const mainClasses =
|
||||
width === "prose" ? "max-w-prose p-6 md:p-12 mx-auto" : "max-w-5xl p-6 md:p-20 mx-auto";
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<main className={mainClasses}>
|
||||
<div className="mb-12">
|
||||
<SiteHeader />
|
||||
</div>
|
||||
{children}
|
||||
</main>
|
||||
<SiteFooter width={width} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user