Add demo link in navbar and fix stack in tech showcase

This commit is contained in:
Aman Varshney
2025-03-23 18:00:26 +05:30
parent c605c7c075
commit ed401d01e9
9 changed files with 261 additions and 262 deletions

View File

@@ -2,8 +2,8 @@ const PackageIcon = ({ pm, className }: { pm: string; className?: string }) => {
switch (pm) {
case "npm":
return (
// biome-ignore lint/a11y/noSvgWithoutTitle: <explanation>
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
<title>npm</title>
<path d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l13.837.019-.009 13.836h-3.464l.01-10.382h-3.456L12.04 19.17H5.113z" />
</svg>
);

View File

@@ -62,7 +62,7 @@ const Navbar = () => {
<div className="flex justify-center">
<div
className={`flex items-center backdrop-blur-md bg-black/40 rounded-md border border-blue-500/30 py-1 px-1.5 text-sm relative transition-all duration-500 ease-out ${
scrolled ? "w-[280px]" : "sm:w-[180px] w-[180px]"
scrolled ? "w-[342px]" : "sm:w-[240px] w-[280px]"
}`}
>
<div
@@ -92,6 +92,18 @@ const Navbar = () => {
<PackageIcon pm="github" className="w-4 h-4" />{" "}
<span className="max-sm:hidden">github</span>
</Link> */}
<Link
href="https://my-better-t-app-client.pages.dev/"
target="_blank"
ref={(ref) => {
linkRefs.current.demo = ref;
}}
onMouseOver={() => setActiveLink("demo")}
onMouseLeave={() => setActiveLink("home")}
className="text-gray-300 hidden hover:text-blue-300 transition-colors py-2 px-4 rounded-md relative sm:flex gap-2 items-center font-mono"
>
<span>demo</span>
</Link>
<Link
href="https://www.npmjs.com/package/create-better-t-stack"
target="_blank"
@@ -105,6 +117,7 @@ const Navbar = () => {
<PackageIcon pm="npm" className="w-4 h-4 rounded-full" />{" "}
<span>npm</span>
</Link>
{/* <span
className="text-blue-500 transition-all duration-300"
style={{
@@ -149,7 +162,7 @@ const Navbar = () => {
}`}
>
<PackageIcon pm="github" className="w-4 h-4" />{" "}
<span className="max-sm:hidden">github</span>
<span className="">github</span>
</Link>
</div>
</div>

View File

@@ -103,7 +103,6 @@ export default function TechMatrix() {
const [isTyping, setIsTyping] = useState(false);
const fullCommand = "show tech-stack --category all";
// biome-ignore lint/correctness/useExhaustiveDependencies: <explanation>
useEffect(() => {
if (isTyping) return;
@@ -120,7 +119,7 @@ export default function TechMatrix() {
}, 80);
return () => clearInterval(typeInterval);
}, []);
}, [isTyping]);
const categories = Array.from(
new Set(techStack.map((item) => item.category)),
@@ -199,8 +198,7 @@ export default function TechMatrix() {
<div className="font-mono text-sm text-gray-300 mb-6 flex items-center">
<span className="text-green-400 mr-2">$</span>
<span>{typedCommand}</span>
{/* biome-ignore lint/style/useSelfClosingElements: <explanation> */}
<span className="h-4 w-2 bg-gray-400 animate-blink ml-1"></span>
<span className="h-4 w-2 bg-gray-400 animate-blink ml-1" />
</div>
{/* Category filters */}
@@ -210,10 +208,9 @@ export default function TechMatrix() {
animate={{ opacity: 1 }}
transition={{ delay: 0.3, duration: 0.5 }}
>
{/* biome-ignore lint/style/useSelfClosingElements: <explanation> */}
<div className="absolute inset-0 -m-2 bg-gradient-to-r from-blue-500/0 via-blue-500/5 to-purple-500/0 rounded-lg blur-md -z-10"></div>
{/* biome-ignore lint/a11y/useButtonType: <explanation> */}
<div className="absolute inset-0 -m-2 bg-gradient-to-r from-blue-500/0 via-blue-500/5 to-purple-500/0 rounded-lg blur-md -z-10" />
<button
type="button"
className={`px-3 py-1 text-xs font-mono rounded-md transition-all duration-300 ${
!selectedCategory
? "bg-blue-500/20 text-blue-300 border border-blue-500/30 shadow-[0_0_10px_rgba(59,130,246,0.3)]"
@@ -225,8 +222,8 @@ export default function TechMatrix() {
</button>
{categories.map((category) => (
// biome-ignore lint/a11y/useButtonType: <explanation>
<button
type="button"
key={category}
className={`px-3 py-1 text-xs font-mono rounded-md transition-all duration-300 ${
selectedCategory === category
@@ -249,10 +246,10 @@ export default function TechMatrix() {
}}
/>
{/* biome-ignore lint/style/noUnusedTemplateLiteral: <explanation> */}
<div className="text-blue-400 mb-4">{`// Better-T Stack Tech Matrix`}</div>
{/* biome-ignore lint/style/noUnusedTemplateLiteral: <explanation> */}
<div className="text-purple-400">{`const techStack = {`}</div>
<div className="text-blue-400 mb-4">
{"// Better-T Stack Tech Matrix"}
</div>
<div className="text-purple-400">{"const techStack = {"}</div>
<AnimatePresence mode="wait">
<motion.div
@@ -329,8 +326,7 @@ export default function TechMatrix() {
</motion.div>
</AnimatePresence>
{/* biome-ignore lint/style/noUnusedTemplateLiteral: <explanation> */}
<div className="text-purple-400">{`};`}</div>
<div className="text-purple-400">{"};"}</div>
{/* Terminal footer */}
<div className="mt-6 text-gray-400 border-t border-gray-800/50 pt-4 flex items-center justify-between">

View File

@@ -4,39 +4,28 @@ import React, { useState } from "react";
interface TechItem {
name: string;
description: string;
category:
| "frontend"
| "backend"
| "database"
| "tooling"
| "deployment"
| "core";
category: "frontend" | "backend" | "database" | "tooling" | "core";
}
const techStack: TechItem[] = [
{
name: "Bun",
description: "Fast all-in-one JavaScript runtime",
category: "core",
},
{
name: "TypeScript",
description: "Type safety across the stack",
description: "Type safety across the entire stack",
category: "core",
},
{
name: "tRPC",
description: "End-to-end type-safe APIs",
category: "core",
},
{
name: "React (Vite)",
name: "React",
description: "JavaScript library for user interfaces",
category: "frontend",
},
{
name: "TanStack Router",
description: "Type-safe routing",
description: "Type-safe routing with file-based routes",
category: "frontend",
},
{
name: "TanStack Query",
description: "Powerful data synchronization",
category: "frontend",
},
{
@@ -46,7 +35,7 @@ const techStack: TechItem[] = [
},
{
name: "shadcn/ui",
description: "Re-usable components",
description: "Re-usable UI components",
category: "frontend",
},
{
@@ -54,6 +43,11 @@ const techStack: TechItem[] = [
description: "Ultrafast web framework",
category: "backend",
},
{
name: "tRPC",
description: "End-to-end type-safe APIs",
category: "backend",
},
{
name: "Better-Auth",
description: "Modern authentication solution",
@@ -61,7 +55,7 @@ const techStack: TechItem[] = [
},
{
name: "Drizzle ORM",
description: "TypeScript ORM",
description: "TypeScript-first ORM",
category: "database",
},
{
@@ -70,10 +64,45 @@ const techStack: TechItem[] = [
category: "database",
},
{
name: "libSQL",
description: "SQLite-compatible database engine",
name: "SQLite + Turso",
description: "Serverless SQLite with edge replication",
category: "database",
},
{
name: "PostgreSQL",
description: "Advanced open-source relational database",
category: "database",
},
{
name: "Biome",
description: "Fast formatter and linter",
category: "tooling",
},
{
name: "Husky",
description: "Git hooks made easy",
category: "tooling",
},
{
name: "PWA",
description: "Progressive Web App support",
category: "tooling",
},
{
name: "Tauri",
description: "Build desktop and mobile apps with web tech",
category: "tooling",
},
{
name: "Docker",
description: "Containerized deployments",
category: "tooling",
},
{
name: "Turborepo",
description: "Optimized build system for monorepos",
category: "core",
},
];
const categoryIcons = {
@@ -81,8 +110,7 @@ const categoryIcons = {
backend: "⚙️",
database: "🗄️",
tooling: "🔧",
deployment: "🚀",
core: "🔑",
core: "",
};
export default function TechShowcase() {
@@ -106,8 +134,8 @@ export default function TechShowcase() {
return (
<section className="w-full max-w-6xl mx-auto py-16 px-4">
<div className="mb-8 flex flex-wrap justify-center gap-3">
{/* biome-ignore lint/a11y/useButtonType: <explanation> */}
<button
type="button"
className={`px-4 py-2 rounded-md font-mono text-sm transition-colors ${
activeCategory === null
? "bg-blue-500 text-white"
@@ -119,9 +147,9 @@ export default function TechShowcase() {
</button>
{categories.map((category) => (
// biome-ignore lint/a11y/useButtonType: <explanation>
<button
key={category}
type="button"
className={`px-4 py-2 rounded-md font-mono text-sm transition-colors ${
activeCategory === category
? "bg-blue-500 text-white"
@@ -149,7 +177,20 @@ export default function TechShowcase() {
</h3>
<p className="text-gray-400 text-sm">{tech.description}</p>
<div className="mt-3 text-xs text-gray-500 font-mono">
<code>--package={tech.name.toLowerCase()}</code>
{tech.category === "tooling" || tech.category === "database" ? (
<span>
{tech.name === "Drizzle ORM" ||
tech.name === "Prisma" ||
tech.name === "SQLite + Turso" ||
tech.name === "PostgreSQL" ? (
<code>--{tech.name.toLowerCase().split(" ")[0]}</code>
) : (
<code>--{tech.name.toLowerCase()}</code>
)}
</span>
) : (
<span>Included by default</span>
)}
</div>
</motion.div>
))}
@@ -183,7 +224,10 @@ export default function TechShowcase() {
{tech.name}
</h3>
<div className="bg-gray-800 px-2 py-1 rounded text-xs font-mono text-gray-400">
core
{group.category === "tooling" ||
tech.category === "database"
? "optional"
: "core"}
</div>
</div>
<p className="text-gray-400 text-sm mt-2">
@@ -191,10 +235,19 @@ export default function TechShowcase() {
</p>
<div className="mt-3 pt-2 border-t border-gray-800 flex items-center justify-between">
<span className="text-xs text-gray-500 font-mono">
include: true
{group.category === "tooling" ||
tech.category === "database"
? tech.name === "Drizzle ORM" ||
tech.name === "Prisma" ||
tech.name === "SQLite + Turso" ||
tech.name === "PostgreSQL"
? `--${tech.name.toLowerCase().split(" ")[0]}`
: `--${tech.name.toLowerCase()}`
: "included by default"}
</span>
{/* biome-ignore lint/style/useSelfClosingElements: <explanation> */}
<span className="h-2 w-2 bg-green-500 rounded-full"></span>
<span
className={`h-2 w-2 ${group.category === "tooling" || tech.category === "database" ? "bg-yellow-500" : "bg-green-500"} rounded-full`}
/>
</div>
</motion.div>
))}
@@ -207,9 +260,8 @@ export default function TechShowcase() {
<div className="mt-10 text-center">
<div className="inline-block bg-gray-900/50 backdrop-blur-sm border border-gray-800 rounded-md px-5 py-3 font-mono text-sm text-gray-400">
<span className="text-green-400">$</span> The perfect tech stack,
carefully selected for{" "}
<span className="text-blue-400">maximum developer happiness</span>
<span className="text-green-400">$</span> npx create-better-t-stack
<span className="text-blue-400"> your-options</span>
</div>
</div>
</section>