import { Button } from "@/components/ui/button";
import { supabaseEnv } from "@/lib/supabase";
import { Check, Copy, Database } from "lucide-react";
import { useState } from "react";
const ENV_TEMPLATE = `VITE_SUPABASE_URL=http://127.0.0.1:54321
VITE_SUPABASE_ANON_KEY=your-anon-key-here`;
function CodeBlock({ code }: { code: string }) {
const [copied, setCopied] = useState(false);
const copy = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
return (
<div className="relative group">
<pre className="bg-zinc-900 text-zinc-100 rounded-md p-4 text-xs overflow-x-auto font-mono">
<code>{code}</code>
</pre>
<Button
type="button"
size="sm"
variant="secondary"
onClick={copy}
className="absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition"
>
{copied ? <Check /> : <Copy />}
{copied ? "Copied" : "Copy"}
</Button>
</div>
);
}
function Step({
n,
title,
children,
}: {
n: number;
title: string;
children: React.ReactNode;
}) {
return (
<div className="flex gap-4">
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-primary text-primary-foreground flex items-center justify-center text-sm font-semibold">
{n}
</div>
<div className="flex-1 space-y-2 pt-0.5">
<h3 className="font-semibold text-base">{title}</h3>
<div className="text-sm text-muted-foreground space-y-2">{children}</div>
</div>
</div>
);
}
export default function SetupGuide() {
const missing = [
!supabaseEnv.url && "VITE_SUPABASE_URL",
!supabaseEnv.anonKey && "VITE_SUPABASE_ANON_KEY",
].filter(Boolean) as string[];
return (
<div className="min-h-screen bg-background text-foreground">
<div className="max-w-2xl mx-auto px-6 py-12 space-y-8">
<header className="space-y-3">
<div className="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-amber-100 text-amber-900 text-xs font-medium">
<Database className="size-3.5" />
Setup required
</div>
<h1 className="text-3xl font-bold tracking-tight">Supabase is not configured</h1>
<p className="text-muted-foreground">
Missing environment variables:{" "}
{missing.map((m, i) => (
<span key={m}>
<code className="font-mono text-xs px-1.5 py-0.5 rounded bg-muted text-foreground">
{m}
</code>
{i < missing.length - 1 ? ", " : ""}
</span>
))}
</p>
</header>
<div className="space-y-8">
<Step n={1} title="Start the local Supabase stack">
<p>Make sure Docker is running, then start Supabase:</p>
<CodeBlock code="supabase start" />
<p>
The first run downloads images and may take a minute. When it finishes, the URL and
anon key are printed in the terminal.
</p>
</Step>
<Step n={2} title="Create .env.local in the project root">
<p>
Copy the values from the <code className="font-mono">supabase start</code> output into
a file named <code className="font-mono">.env.local</code>:
</p>
<CodeBlock code={ENV_TEMPLATE} />
</Step>
<Step n={3} title="Restart the dev server">
<p>Vite reads env files at startup. Stop the dev server (Ctrl+C) and run it again:</p>
<CodeBlock code="pnpm dev" />
</Step>
</div>
<footer className="pt-6 border-t text-xs text-muted-foreground">
Bootstrapped with Devist ยท react-supabase template
</footer>
</div>
</div>
);
}