diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx index ff9d3ca..8e21eea 100644 --- a/apps/web/src/routes/index.tsx +++ b/apps/web/src/routes/index.tsx @@ -1,50 +1,402 @@ import { useQuery } from "@tanstack/react-query"; -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, Link } from "@tanstack/react-router"; +import { + AudioLines, + Brain, + Image as ImageIcon, + Lock, + Network, + Search, + Sparkles, +} from "lucide-react"; +import type { ComponentType } from "react"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; import { trpc } from "@/utils/trpc"; export const Route = createFileRoute("/")({ component: HomeComponent, }); -const TITLE_TEXT = ` - ██████╗ ███████╗████████╗████████╗███████╗██████╗ - ██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗ - ██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝ - ██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗ - ██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║ - ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝ - - ████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗ - ╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝ - ██║ ███████╗ ██║ ███████║██║ █████╔╝ - ██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗ - ██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗ - ╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ - `; - -function HomeComponent() { +function HealthBadge() { const healthCheck = useQuery(trpc.healthCheck.queryOptions()); - + const status = healthCheck.isLoading + ? "Checking" + : healthCheck.data + ? "Online" + : "Offline"; + const color = healthCheck.isLoading + ? "bg-yellow-500" + : healthCheck.data + ? "bg-emerald-500" + : "bg-red-500"; return ( -
-
{TITLE_TEXT}
-
-
-

API Status

-
-
- - {healthCheck.isLoading - ? "Checking..." - : healthCheck.data - ? "Connected" - : "Disconnected"} - +
+ + API {status} +
+ ); +} + +function PreviewCard() { + return ( + + +
+ {/* window chrome */} +
+
+ + + +
+
+ reflecto.app +
-
+ {/* fake content */} +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + ); +} + +type Feature = { + key: string; + title: string; + desc: string; + icon: ComponentType<{ className?: string }>; + from: string; // e.g., from-purple-500/40 + to: string; // e.g., to-fuchsia-500/30 +}; + +function FeatureTile({ feature }: { feature: Feature }) { + const Icon = feature.icon; + return ( +
+
+
+
+ +
+
+
{feature.title}
+
{feature.desc}
+
+
+
); } + +function StepCard({ step }: { step: Step }) { + return ( +
+ {/* Card */} +
+ {/* Gradient accent */} +
+ + {/* Content */} +
+ {/* Step number */} +
+ + {step.n} + +
+ + {/* Title */} +

{step.title}

+ + {/* Description */} +

{step.desc}

+
+ + {/* Hover glow effect */} +
+
+
+ ); +} + +type Step = { + n: number; + title: string; + desc: string; + gradient: string; +}; + +function HowItWorks() { + const STEPS: Step[] = [ + { + n: 1, + title: "Capture", + desc: "Upload images, record audio, or paste text. Your thoughts, instantly digitized.", + gradient: "bg-gradient-to-br from-blue-500/20 to-cyan-500/20", + }, + { + n: 2, + title: "Extract", + desc: "Advanced OCR and speech-to-text automatically convert everything into searchable text.", + gradient: "bg-gradient-to-br from-purple-500/20 to-pink-500/20", + }, + { + n: 3, + title: "Organize", + desc: "AI intelligently tags and creates connections between your ideas in visual Spaces.", + gradient: "bg-gradient-to-br from-green-500/20 to-emerald-500/20", + }, + { + n: 4, + title: "Discover", + desc: "Find anything instantly with powerful full-text search across your entire knowledge base.", + gradient: "bg-gradient-to-br from-orange-500/20 to-yellow-500/20", + }, + ]; + + return ( +
+ {/* Desktop layout */} +
+ {STEPS.map((step) => ( + + ))} +
+ + {/* Mobile layout */} +
+ {STEPS.map((step) => ( + + ))} +
+
+ ); +} + +const FEATURES: Feature[] = [ + { + key: "ingestion", + title: "Ingestion", + desc: "Upload images and voice notes. OCR and speech‑to‑text run automatically.", + icon: ImageIcon, + from: "from-purple-500/40", + to: "to-fuchsia-500/30", + }, + { + key: "ai", + title: "AI Processing", + desc: "We extract text and metadata into a structured store for fast retrieval.", + icon: Brain, + from: "from-indigo-500/40", + to: "to-violet-500/30", + }, + { + key: "spaces", + title: "Spaces Graph", + desc: "Discover AI‑suggested relationships and navigate ideas visually.", + icon: Network, + from: "from-cyan-500/40", + to: "to-emerald-500/30", + }, + { + key: "search", + title: "Full‑text Search", + desc: "Find anything with keywords across your entire second brain.", + icon: Search, + from: "from-emerald-500/40", + to: "to-lime-500/30", + }, + { + key: "secure", + title: "Secure & Private", + desc: "Your data is yours—authentication and storage are handled securely.", + icon: Lock, + from: "from-rose-500/40", + to: "to-pink-500/30", + }, + { + key: "voice", + title: "Voice‑first", + desc: "Capture thoughts hands‑free and let Reflecto do the rest.", + icon: AudioLines, + from: "from-amber-500/40", + to: "to-orange-500/30", + }, +]; + +function HomeComponent() { + return ( +
+ {/* Background aesthetics */} +
+ {/* aurora blobs */} +
+
+
+ {/* dotted grid overlay */} +
+
+ + {/* Hero */} +
+
+ +

+ Reflecto +

+

+ Your AI‑powered second brain. Capture voice, images, and + text—Reflecto turns it into a searchable, connected knowledge base. +

+
+ + +
+
+ Reflecto + Private by default • Powered by lightweight AI +
+
+ {/* Showcase preview */} +
+ +
+
+ + {/* Features */} +
+ {/* quick stats */} +
+ {[ + { n: "2x", l: "Faster capture" }, + { n: "100%", l: "Private by default" }, + { n: "< 1s", l: "Search latency" }, + { n: "∞", l: "Ideas connected" }, + ].map((s) => ( +
+
{s.n}
+
{s.l}
+
+ ))} +
+
+ {FEATURES.map((f) => ( + + ))} +
+
+ + {/* How it works */} +
+
+
+ + How it works +
+

+ From chaos to clarity +

+

+ Transform scattered thoughts into organized knowledge in four + seamless steps. +

+
+ +
+ + {/* Call to action */} +
+
+
+
+

+ Build your second brain +

+

+ Start free. Your knowledge stays private. +

+
+
+ + +
+
+
+
+ + {/* Footer */} + +
+ ); +}