diff --git a/apps/web/src/app/(home)/_components/command-section.tsx b/apps/web/src/app/(home)/_components/command-section.tsx
index 48370c0..4b7d7b1 100644
--- a/apps/web/src/app/(home)/_components/command-section.tsx
+++ b/apps/web/src/app/(home)/_components/command-section.tsx
@@ -1,5 +1,12 @@
"use client";
-import { Check, ChevronDown, ChevronRight, Copy, Terminal } from "lucide-react";
+import {
+ Check,
+ ChevronDown,
+ ChevronRight,
+ Copy,
+ Terminal,
+ Zap,
+} from "lucide-react";
import Link from "next/link";
import { useState } from "react";
import {
@@ -28,7 +35,7 @@ export default function CommandSection() {
};
return (
-
+
@@ -104,7 +111,7 @@ export default function CommandSection() {
-
⚡
+
Interactive configuration wizard
diff --git a/apps/web/src/app/(home)/_components/hero-section.tsx b/apps/web/src/app/(home)/_components/hero-section.tsx
index bd84350..37b83ac 100644
--- a/apps/web/src/app/(home)/_components/hero-section.tsx
+++ b/apps/web/src/app/(home)/_components/hero-section.tsx
@@ -2,7 +2,7 @@ import NpmPackage from "./npm-package";
export default function HeroSection() {
return (
- <>
+
@@ -47,15 +47,12 @@ export default function HeroSection() {
-
+
Modern CLI for scaffolding end-to-end type-safe TypeScript projects
-
- Production-ready • Customizable • Best practices included
-
- >
+
);
}
diff --git a/apps/web/src/app/(home)/_components/sponsors-section.tsx b/apps/web/src/app/(home)/_components/sponsors-section.tsx
index cc2754a..c487350 100644
--- a/apps/web/src/app/(home)/_components/sponsors-section.tsx
+++ b/apps/web/src/app/(home)/_components/sponsors-section.tsx
@@ -1,6 +1,4 @@
"use client";
-import type { api } from "@better-t-stack/backend/convex/_generated/api";
-import { type Preloaded, usePreloadedQuery } from "convex/react";
import {
ChevronDown,
ChevronUp,
@@ -26,17 +24,33 @@ import {
sortSponsors,
} from "@/lib/sponsor-utils";
-export default function SponsorsSection({
- preloadedSponsors,
-}: {
- preloadedSponsors: Preloaded
;
-}) {
- const sponsorsData = usePreloadedQuery(preloadedSponsors);
+type SponsorEntry = {
+ sponsor: {
+ login: string;
+ name: string;
+ avatarUrl: string;
+ websiteUrl?: string;
+ linkUrl: string;
+ customLogoUrl?: string;
+ type: string;
+ };
+ isOneTime: boolean;
+ monthlyDollars: number;
+ privacyLevel: string;
+ tierName: string;
+ createdAt: string;
+ provider: string;
+};
+export default function SponsorsSection({
+ sponsors,
+}: {
+ sponsors: Array;
+}) {
const [showPastSponsors, setShowPastSponsors] = useState(false);
- const sponsors =
- sponsorsData.map((sponsor) => ({
+ const sponsorsData =
+ sponsors.map((sponsor) => ({
...sponsor,
sponsor: {
...sponsor.sponsor,
@@ -44,16 +58,16 @@ export default function SponsorsSection({
},
})) || [];
- const visibleSponsors = filterVisibleSponsors(sponsors);
+ const visibleSponsors = filterVisibleSponsors(sponsorsData);
const sortedSponsors = sortSponsors(visibleSponsors);
const currentSponsors = filterCurrentSponsors(sortedSponsors);
- const pastSponsors = filterPastSponsors(sortSponsors(sponsors));
+ const pastSponsors = filterPastSponsors(sortSponsors(sponsorsData));
const specialSponsors = sortSpecialSponsors(
filterSpecialSponsors(currentSponsors),
);
return (
-
+
diff --git a/apps/web/src/app/(home)/_components/stats-section.tsx b/apps/web/src/app/(home)/_components/stats-section.tsx
index b4ab916..09e48fa 100644
--- a/apps/web/src/app/(home)/_components/stats-section.tsx
+++ b/apps/web/src/app/(home)/_components/stats-section.tsx
@@ -33,7 +33,7 @@ export default function StatsSection({
const liveNpmDownloadCount = useNpmDownloadCounter(npmPackages);
return (
-
+
diff --git a/apps/web/src/app/(home)/_components/testimonials.tsx b/apps/web/src/app/(home)/_components/testimonials.tsx
index 1d0a7d4..649f758 100644
--- a/apps/web/src/app/(home)/_components/testimonials.tsx
+++ b/apps/web/src/app/(home)/_components/testimonials.tsx
@@ -1,7 +1,5 @@
"use client";
-import type { api } from "@better-t-stack/backend/convex/_generated/api";
-import { type Preloaded, usePreloadedQuery } from "convex/react";
import { Play, Terminal } from "lucide-react";
import { motion } from "motion/react";
import Image from "next/image";
@@ -99,14 +97,13 @@ const TweetCard = ({ tweetId, index }: { tweetId: string; index: number }) => (
);
export default function Testimonials({
- preloadedTestimonialsTweet,
- preloadedTestimonialsVideos,
+ videos,
+ tweets,
}: {
- preloadedTestimonialsTweet: Preloaded
;
- preloadedTestimonialsVideos: Preloaded;
+ videos: Array<{ embedId: string; title: string }>;
+ tweets: Array<{ tweetId: string }>;
}) {
- const videos = usePreloadedQuery(preloadedTestimonialsVideos).reverse();
- const tweets = usePreloadedQuery(preloadedTestimonialsTweet);
+ const videosReversed = [...videos].reverse();
const getResponsiveColumns = (numCols: number) => {
const columns: string[][] = Array(numCols)
@@ -138,7 +135,7 @@ export default function Testimonials({
};
return (
-
+
@@ -149,7 +146,7 @@ export default function Testimonials({
- [{videos.length} ENTRIES]
+ [{videosReversed.length} ENTRIES]
@@ -160,7 +157,7 @@ export default function Testimonials({
initial="hidden"
animate="visible"
>
- {videos.map((video, index) => (
+ {videosReversed.map((video, index) => (
- {videos.map((video, index) => (
+ {videosReversed.map((video, index) => (
({
+ embedId: v.embedId,
+ title: v.title,
+ }));
+ const tweets = fetchedTweets.map((t) => ({ tweetId: t.tweetId }));
const minimalAnalytics = await fetch(
"https://r2.better-t-stack.dev/analytics-minimal.json",
@@ -23,18 +24,15 @@ export default async function HomePage() {
const minimalAnalyticsData = await minimalAnalytics.json();
return (
-
+
);
}
diff --git a/apps/web/src/app/(home)/showcase/_components/showcase-page.tsx b/apps/web/src/app/(home)/showcase/_components/showcase-page.tsx
index 4808d2d..382e48e 100644
--- a/apps/web/src/app/(home)/showcase/_components/showcase-page.tsx
+++ b/apps/web/src/app/(home)/showcase/_components/showcase-page.tsx
@@ -1,18 +1,24 @@
"use client";
-import type { api } from "@better-t-stack/backend/convex/_generated/api";
-import { type Preloaded, usePreloadedQuery } from "convex/react";
import { Terminal } from "lucide-react";
import Footer from "../../_components/footer";
import ShowcaseItem from "../_components/ShowcaseItem";
-export default function ShowcasePage({
- preloadedShowcase,
-}: {
- preloadedShowcase: Preloaded;
-}) {
- const showcaseProjects = usePreloadedQuery(preloadedShowcase);
+type ShowcaseProject = {
+ _id: string;
+ _creationTime: number;
+ title: string;
+ description: string;
+ imageUrl: string;
+ liveUrl: string;
+ tags: string[];
+};
+export default function ShowcasePage({
+ showcaseProjects,
+}: {
+ showcaseProjects: Array;
+}) {
return (
diff --git a/apps/web/src/app/(home)/showcase/page.tsx b/apps/web/src/app/(home)/showcase/page.tsx
index 29f22f3..1d87b04 100644
--- a/apps/web/src/app/(home)/showcase/page.tsx
+++ b/apps/web/src/app/(home)/showcase/page.tsx
@@ -1,10 +1,8 @@
import { api } from "@better-t-stack/backend/convex/_generated/api";
-import { preloadQuery } from "convex/nextjs";
+import { fetchQuery } from "convex/nextjs";
import ShowcasePage from "./_components/showcase-page";
export default async function Showcase() {
- const preloadedShowcase = await preloadQuery(
- api.showcase.getShowcaseProjects,
- );
- return ;
+ const showcaseProjects = await fetchQuery(api.showcase.getShowcaseProjects);
+ return ;
}