Seed: dashboard template (24 files)
This commit is contained in:
+73
@@ -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;
|
||||
Reference in New Issue
Block a user