mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
update ui
This commit is contained in:
@@ -117,9 +117,6 @@ export default function SponsorsSection() {
|
|||||||
<div className="border-border border-b bg-muted/20 px-3 py-2">
|
<div className="border-border border-b bg-muted/20 px-3 py-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-primary text-xs">▶</span>
|
<span className="text-primary text-xs">▶</span>
|
||||||
<span className="truncate font-mono font-semibold text-xs">
|
|
||||||
[SPONSOR_{String(index + 1).padStart(3, "0")}]
|
|
||||||
</span>
|
|
||||||
<div className="ml-auto flex items-center gap-2 text-muted-foreground text-xs">
|
<div className="ml-auto flex items-center gap-2 text-muted-foreground text-xs">
|
||||||
<span>{entry.isOneTime ? "ONE-TIME" : "MONTHLY"}</span>
|
<span>{entry.isOneTime ? "ONE-TIME" : "MONTHLY"}</span>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
|
|||||||
@@ -319,6 +319,20 @@ const analyzeStackCompatibility = (stack: StackState): CompatibilityResult => {
|
|||||||
}
|
}
|
||||||
if (nextStack.api === "none" && (isConvex || isBackendNone)) {
|
if (nextStack.api === "none" && (isConvex || isBackendNone)) {
|
||||||
} else if (nextStack.api === "none" && !(isConvex || isBackendNone)) {
|
} else if (nextStack.api === "none" && !(isConvex || isBackendNone)) {
|
||||||
|
if (nextStack.examples.length > 0) {
|
||||||
|
notes.api.notes.push("API 'None' selected: Examples will be removed.");
|
||||||
|
notes.examples.notes.push(
|
||||||
|
"Examples require an API. They will be removed when API is 'None'.",
|
||||||
|
);
|
||||||
|
notes.api.hasIssue = true;
|
||||||
|
notes.examples.hasIssue = true;
|
||||||
|
nextStack.examples = [];
|
||||||
|
changed = true;
|
||||||
|
changes.push({
|
||||||
|
category: "api",
|
||||||
|
message: "Examples removed (API 'None' does not support examples)",
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextStack.database === "none") {
|
if (nextStack.database === "none") {
|
||||||
@@ -1283,6 +1297,17 @@ const StackBuilder = () => {
|
|||||||
"Disabled: This example requires a web frontend.",
|
"Disabled: This example requires a web frontend.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
stack.api === "none" &&
|
||||||
|
!rules.isConvex &&
|
||||||
|
!rules.isBackendNone
|
||||||
|
) {
|
||||||
|
addRule(
|
||||||
|
category,
|
||||||
|
techId,
|
||||||
|
"Disabled: Examples require an API. Cannot be selected when API is 'None'.",
|
||||||
|
);
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
stack.database === "none" &&
|
stack.database === "none" &&
|
||||||
techId === "todo" &&
|
techId === "todo" &&
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ export default function Testimonials() {
|
|||||||
onClick={handlePrev}
|
onClick={handlePrev}
|
||||||
disabled={currentPage === 1}
|
disabled={currentPage === 1}
|
||||||
className={cn(
|
className={cn(
|
||||||
"terminal-block-hover flex items-center gap-1.5 rounded border border-border bg-background px-3 py-1.5 font-mono text-xs transition-colors",
|
"terminal-block-hover hidden items-center gap-1.5 rounded border border-border bg-background px-3 py-1.5 font-mono text-xs transition-colors sm:flex",
|
||||||
currentPage === 1
|
currentPage === 1
|
||||||
? "cursor-not-allowed opacity-50"
|
? "cursor-not-allowed opacity-50"
|
||||||
: "hover:bg-muted/50",
|
: "hover:bg-muted/50",
|
||||||
@@ -225,7 +225,7 @@ export default function Testimonials() {
|
|||||||
onClick={handleNext}
|
onClick={handleNext}
|
||||||
disabled={currentPage === totalPages}
|
disabled={currentPage === totalPages}
|
||||||
className={cn(
|
className={cn(
|
||||||
"terminal-block-hover flex items-center gap-1.5 rounded border border-border bg-background px-3 py-1.5 font-mono text-xs transition-colors",
|
"terminal-block-hover hidden items-center gap-1.5 rounded border border-border bg-background px-3 py-1.5 font-mono text-xs transition-colors sm:flex",
|
||||||
currentPage === totalPages
|
currentPage === totalPages
|
||||||
? "cursor-not-allowed opacity-50"
|
? "cursor-not-allowed opacity-50"
|
||||||
: "hover:bg-muted/50",
|
: "hover:bg-muted/50",
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ export default function HomePage() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span className="flex-1 truncate font-mono text-xs">
|
<span className="flex-1 truncate font-mono text-xs">
|
||||||
{option.name.toLowerCase().replace(/\s+/g, "-")}.pkg
|
{option.name.toLowerCase().replace(/\s+/g, "-")}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-mono text-muted-foreground text-xs opacity-0 transition-opacity group-hover:opacity-100">
|
<span className="font-mono text-muted-foreground text-xs opacity-0 transition-opacity group-hover:opacity-100">
|
||||||
-rw-r--r--
|
-rw-r--r--
|
||||||
|
|||||||
142
apps/web/src/app/(home)/showcase/_components/ShowcaseItem.tsx
Normal file
142
apps/web/src/app/(home)/showcase/_components/ShowcaseItem.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { ExternalLink, File, Github, Monitor } from "lucide-react";
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import Image from "next/image";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
export interface ShowcaseItemProps {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
imageUrl: string;
|
||||||
|
liveUrl?: string;
|
||||||
|
sourceUrl?: string;
|
||||||
|
tags: string[];
|
||||||
|
index?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ShowcaseItem({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
imageUrl,
|
||||||
|
liveUrl,
|
||||||
|
sourceUrl,
|
||||||
|
tags,
|
||||||
|
index = 0,
|
||||||
|
}: ShowcaseItemProps) {
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { opacity: 0, y: 20 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
y: 0,
|
||||||
|
transition: {
|
||||||
|
duration: 0.5,
|
||||||
|
ease: "easeOut",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const projectId = `PROJECT_${String(index + 1).padStart(3, "0")}`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
variants={itemVariants}
|
||||||
|
className="terminal-block-hover flex h-full flex-col overflow-hidden rounded border border-border bg-background"
|
||||||
|
style={{ animationDelay: `${index * 100}ms` }}
|
||||||
|
>
|
||||||
|
<div className="border-border border-b bg-muted/20 px-3 py-2">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<File className="h-3 w-3 text-primary" />
|
||||||
|
<span className="font-mono font-semibold text-foreground text-xs">
|
||||||
|
{projectId}.PROJECT
|
||||||
|
</span>
|
||||||
|
<div className="ml-auto flex items-center gap-2 text-muted-foreground text-xs">
|
||||||
|
<span>•</span>
|
||||||
|
<span>{tags.length} DEPS</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative aspect-[4/3] w-full overflow-hidden bg-muted/10">
|
||||||
|
<Image
|
||||||
|
src={imageUrl}
|
||||||
|
alt={title}
|
||||||
|
fill
|
||||||
|
className="object-cover transition-all duration-300 ease-in-out hover:scale-105"
|
||||||
|
unoptimized
|
||||||
|
/>
|
||||||
|
<div className="absolute inset-0 bg-black/20 opacity-0 transition-opacity duration-300 hover:opacity-100" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-1 flex-col p-4">
|
||||||
|
<h3 className="mb-2 font-bold font-mono text-lg text-primary">
|
||||||
|
{title}
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p className="mb-4 flex-grow font-mono text-muted-foreground text-sm leading-relaxed">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className="mb-4">
|
||||||
|
<div className="mb-2 flex items-center gap-2">
|
||||||
|
<span className="font-mono text-muted-foreground text-xs">
|
||||||
|
DEPENDENCIES:
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-wrap gap-1">
|
||||||
|
{tags.map((tag) => (
|
||||||
|
<span
|
||||||
|
key={tag}
|
||||||
|
className="rounded border border-border bg-muted/30 px-2 py-1 font-mono text-foreground text-xs transition-colors hover:bg-muted/50"
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-auto space-y-2">
|
||||||
|
<div className="grid gap-2">
|
||||||
|
{liveUrl && (
|
||||||
|
<Link
|
||||||
|
href={liveUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-2 rounded border border-border bg-primary/10 px-3 py-2 font-mono text-primary text-sm transition-all hover:bg-primary/20 hover:text-primary"
|
||||||
|
>
|
||||||
|
<Monitor className="h-3 w-3" />
|
||||||
|
<span>LAUNCH_DEMO.EXE</span>
|
||||||
|
<ExternalLink className="ml-auto h-3 w-3" />
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
{sourceUrl && (
|
||||||
|
<Link
|
||||||
|
href={sourceUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="flex items-center gap-2 rounded border border-border bg-muted/20 px-3 py-2 font-mono text-muted-foreground text-sm transition-all hover:bg-muted/40 hover:text-foreground"
|
||||||
|
>
|
||||||
|
<Github className="h-3 w-3" />
|
||||||
|
<span>VIEW_SOURCE.GIT</span>
|
||||||
|
<ExternalLink className="ml-auto h-3 w-3" />
|
||||||
|
</Link>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-border border-t pt-2">
|
||||||
|
<div className="flex items-center gap-2 text-xs">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-muted-foreground">
|
||||||
|
echo "Status: READY"
|
||||||
|
</span>
|
||||||
|
<div className="ml-auto flex items-center gap-1">
|
||||||
|
<div className="h-1 w-1 animate-pulse rounded-full bg-green-400" />
|
||||||
|
<span className="font-mono text-green-400 text-xs">ONLINE</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
142
apps/web/src/app/(home)/showcase/page.tsx
Normal file
142
apps/web/src/app/(home)/showcase/page.tsx
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { FolderOpen, Terminal } from "lucide-react";
|
||||||
|
import { motion } from "motion/react";
|
||||||
|
import Navbar from "../_components/navbar";
|
||||||
|
import ShowcaseItem from "./_components/ShowcaseItem";
|
||||||
|
|
||||||
|
const showcaseProjects = [
|
||||||
|
{
|
||||||
|
title: "Project Alpha",
|
||||||
|
description: "A cool project built with Better-T-Stack.",
|
||||||
|
imageUrl: "https://via.placeholder.com/400x300?text=Project+Alpha",
|
||||||
|
liveUrl: "#",
|
||||||
|
sourceUrl: "#",
|
||||||
|
tags: ["Next.js", "tRPC", "Drizzle"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Beta App",
|
||||||
|
description: "Another awesome application powered by Better-T-Stack.",
|
||||||
|
imageUrl: "https://via.placeholder.com/400x300?text=Beta+App",
|
||||||
|
liveUrl: "#",
|
||||||
|
sourceUrl: "#",
|
||||||
|
tags: ["Hono", "React Native", "SQLite"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Gamma Platform",
|
||||||
|
description: "Showcasing the versatility of Better-T-Stack.",
|
||||||
|
imageUrl: "https://via.placeholder.com/400x300?text=Gamma+Platform",
|
||||||
|
liveUrl: "#",
|
||||||
|
tags: ["Convex", "TanStack Router"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function ShowcasePage() {
|
||||||
|
const containerVariants = {
|
||||||
|
hidden: { opacity: 0 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
transition: {
|
||||||
|
staggerChildren: 0.1,
|
||||||
|
delayChildren: 0.2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const itemVariants = {
|
||||||
|
hidden: { opacity: 0, y: 20 },
|
||||||
|
visible: {
|
||||||
|
opacity: 1,
|
||||||
|
y: 0,
|
||||||
|
transition: {
|
||||||
|
duration: 0.5,
|
||||||
|
ease: "easeOut",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<main className="flex min-h-svh flex-col items-center bg-background px-4 pt-24 pb-10 sm:px-6 md:px-8 md:pt-28 lg:pt-32">
|
||||||
|
<motion.div
|
||||||
|
className="mx-auto w-full max-w-6xl"
|
||||||
|
initial="hidden"
|
||||||
|
animate="visible"
|
||||||
|
variants={containerVariants}
|
||||||
|
>
|
||||||
|
<motion.div className="mb-8" variants={itemVariants}>
|
||||||
|
<div className="mb-6 flex items-center gap-2">
|
||||||
|
<Terminal className="terminal-glow h-4 w-4 text-primary" />
|
||||||
|
<span className="terminal-glow font-bold font-mono text-lg">
|
||||||
|
PROJECT_SHOWCASE.EXE
|
||||||
|
</span>
|
||||||
|
<div className="h-px flex-1 bg-border" />
|
||||||
|
<span className="font-mono text-muted-foreground text-xs">
|
||||||
|
[{showcaseProjects.length} PROJECTS FOUND]
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="terminal-block-hover mb-8 rounded border border-border bg-muted/20 p-4">
|
||||||
|
<div className="flex items-center gap-2 text-sm">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-foreground">
|
||||||
|
user@dev-machine:~/showcase$ ls -la
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex items-center gap-2 text-sm">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-muted-foreground">
|
||||||
|
# Discover amazing projects built with Better-T-Stack
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex items-center gap-2 text-sm">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-muted-foreground">
|
||||||
|
# Real-world implementations showcasing stack capabilities
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="terminal-block-hover rounded border border-border bg-background p-3">
|
||||||
|
<div className="flex items-center gap-2 font-mono text-sm">
|
||||||
|
<FolderOpen className="h-4 w-4 text-blue-400" />
|
||||||
|
<span className="text-foreground">/showcase/projects/</span>
|
||||||
|
<div className="ml-auto text-muted-foreground text-xs">
|
||||||
|
drwxr-xr-x {showcaseProjects.length} items
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div
|
||||||
|
className="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3"
|
||||||
|
variants={containerVariants}
|
||||||
|
>
|
||||||
|
{showcaseProjects.map((project, index) => (
|
||||||
|
<ShowcaseItem key={project.title} {...project} index={index} />
|
||||||
|
))}
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
<motion.div className="mt-8" variants={itemVariants}>
|
||||||
|
<div className="terminal-block-hover rounded border border-border bg-muted/20 p-4">
|
||||||
|
<div className="flex items-center gap-2 text-sm">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-muted-foreground">
|
||||||
|
# Want to showcase your project? Submit via GitHub issues
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="mt-2 flex items-center gap-2 text-sm">
|
||||||
|
<span className="terminal-glow text-primary">$</span>
|
||||||
|
<span className="font-mono text-foreground">
|
||||||
|
echo "Built something amazing? We'd love to feature
|
||||||
|
it!"
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
</motion.div>
|
||||||
|
</main>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { motion } from "motion/react";
|
|
||||||
import Image from "next/image";
|
|
||||||
import Link from "next/link";
|
|
||||||
|
|
||||||
export interface ShowcaseItemProps {
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
imageUrl: string;
|
|
||||||
liveUrl?: string;
|
|
||||||
sourceUrl?: string;
|
|
||||||
tags: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function ShowcaseItem({
|
|
||||||
title,
|
|
||||||
description,
|
|
||||||
imageUrl,
|
|
||||||
liveUrl,
|
|
||||||
sourceUrl,
|
|
||||||
tags,
|
|
||||||
}: ShowcaseItemProps) {
|
|
||||||
const itemVariants = {
|
|
||||||
hidden: { opacity: 0, y: 20 },
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
y: 0,
|
|
||||||
transition: {
|
|
||||||
duration: 0.5,
|
|
||||||
ease: "easeOut",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
variants={itemVariants}
|
|
||||||
className="flex h-full flex-col overflow-hidden rounded-lg border border-border bg-card p-6 shadow-sm"
|
|
||||||
>
|
|
||||||
<div className="relative mb-4 aspect-[4/3] w-full overflow-hidden rounded-md">
|
|
||||||
<Image
|
|
||||||
src={imageUrl}
|
|
||||||
alt={title}
|
|
||||||
fill
|
|
||||||
className="object-cover transition-transform duration-300 ease-in-out hover:scale-105"
|
|
||||||
unoptimized
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<h3 className="mb-2 font-mono font-semibold text-primary text-xl">
|
|
||||||
{title}
|
|
||||||
</h3>
|
|
||||||
<p className="mb-4 flex-grow text-muted-foreground text-sm">
|
|
||||||
{description}
|
|
||||||
</p>
|
|
||||||
<div className="mb-4">
|
|
||||||
{tags.map((tag) => (
|
|
||||||
<span
|
|
||||||
key={tag}
|
|
||||||
className="mr-2 mb-2 inline-block rounded-full bg-muted px-2 py-1 font-mono text-muted-foreground text-xs"
|
|
||||||
>
|
|
||||||
{tag}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="mt-auto flex space-x-3">
|
|
||||||
{liveUrl && (
|
|
||||||
<Link
|
|
||||||
href={liveUrl}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="font-mono text-primary text-sm hover:underline"
|
|
||||||
>
|
|
||||||
Live Demo
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
{sourceUrl && (
|
|
||||||
<Link
|
|
||||||
href={sourceUrl}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="font-mono text-muted-foreground text-sm hover:underline"
|
|
||||||
>
|
|
||||||
Source Code
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { motion } from "motion/react";
|
|
||||||
import Navbar from "../(home)/_components/navbar";
|
|
||||||
import ShowcaseItem from "./_components/ShowcaseItem";
|
|
||||||
|
|
||||||
const showcaseProjects = [
|
|
||||||
{
|
|
||||||
title: "Project Alpha",
|
|
||||||
description: "A cool project built with Better-T-Stack.",
|
|
||||||
imageUrl: "https://via.placeholder.com/400x300?text=Project+Alpha",
|
|
||||||
liveUrl: "#",
|
|
||||||
sourceUrl: "#",
|
|
||||||
tags: ["Next.js", "tRPC", "Drizzle"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Beta App",
|
|
||||||
description: "Another awesome application powered by Better-T-Stack.",
|
|
||||||
imageUrl: "https://via.placeholder.com/400x300?text=Beta+App",
|
|
||||||
liveUrl: "#",
|
|
||||||
sourceUrl: "#",
|
|
||||||
tags: ["Hono", "React Native", "SQLite"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Gamma Platform",
|
|
||||||
description: "Showcasing the versatility of Better-T-Stack.",
|
|
||||||
imageUrl: "https://via.placeholder.com/400x300?text=Gamma+Platform",
|
|
||||||
liveUrl: "#",
|
|
||||||
tags: ["Convex", "TanStack Router"],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default function ShowcasePage() {
|
|
||||||
const containerVariants = {
|
|
||||||
hidden: { opacity: 0 },
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
transition: {
|
|
||||||
staggerChildren: 0.1,
|
|
||||||
delayChildren: 0.2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const itemVariants = {
|
|
||||||
hidden: { opacity: 0, y: 20 },
|
|
||||||
visible: {
|
|
||||||
opacity: 1,
|
|
||||||
y: 0,
|
|
||||||
transition: {
|
|
||||||
duration: 0.5,
|
|
||||||
ease: "easeOut",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Navbar />
|
|
||||||
<main className="flex min-h-svh flex-col items-center bg-background px-4 pt-24 pb-10 sm:px-6 md:px-8 md:pt-28 lg:pt-32">
|
|
||||||
<motion.div
|
|
||||||
className="mx-auto w-full max-w-6xl"
|
|
||||||
initial="hidden"
|
|
||||||
animate="visible"
|
|
||||||
variants={containerVariants}
|
|
||||||
>
|
|
||||||
<motion.div className="mb-12 text-center" variants={itemVariants}>
|
|
||||||
<h1 className="font-bold font-mono text-4xl tracking-tight sm:text-5xl md:text-6xl">
|
|
||||||
<span className="text-foreground dark:text-primary">
|
|
||||||
Showcase
|
|
||||||
</span>
|
|
||||||
</h1>
|
|
||||||
<p className="mx-auto mt-4 max-w-2xl font-mono text-lg text-muted-foreground sm:text-xl">
|
|
||||||
Discover amazing projects built with Better-T-Stack.
|
|
||||||
</p>
|
|
||||||
</motion.div>
|
|
||||||
|
|
||||||
<motion.div
|
|
||||||
className="grid grid-cols-1 gap-8 md:grid-cols-2 lg:grid-cols-3"
|
|
||||||
variants={containerVariants}
|
|
||||||
>
|
|
||||||
{showcaseProjects.map((project) => (
|
|
||||||
<ShowcaseItem key={project.title} {...project} />
|
|
||||||
))}
|
|
||||||
</motion.div>
|
|
||||||
</motion.div>
|
|
||||||
</main>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
32
bun.lock
32
bun.lock
@@ -14,28 +14,28 @@
|
|||||||
},
|
},
|
||||||
"apps/cli": {
|
"apps/cli": {
|
||||||
"name": "create-better-t-stack",
|
"name": "create-better-t-stack",
|
||||||
"version": "2.13.4",
|
"version": "2.14.0",
|
||||||
"bin": {
|
"bin": {
|
||||||
"create-better-t-stack": "dist/index.js",
|
"create-better-t-stack": "dist/index.js",
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "latest",
|
"@clack/prompts": "^0.11.0",
|
||||||
"consola": "latest",
|
"consola": "^3.4.2",
|
||||||
"execa": "latest",
|
"execa": "^9.6.0",
|
||||||
"fs-extra": "latest",
|
"fs-extra": "^11.3.0",
|
||||||
"globby": "latest",
|
"globby": "^14.1.0",
|
||||||
"gradient-string": "latest",
|
"gradient-string": "^3.0.0",
|
||||||
"handlebars": "latest",
|
"handlebars": "^4.7.8",
|
||||||
"picocolors": "latest",
|
"picocolors": "^1.1.1",
|
||||||
"posthog-node": "latest",
|
"posthog-node": "^4.18.0",
|
||||||
"yargs": "latest",
|
"yargs": "^18.0.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/fs-extra": "latest",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/node": "latest",
|
"@types/node": "^22.15.23",
|
||||||
"@types/yargs": "latest",
|
"@types/yargs": "^17.0.33",
|
||||||
"tsdown": "latest",
|
"tsdown": "^0.12.4",
|
||||||
"typescript": "latest",
|
"typescript": "^5.8.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"apps/web": {
|
"apps/web": {
|
||||||
|
|||||||
Reference in New Issue
Block a user