|
1 | | -import Link from "next/link"; |
2 | | -import { ArrowRight, Download } from "lucide-react"; |
3 | | -import { ScreenshotGallery } from "@/components/screenshot-gallery"; |
4 | | -import { homepage, siteConfig } from "@/content/homepage"; |
5 | | -import { docsNav } from "@/lib/navigation"; |
6 | 1 | import { |
7 | | - formatReleaseDate, |
8 | | - getLatestRelease, |
9 | | - getRepoStats, |
10 | | - parseReleaseSections, |
11 | | -} from "@/lib/github"; |
| 2 | + BottomDownloadCta, |
| 3 | +} from "@/components/home/bottom-download-cta"; |
| 4 | +import { BuiltFor } from "@/components/home/built-for"; |
| 5 | +import { CommunityCta } from "@/components/home/community-cta"; |
| 6 | +import { DocsPreview } from "@/components/home/docs-preview"; |
| 7 | +import { FeatureGrid } from "@/components/home/feature-grid"; |
| 8 | +import { FeatureShowcase } from "@/components/home/feature-showcase"; |
| 9 | +import { HeroSection } from "@/components/home/hero-section"; |
| 10 | +import { LatestReleaseSection } from "@/components/home/latest-release-section"; |
| 11 | +import { OpenSourceStrip } from "@/components/home/open-source-strip"; |
| 12 | +import { ScreenshotGallery } from "@/components/screenshot-gallery"; |
| 13 | +import { getLatestRelease, getRepoStats } from "@/lib/github"; |
12 | 14 |
|
13 | 15 | export default async function HomePage() { |
14 | 16 | const [release, stats] = await Promise.all([ |
15 | 17 | getLatestRelease(), |
16 | 18 | getRepoStats(), |
17 | 19 | ]); |
18 | | - const highlights = release ? parseReleaseSections(release.body) : {}; |
19 | 20 |
|
20 | 21 | return ( |
21 | 22 | <> |
22 | | - <section className="border-b border-border/60 bg-gradient-to-b from-muted/40 to-background"> |
23 | | - <div className="mx-auto max-w-6xl px-4 py-20 sm:px-6 sm:py-28"> |
24 | | - <p className="mb-4 text-sm font-medium text-primary"> |
25 | | - Free & open source · Windows 10/11 |
26 | | - </p> |
27 | | - <h1 className="max-w-3xl text-4xl font-bold tracking-tight sm:text-5xl"> |
28 | | - {homepage.hero.title} |
29 | | - </h1> |
30 | | - <p className="mt-6 max-w-2xl text-lg text-muted-foreground"> |
31 | | - {homepage.hero.subtitle} |
32 | | - </p> |
33 | | - <div className="mt-8 flex flex-wrap gap-4"> |
34 | | - <Link |
35 | | - href="/download" |
36 | | - className="inline-flex items-center gap-2 rounded-lg bg-primary px-5 py-3 text-sm font-semibold text-white transition-opacity hover:opacity-90" |
37 | | - > |
38 | | - <Download className="h-4 w-4" /> |
39 | | - {homepage.hero.primaryCta} |
40 | | - </Link> |
41 | | - <Link |
42 | | - href="/docs" |
43 | | - className="inline-flex items-center gap-2 rounded-lg border border-border px-5 py-3 text-sm font-semibold transition-colors hover:bg-muted" |
44 | | - > |
45 | | - {homepage.hero.secondaryCta} |
46 | | - <ArrowRight className="h-4 w-4" /> |
47 | | - </Link> |
48 | | - </div> |
49 | | - {release ? ( |
50 | | - <p className="mt-4 text-sm text-muted-foreground"> |
51 | | - Latest release:{" "} |
52 | | - <Link href="/download" className="font-medium text-foreground"> |
53 | | - {release.tag_name} |
54 | | - </Link>{" "} |
55 | | - · {formatReleaseDate(release.published_at)} |
56 | | - </p> |
57 | | - ) : null} |
58 | | - </div> |
59 | | - </section> |
60 | | - |
61 | | - <section className="mx-auto max-w-6xl px-4 py-16 sm:px-6"> |
62 | | - <h2 className="mb-10 text-center text-2xl font-bold">Why DevStackBox?</h2> |
63 | | - <div className="grid gap-6 sm:grid-cols-2"> |
64 | | - {homepage.features.map((f) => ( |
65 | | - <div |
66 | | - key={f.title} |
67 | | - className="rounded-xl border border-border p-6 shadow-sm" |
68 | | - > |
69 | | - <h3 className="font-semibold">{f.title}</h3> |
70 | | - <p className="mt-2 text-sm text-muted-foreground">{f.description}</p> |
71 | | - </div> |
72 | | - ))} |
73 | | - </div> |
74 | | - </section> |
75 | | - |
76 | | - {release && (highlights.Added?.length || highlights.Changed?.length) ? ( |
77 | | - <section className="border-y border-border/60 bg-muted/20"> |
78 | | - <div className="mx-auto max-w-6xl px-4 py-16 sm:px-6"> |
79 | | - <div className="flex items-end justify-between gap-4"> |
80 | | - <div> |
81 | | - <h2 className="text-2xl font-bold">What's new</h2> |
82 | | - <p className="mt-1 text-muted-foreground">{release.tag_name}</p> |
83 | | - </div> |
84 | | - <Link href="/whats-new" className="text-sm font-medium text-primary"> |
85 | | - Read more → |
86 | | - </Link> |
87 | | - </div> |
88 | | - <ul className="mt-6 grid gap-2 sm:grid-cols-2"> |
89 | | - {[...(highlights.Added ?? []), ...(highlights.Changed ?? [])] |
90 | | - .slice(0, 6) |
91 | | - .map((item) => ( |
92 | | - <li key={item} className="text-sm text-muted-foreground"> |
93 | | - • {item} |
94 | | - </li> |
95 | | - ))} |
96 | | - </ul> |
97 | | - </div> |
98 | | - </section> |
99 | | - ) : null} |
100 | | - |
| 23 | + <HeroSection release={release} /> |
| 24 | + <OpenSourceStrip /> |
| 25 | + <FeatureGrid /> |
| 26 | + <BuiltFor /> |
| 27 | + <FeatureShowcase /> |
101 | 28 | <ScreenshotGallery /> |
102 | | - |
103 | | - <section className="mx-auto max-w-6xl px-4 py-16 sm:px-6"> |
104 | | - <h2 className="mb-8 text-center text-2xl font-bold">Documentation</h2> |
105 | | - <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4"> |
106 | | - {docsNav.map((section) => ( |
107 | | - <Link |
108 | | - key={section.title} |
109 | | - href={ |
110 | | - section.items[0]?.slug |
111 | | - ? `/docs/${section.items[0].slug}` |
112 | | - : "/docs" |
113 | | - } |
114 | | - className="rounded-xl border border-border p-5 transition-colors hover:bg-muted/50" |
115 | | - > |
116 | | - <h3 className="font-semibold">{section.title}</h3> |
117 | | - <p className="mt-1 text-sm text-muted-foreground"> |
118 | | - {section.items.length} guides |
119 | | - </p> |
120 | | - </Link> |
121 | | - ))} |
122 | | - </div> |
123 | | - </section> |
124 | | - |
125 | | - <section className="border-t border-border/60 bg-muted/20"> |
126 | | - <div className="mx-auto max-w-6xl px-4 py-16 text-center sm:px-6"> |
127 | | - <h2 className="text-2xl font-bold">Community</h2> |
128 | | - <p className="mx-auto mt-3 max-w-xl text-muted-foreground"> |
129 | | - DevStackBox is open source. Report bugs, suggest features, or |
130 | | - contribute on GitHub. |
131 | | - </p> |
132 | | - {stats ? ( |
133 | | - <p className="mt-4 text-sm text-muted-foreground"> |
134 | | - {stats.stargazers_count.toLocaleString()} stars ·{" "} |
135 | | - {stats.forks_count.toLocaleString()} forks |
136 | | - </p> |
137 | | - ) : null} |
138 | | - <div className="mt-6 flex flex-wrap justify-center gap-4"> |
139 | | - <a |
140 | | - href={siteConfig.githubUrl} |
141 | | - target="_blank" |
142 | | - rel="noopener noreferrer" |
143 | | - className="rounded-lg border border-border px-4 py-2 text-sm font-medium hover:bg-background" |
144 | | - > |
145 | | - GitHub |
146 | | - </a> |
147 | | - <Link |
148 | | - href="/community" |
149 | | - className="rounded-lg border border-border px-4 py-2 text-sm font-medium hover:bg-background" |
150 | | - > |
151 | | - Community |
152 | | - </Link> |
153 | | - </div> |
154 | | - </div> |
155 | | - </section> |
| 29 | + <LatestReleaseSection release={release} /> |
| 30 | + <DocsPreview /> |
| 31 | + <CommunityCta stats={stats} /> |
| 32 | + <BottomDownloadCta /> |
156 | 33 | </> |
157 | 34 | ); |
158 | 35 | } |
0 commit comments