Seed: dashboard template (24 files)

This commit is contained in:
2026-07-23 22:10:41 +00:00
parent 97a242d12f
commit 6894be2d41
+73
View File
@@ -0,0 +1,73 @@
import { useState } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Activity } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useAuth } from "@/hooks/use-tygarun";
import IndexPage from "@/pages/Index";
import AnalyticsPage from "@/pages/Analytics";
import UsersPage from "@/pages/Users";
import SettingsPage from "@/pages/Settings";
import ReportsPage from "@/pages/Reports";
import ProfilePage from "@/pages/Profile";
// Auth gate: when tyga.run is connected, require a real sign-in before the
// dashboard renders. In demo/seed mode (not connected) the dashboard stays
// fully walkable so the template previews without a backend.
function AuthGate({ children }: { children: React.ReactNode }) {
const { isSignedIn, connected, signin, loading, error } = useAuth();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
if (!connected || isSignedIn) return <>{children}</>;
const handleSignin = async (e: React.FormEvent) => {
e.preventDefault();
try { await signin(email, password); } catch { /* error surfaced below */ }
};
return (
<div className="min-h-screen flex items-center justify-center bg-slate-900 px-6">
<form onSubmit={handleSignin} className="w-full max-w-sm bg-slate-800/60 border border-slate-700 rounded-2xl p-8 space-y-5">
<div className="flex items-center gap-3">
<div className="h-9 w-9 rounded-xl bg-sky-500 flex items-center justify-center">
<Activity className="h-5 w-5 text-white" />
</div>
<h1 className="text-lg font-bold text-white">Sign in to continue</h1>
</div>
<div className="space-y-2">
<Label htmlFor="email" className="text-slate-300">Email</Label>
<Input id="email" type="email" required value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" />
</div>
<div className="space-y-2">
<Label htmlFor="password" className="text-slate-300">Password</Label>
<Input id="password" type="password" required value={password} onChange={(e) => setPassword(e.target.value)} placeholder="••••••••" />
</div>
{error && <p className="text-sm text-red-400">{error}</p>}
<Button type="submit" disabled={loading} className="w-full">
{loading ? "Signing in…" : "Sign In"}
</Button>
</form>
</div>
);
}
function App() {
return (
<BrowserRouter>
<AuthGate>
<Routes>
<Route path="/" element={<IndexPage />} />
<Route path="/analytics" element={<AnalyticsPage />} />
<Route path="/users" element={<UsersPage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/reports" element={<ReportsPage />} />
<Route path="/profile" element={<ProfilePage />} />
</Routes>
</AuthGate>
</BrowserRouter>
);
}
export default App;