feat: overhaul landing page with demo gallery, preview mockup, and fix links
- Add 'Featured Examples' section with 6 popular repos (express, flask, zod, etc.) - Add browser window mockup in hero showing what generated docs look like - Fix all links: company.repi.fun → vectry.tech, github.com → gitea.repi.fun - Update stats: ~3 min generation, 10+ languages supported - New ExampleRepos client component with generate-on-click functionality
This commit is contained in:
96
apps/web/src/components/example-repo-card.tsx
Normal file
96
apps/web/src/components/example-repo-card.tsx
Normal file
@@ -0,0 +1,96 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { ArrowRight, Loader2 } from "lucide-react";
|
||||
|
||||
interface ExampleRepo {
|
||||
name: string;
|
||||
description: string;
|
||||
language: string;
|
||||
languageColor: string;
|
||||
}
|
||||
|
||||
interface ExampleRepoCardProps {
|
||||
repo: ExampleRepo;
|
||||
}
|
||||
|
||||
export function ExampleRepoCard({ repo }: ExampleRepoCardProps) {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
const handleGenerate = async () => {
|
||||
const repoUrl = `https://github.com/${repo.name}`;
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const response = await fetch("/api/generate", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ repoUrl }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const data = await response.json();
|
||||
throw new Error(data.error || "Failed to start generation");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
router.push(`/generate?repo=${encodeURIComponent(repoUrl)}&id=${data.id}`);
|
||||
} catch (err) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="group relative p-6 rounded-2xl glass hover:bg-white/[0.05] transition-all duration-300 hover:-translate-y-1 hover:shadow-2xl hover:shadow-blue-500/10">
|
||||
<div className="absolute inset-0 rounded-2xl bg-gradient-to-r from-blue-500/20 via-indigo-500/20 to-purple-500/20 opacity-0 group-hover:opacity-100 transition-opacity -z-10 blur-xl" />
|
||||
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div
|
||||
className="flex items-center gap-2 px-3 py-1 rounded-full text-xs font-medium"
|
||||
style={{
|
||||
backgroundColor: `${repo.languageColor}20`,
|
||||
color: repo.languageColor,
|
||||
border: `1px solid ${repo.languageColor}40`,
|
||||
}}
|
||||
>
|
||||
<span
|
||||
className="w-2 h-2 rounded-full"
|
||||
style={{ backgroundColor: repo.languageColor }}
|
||||
/>
|
||||
{repo.language}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 className="text-lg font-semibold text-white mb-2 group-hover:text-blue-300 transition-colors font-mono">
|
||||
{repo.name}
|
||||
</h3>
|
||||
|
||||
<p className="text-sm text-zinc-400 mb-6 leading-relaxed line-clamp-2">
|
||||
{repo.description}
|
||||
</p>
|
||||
|
||||
<button
|
||||
onClick={handleGenerate}
|
||||
disabled={isLoading}
|
||||
className="w-full flex items-center justify-center gap-2 px-4 py-3 rounded-xl text-sm font-medium transition-all duration-200
|
||||
bg-gradient-to-r from-blue-600/20 to-indigo-600/20 hover:from-blue-600 hover:to-indigo-600
|
||||
border border-blue-500/30 hover:border-transparent text-blue-300 hover:text-white
|
||||
disabled:opacity-50 disabled:cursor-not-allowed group/btn"
|
||||
>
|
||||
{isLoading ? (
|
||||
<>
|
||||
<Loader2 className="w-4 h-4 animate-spin" />
|
||||
<span>Starting...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span>Generate Docs</span>
|
||||
<ArrowRight className="w-4 h-4 group-hover/btn:translate-x-1 transition-transform" />
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user