From 1ef37786b112a2647e754bb152bde28608b295a2 Mon Sep 17 00:00:00 2001 From: zhenyi <434836402@qq.com> Date: Sun, 31 May 2026 13:12:32 +0800 Subject: [PATCH] feat(landing): add landing page components --- src/components/landing/ambient-light.tsx | 8 + src/components/landing/badge.tsx | 18 ++ src/components/landing/dashboard-mockup.tsx | 127 +++++++++++++ src/components/landing/footer.tsx | 80 ++++++++ src/components/landing/header.tsx | 50 +++++ src/components/landing/section.tsx | 15 ++ src/components/landing/terminal-demo.tsx | 44 +++++ src/page/landing/features-grid.tsx | 55 ++++++ src/page/landing/features.tsx | 151 +++++++++++++++ src/page/landing/home.tsx | 190 +++++++++++++++++++ src/page/landing/layout.tsx | 36 ++++ src/page/landing/pricing.tsx | 193 ++++++++++++++++++++ src/page/landing/workflow.tsx | 109 +++++++++++ 13 files changed, 1076 insertions(+) create mode 100644 src/components/landing/ambient-light.tsx create mode 100644 src/components/landing/badge.tsx create mode 100644 src/components/landing/dashboard-mockup.tsx create mode 100644 src/components/landing/footer.tsx create mode 100644 src/components/landing/header.tsx create mode 100644 src/components/landing/section.tsx create mode 100644 src/components/landing/terminal-demo.tsx create mode 100644 src/page/landing/features-grid.tsx create mode 100644 src/page/landing/features.tsx create mode 100644 src/page/landing/home.tsx create mode 100644 src/page/landing/layout.tsx create mode 100644 src/page/landing/pricing.tsx create mode 100644 src/page/landing/workflow.tsx diff --git a/src/components/landing/ambient-light.tsx b/src/components/landing/ambient-light.tsx new file mode 100644 index 0000000..88ad5c9 --- /dev/null +++ b/src/components/landing/ambient-light.tsx @@ -0,0 +1,8 @@ +export default function AmbientLight() { + return ( +
+
+
+
+ ); +} diff --git a/src/components/landing/badge.tsx b/src/components/landing/badge.tsx new file mode 100644 index 0000000..a4d2aa5 --- /dev/null +++ b/src/components/landing/badge.tsx @@ -0,0 +1,18 @@ +import type { ReactNode } from "react"; + +type Props = { + icon?: ReactNode; + children: ReactNode; + className?: string; +}; + +export default function Badge({ icon, children, className = "" }: Props) { + return ( +
+ {icon} + {children} +
+ ); +} diff --git a/src/components/landing/dashboard-mockup.tsx b/src/components/landing/dashboard-mockup.tsx new file mode 100644 index 0000000..8b6c101 --- /dev/null +++ b/src/components/landing/dashboard-mockup.tsx @@ -0,0 +1,127 @@ +import type { ReactNode } from "react"; +import { Bot, Code2, GitBranch, GitCommitHorizontal, MessageSquare, Search } from "lucide-react"; + +export default function DashboardMockup() { + return ( +
+
+ {/* Workspace rail */} +
+
+ +
+
+ {['GD', 'AI', 'RS'].map((item, index) => ( +
+ {item} +
+ ))} +
+ + {/* Workspace sidebar */} +
+
+
+ +
+ GitDataAI +
+
+
Workplan
+
Channel
+
+
+ } label="Repositories" /> + } label="Pull requests" /> + } label="Workplan chat" /> +
+
+ + {/* Main content */} +
+
+ GitDataAI + / + core +
+ +
+
+ +
+
+
+
+ +
+
+
feat: implement AI auto-review
+
Alice committed 2 hours ago
+
+ + a1b2c3d + +
+ +
+ {[ + { name: "src/agent/review.rs", status: "+84", tone: "text-emerald-500" }, + { name: "src/api/handler.rs", status: "+27", tone: "text-emerald-500" }, + { name: "tests/ai_test.rs", status: "+16", tone: "text-primary" }, + ].map((file) => ( +
+ + {file.name} + {file.status} +
+ ))} +
+
+ +
+
+
+ +
+ AI Reviewer +
+

+ Review complete. Add a timeout to the API call before merging. +

+
+
+
+
+
+ ); +} + +function SidebarItem({ + active = false, + icon, + label, +}: { + active?: boolean; + icon: ReactNode; + label: string; +}) { + return ( +
+ {icon} + {label} +
+ ); +} diff --git a/src/components/landing/footer.tsx b/src/components/landing/footer.tsx new file mode 100644 index 0000000..936ee29 --- /dev/null +++ b/src/components/landing/footer.tsx @@ -0,0 +1,80 @@ +import { Link } from "react-router"; +import { Code2 } from "lucide-react"; + +export default function Footer() { + return ( +
+
+
+ {/* Brand */} +
+
+
+ +
+ + GitDataAI + +
+

+ The all-in-one developer platform — git hosting, real-time + collaboration, and AI agents. +

+
+ + {/* Product */} +
+

+ Product +

+
    + {[ + { label: "Features", href: "#features" }, + { label: "Workflow", href: "#workflow" }, + ].map((l) => ( +
  • + + {l.label} + +
  • + ))} +
+
+ + {/* Account */} +
+

+ Account +

+
    +
  • + + Sign in + +
  • +
  • + + Register + +
  • +
+
+
+ + {/* Bottom bar */} +
+ © {new Date().getFullYear()} GitDataAI. All rights reserved. +
+
+
+ ); +} diff --git a/src/components/landing/header.tsx b/src/components/landing/header.tsx new file mode 100644 index 0000000..ab3e476 --- /dev/null +++ b/src/components/landing/header.tsx @@ -0,0 +1,50 @@ +import { Link } from "react-router"; +import { Code2, ArrowRight } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +const navItems = [ + { label: "Features", to: "/features" }, + { label: "Workflow", to: "/workflow" }, + { label: "Pricing", to: "/pricing" }, +]; + +export default function Header() { + return ( +
+
+ +
+ +
+ + GitDataAI + + + + + +
+ + +
+
+
+ ); +} diff --git a/src/components/landing/section.tsx b/src/components/landing/section.tsx new file mode 100644 index 0000000..9af4aaa --- /dev/null +++ b/src/components/landing/section.tsx @@ -0,0 +1,15 @@ +export default function Section({ + children, + className = "", + id, +}: { + children: React.ReactNode; + className?: string; + id?: string; +}) { + return ( +
+
{children}
+
+ ); +} diff --git a/src/components/landing/terminal-demo.tsx b/src/components/landing/terminal-demo.tsx new file mode 100644 index 0000000..83f4cec --- /dev/null +++ b/src/components/landing/terminal-demo.tsx @@ -0,0 +1,44 @@ +import { Layers } from "lucide-react"; + +export default function TerminalDemo() { + return ( +
+ {/* title bar */} +
+
+
+
+ + Terminal + +
+ {/* body */} +
+

+ $ git clone{" "} + + https://gitdata.ai/acme/backend + +

+

+ $ git checkout -b{" "} + feature/payments +

+

+ $ git commit -m{" "} + + "feat: add Stripe integration" + +

+

+ $ git push origin + feature/payments +

+
+ + PR #128 created · AI review started · #backend notified +
+
+
+ ); +} diff --git a/src/page/landing/features-grid.tsx b/src/page/landing/features-grid.tsx new file mode 100644 index 0000000..ce3806c --- /dev/null +++ b/src/page/landing/features-grid.tsx @@ -0,0 +1,55 @@ +import { GitMerge, MessageSquare, Bot, Workflow, Shield, Terminal } from "lucide-react"; + +const items = [ + { + icon: , + title: "Git Repositories", + desc: "Full git hosting with branches, tags, pull requests, code review, and webhooks. HTTPS / SSH clone.", + }, + { + icon: , + title: "Real-time Channels", + desc: "Threads, reactions, file sharing, and article publishing. Voice channels for your team.", + }, + { + icon: , + title: "AI Agents", + desc: "Built-in AI for code review, issue triage, and task automation. Persistent memory & streaming.", + }, + { + icon: , + title: "Issue Tracking", + desc: "Create, assign, and track issues. Labels, milestones, board view, and pull request linking.", + }, + { + icon: , + title: "Enterprise Security", + desc: "TOTP 2FA, role-based access, audit logs, SSH keys, and private repositories.", + }, + { + icon: , + title: "Developer Experience", + desc: "REST + WebSocket APIs, OpenAPI spec, webhooks, and git-native CLI. By devs, for devs.", + }, +]; + +export default function FeaturesGrid() { + return ( +
+ {items.map((f) => ( +
+
+ {f.icon} +
+

{f.title}

+

+ {f.desc} +

+
+ ))} +
+ ); +} diff --git a/src/page/landing/features.tsx b/src/page/landing/features.tsx new file mode 100644 index 0000000..e12cec0 --- /dev/null +++ b/src/page/landing/features.tsx @@ -0,0 +1,151 @@ +import { Link } from "react-router"; +import { ArrowRight, Zap, GitCommitHorizontal, MessageSquare, Bot } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import FeaturesGrid from "./features-grid"; + +export default function FeaturesPage() { + return ( + <> +
+
+
+
+ + Platform +
+

+ Everything you need to ship +

+

+ One integrated platform — no stitching together a dozen tools. +

+
+ + +
+
+ + {/* Deep Dives */} +
+
+ + {/* Git */} +
+
+
+
+ + commit history +
+
+ {[1,2,3].map(i => ( +
+
+
+
+
+
+
+ ))} +
+
+
+
+
+ +
+

Enterprise-grade Git Hosting

+

+ Experience lightning-fast git operations. Branch, tag, and merge with confidence. Our architecture ensures your code is safe, accessible, and always available. +

+
    +
  • ✓ SSH and HTTPS cloning
  • +
  • ✓ Branch protection rules
  • +
  • ✓ Comprehensive audit logs
  • +
+
+
+ + {/* Chat */} +
+
+
+ +
+

Contextual Conversations

+

+ Real-time channels integrated directly into your workflow. Discuss code, share files, and resolve issues without context switching. +

+
    +
  • ✓ Threaded conversations
  • +
  • ✓ Link unfurling for PRs & Issues
  • +
  • ✓ Voice and screen sharing
  • +
+
+
+
+
+ + # engineering +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + {/* AI */} +
+
+
+
+ +
+
+
+
+
+
+ +
+

Intelligent Automation

+

+ Deploy autonomous agents that understand your codebase. Have them review PRs, triage issues, and answer questions. +

+
    +
  • ✓ Automated Code Review
  • +
  • ✓ Semantic Code Search
  • +
  • ✓ Smart Issue Triage
  • +
+
+
+ +
+ +
+

Ready to experience it?

+ +
+
+ + ); +} diff --git a/src/page/landing/home.tsx b/src/page/landing/home.tsx new file mode 100644 index 0000000..c60ff06 --- /dev/null +++ b/src/page/landing/home.tsx @@ -0,0 +1,190 @@ +import { Link } from "react-router"; +import { ArrowRight } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import FeaturesGrid from "./features-grid"; +import TerminalDemo from "@/components/landing/terminal-demo"; +import DashboardMockup from "@/components/landing/dashboard-mockup"; +import { GitBranch, Layers, MessageSquare, Bot } from "lucide-react"; + +export default function LandingHome() { + return ( + <> + {/* Hero */} +
+
+
+
+ + The all-in-one developer platform +
+ +

+ Build. Ship.{" "} + + With intelligence. + +

+ +

+ Git hosting, real-time collaboration, and AI agents — one platform + for modern dev teams who ship fast. +

+ +
+ + +
+ +

+ Free to start. No credit card required. +

+
+ + +
+
+
+ + {/* Product loop */} +
+
+ {[ + { label: "Git-native", value: "Repos, PRs, branches" }, + { label: "AI in context", value: "Review, triage, automate" }, + { label: "Team sync", value: "Channels tied to work" }, + ].map((item) => ( +
+
{item.label}
+
{item.value}
+
+ ))} +
+
+ + {/* Features overview */} +
+
+
+

+ Everything you need to ship +

+
+ +
+ +
+
+
+ + {/* Workflow + Terminal */} +
+
+
+
+
+ + Workflow +
+

+ Standard git, supercharged +

+

+ Same workflow you know. AI reviews every PR. Channels keep your + team in sync. Deploy with confidence. +

+
+ +
+
+ +
+
+
+ + {/* Product fit */} +
+
+
+

+ One workspace for code, agents, and discussion +

+

+ The interface mirrors the app itself: repository work on the left, + live context in channels, and AI assistance close to every task. +

+
+
+ {[ + { + icon: GitBranch, + title: "Trace work to code", + desc: "Repositories, issues, pull requests, and commits stay in the same workspace structure.", + }, + { + icon: MessageSquare, + title: "Discuss with context", + desc: "Channels keep team decisions next to the repositories and workplans they affect.", + }, + { + icon: Bot, + title: "Bring agents into flow", + desc: "AI review and automation live beside human collaboration instead of in a separate tool.", + }, + ].map((item) => ( +
+
+ +
+

{item.title}

+

{item.desc}

+
+ ))} +
+
+
+ + {/* Bottom CTA */} +
+
+
+
+

+ Ready to ship faster? +

+

+ Join teams using GitDataAI to build better software, together. +

+
+ + +
+
+
+
+ + ); +} diff --git a/src/page/landing/layout.tsx b/src/page/landing/layout.tsx new file mode 100644 index 0000000..a07a44f --- /dev/null +++ b/src/page/landing/layout.tsx @@ -0,0 +1,36 @@ +import { useEffect } from "react"; +import { Outlet, useNavigate } from "react-router"; +import { Loader2 } from "lucide-react"; +import { useAuth } from "@/context/auth-context"; +import AmbientLight from "@/components/landing/ambient-light"; +import Header from "@/components/landing/header"; +import Footer from "@/components/landing/footer"; + +export default function LandingLayout() { + const { isAuthenticated, isLoading } = useAuth(); + const navigate = useNavigate(); + + useEffect(() => { + if (!isLoading && isAuthenticated) navigate("/me", { replace: true }); + }, [isAuthenticated, isLoading, navigate]); + + if (isLoading) { + return ( +
+ +
+ ); + } + if (isAuthenticated) return null; + + return ( +
+ +
+
+ +
+
+
+ ); +} diff --git a/src/page/landing/pricing.tsx b/src/page/landing/pricing.tsx new file mode 100644 index 0000000..87b7d4e --- /dev/null +++ b/src/page/landing/pricing.tsx @@ -0,0 +1,193 @@ +import { Link } from "react-router"; +import { CheckCircle2, XCircle } from "lucide-react"; +import { Button } from "@/components/ui/button"; + +const plans = [ + { + name: "Free", + price: "$0", + period: "forever", + desc: "For individuals and small teams getting started.", + features: [ + "Unlimited public repositories", + "5 private repositories", + "Real-time channels", + "Community support", + "1 GB storage", + ], + cta: "Get started free", + href: "/auth/register", + primary: false, + }, + { + name: "Pro", + price: "$12", + period: "/ month", + desc: "For growing teams that need more power.", + features: [ + "Unlimited private repositories", + "AI code review agents", + "Voice channels", + "Priority support", + "50 GB storage", + "Advanced analytics", + ], + cta: "Start Pro trial", + href: "/auth/register", + primary: true, + }, + { + name: "Enterprise", + price: "Custom", + period: "", + desc: "For large organizations with custom needs.", + features: [ + "Everything in Pro", + "SSO & SAML", + "Audit logs", + "Dedicated support", + "Unlimited storage", + "Custom integrations", + "On-premise option", + ], + cta: "Contact sales", + href: "/auth/register", + primary: false, + }, +]; + +const compareFeatures = [ + { name: "Public Repositories", free: true, pro: true, ent: true }, + { name: "Private Repositories", free: "5", pro: "Unlimited", ent: "Unlimited" }, + { name: "Storage", free: "1 GB", pro: "50 GB", ent: "Unlimited" }, + { name: "Real-time Channels", free: true, pro: true, ent: true }, + { name: "Voice Channels", free: false, pro: true, ent: true }, + { name: "AI Code Review", free: false, pro: true, ent: true }, + { name: "Custom AI Agents", free: false, pro: "3 included", ent: "Unlimited" }, + { name: "SSO & SAML", free: false, pro: false, ent: true }, + { name: "Audit Logs", free: false, pro: false, ent: true }, + { name: "Support", free: "Community", pro: "Priority", ent: "Dedicated" }, +]; + +export default function PricingPage() { + return ( + <> +
+
+
+

+ Simple, transparent pricing +

+

+ Start for free. Upgrade when you need more. No hidden fees. +

+
+ +
+ {plans.map((p) => ( +
+ {p.primary && ( +
+ Most popular +
+ )} +

{p.name}

+
+ + {p.price} + + {p.period && ( + + {p.period} + + )} +
+

{p.desc}

+ +
    + {p.features.map((f) => ( +
  • + + {f} +
  • + ))} +
+ + +
+ ))} +
+
+
+ + {/* Feature Comparison */} +
+
+

Compare features

+
+ + + + + + + + + + + {compareFeatures.map((f, i) => ( + + + + + + + ))} + +
FeatureFreeProEnterprise
{f.name} + {typeof f.free === 'boolean' ? (f.free ? : ) : {f.free}} + + {typeof f.pro === 'boolean' ? (f.pro ? : ) : {f.pro}} + + {typeof f.ent === 'boolean' ? (f.ent ? : ) : {f.ent}} +
+
+
+
+ + {/* FAQ */} +
+
+

Frequently asked questions

+
+ {[ + { q: "Can I use GitDataAI for free?", a: "Yes, our Free plan gives you everything you need to get started, including unlimited public repos, 5 private repos, and core channel features." }, + { q: "How do AI agents work?", a: "AI agents are built into the platform. You can invite them to PRs for automatic code review, or @mention them in channels to answer questions based on your codebase context." }, + { q: "Do you offer an on-premise version?", a: "Yes, GitDataAI Enterprise can be deployed on your own infrastructure (AWS, GCP, Azure, or bare metal). Contact our sales team for details." } + ].map((faq, i) => ( +
+

{faq.q}

+

{faq.a}

+
+ ))} +
+
+
+ + ); +} diff --git a/src/page/landing/workflow.tsx b/src/page/landing/workflow.tsx new file mode 100644 index 0000000..c5f3684 --- /dev/null +++ b/src/page/landing/workflow.tsx @@ -0,0 +1,109 @@ +import { Link } from "react-router"; +import { ArrowRight, GitBranch, ArrowDown } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import TerminalDemo from "@/components/landing/terminal-demo"; + +const steps = [ + { + title: "1. Create a workspace", + desc: "Set up a workspace for your team and invite members. Public or private — you decide.", + }, + { + title: "2. Push code", + desc: "Clone repositories via SSH or HTTPS. Push branches, create tags. Standard git, nothing new to learn.", + }, + { + title: "3. Open pull requests", + desc: "Create PRs with descriptions and reviewers. AI agents automatically review code for common issues.", + }, + { + title: "4. Collaborate in channels", + desc: "Discuss PRs and issues in real-time channels. Threads keep conversations organized. Voice channels for live reviews.", + }, + { + title: "5. Ship with confidence", + desc: "Merge, tag releases, and deploy. Webhooks integrate with your CI/CD pipeline. Monitor everything.", + }, +]; + +export default function WorkflowPage() { + return ( + <> +
+
+
+
+ + Workflow +
+

+ From idea to production +

+

+ Five steps to ship your next feature. Same tools you know, better together. +

+
+ +
+ {/* Steps */} +
+ {steps.map((s, i) => ( +
+ + {i + 1} + +

+ {s.title} +

+

+ {s.desc} +

+
+ ))} +
+ + {/* Visuals */} +
+ + +
+
+
+ +
+
+
Automated CI/CD Pipeline
+
Triggered on merge to main
+
+
+
+
+ Lint & Format + Success +
+
+ Unit Tests + Success +
+
+ Deploy to Production + Running… +
+
+
+
+
+ +
+ +
+
+
+ + ); +}