diff --git a/app/page.tsx b/app/page.tsx index 870ceae..4c6b731 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -50,6 +50,12 @@ export default function Home() { > Docs + + Roadmap + diff --git a/app/roadmap/page.tsx b/app/roadmap/page.tsx new file mode 100644 index 0000000..0512157 --- /dev/null +++ b/app/roadmap/page.tsx @@ -0,0 +1,114 @@ +import type { Metadata } from "next"; +import Link from "next/link"; +import { Globe, Map, Info } from "lucide-react"; +import { ThemeToggle } from "@/components/theme-toggle"; +import { RoadmapFlowchart } from "@/components/roadmap-flowchart"; +import { Badge } from "@/components/ui/badge"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, +} from "@/components/ui/card"; + +export const metadata: Metadata = { + title: "Roadmap", + description: "Visual roadmap and development phases for VectorDNS.", +}; + +export default function RoadmapPage() { + return ( +
+ {/* Header */} +
+
+ + + + VectorDNS + + +
+ + Docs + + + Roadmap + + +
+
+
+ +
+
+ {/* Page Header */} +
+ + + Project Roadmap + +

+ Building the Future of{" "} + DNS Monitoring +

+

+ Follow our journey from foundation to a full-featured domain + toolkit. Drag, zoom, and explore the development phases below. +

+
+ + {/* Interactive Flowchart */} +
+ +
+ + {/* Additional Context Cards */} +
+ + +
+ + Project Philosophy +
+ + VectorDNS is built on three core pillars: speed, accuracy, and + transparency. Every phase of our roadmap is designed to ensure + the highest quality data while maintaining a modern, + user-friendly experience. + +
+
+ + + Contributing + + We are currently in the early development stages. If + you're interested in contributing to the Go DNS API or + the Next.js frontend, please check out our GitHub repository + and open an issue or PR. + + + +
+
+
+ + {/* Footer */} +
+
+

© {new Date().getFullYear()} VectorDNS

+
+
+
+ ); +} diff --git a/components/docs/sidebar.tsx b/components/docs/sidebar.tsx index eb94a50..7930a6a 100644 --- a/components/docs/sidebar.tsx +++ b/components/docs/sidebar.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { usePathname } from "next/navigation"; import { + SquareKanban, BookOpen, Layers, ArrowRightLeft, @@ -13,6 +14,10 @@ import { } from "lucide-react"; const sections = [ + { + title: "Roadmap", + items: [{ title: "Project Roadmap", href: "/roadmap", icon: SquareKanban }], + }, { title: "Getting Started", items: [{ title: "Overview", href: "/docs", icon: BookOpen }], diff --git a/components/roadmap-flowchart.tsx b/components/roadmap-flowchart.tsx new file mode 100644 index 0000000..0fb7915 --- /dev/null +++ b/components/roadmap-flowchart.tsx @@ -0,0 +1,309 @@ +"use client"; + +import { + ReactFlow, + Background, + type Node, + type Edge, + type NodeProps, + Handle, + Position, + MarkerType, +} from "@xyflow/react"; +import "@xyflow/react/dist/style.css"; +import { + CheckCircle2, + Circle, + Flag, + Rocket, + Settings, + ShieldCheck, + Database, + Layout, + Activity, + TestTube, +} from "lucide-react"; + +type PhaseNodeData = { + label: string; + status: "todo" | "doing" | "done"; + icon: React.ElementType; + color: string; + items: { text: string; completed: boolean }[]; +}; + +function PhaseNode({ data }: NodeProps>) { + const Icon = data.icon; + return ( +
+ + + +
+
+ +
+
+
+ {data.label} +
+
+ {data.status} +
+
+
+ +
    + {data.items.map((item, i) => ( +
  • + {item.completed ? ( + + ) : ( + + )} + + {item.text} + +
  • + ))} +
+
+ ); +} + +const nodeTypes = { phase: PhaseNode }; + +const nodes: Node[] = [ + { + id: "p1", + type: "phase", + position: { x: 0, y: 0 }, + data: { + label: "Phase 1 — Foundation", + status: "todo", + icon: Database, + color: "#6366f1", + items: [ + { text: "TypeScript types", completed: false }, + { text: "Supabase schema & migrations", completed: false }, + { text: "Supabase client setup (@supabase/ssr)", completed: false }, + { text: "Project config & env setup", completed: false }, + ], + }, + }, + { + id: "p2", + type: "phase", + position: { x: 400, y: 0 }, + data: { + label: "Phase 2 — Core Services", + status: "todo", + icon: Settings, + color: "#8b5cf6", + items: [ + { text: "DNS service (tangerine)", completed: false }, + { text: "WHOIS service (whoiser)", completed: false }, + { text: "Availability service (IANA RDAP)", completed: false }, + { text: "Public lookup APIs", completed: false }, + { text: "Integration tests", completed: false }, + ], + }, + }, + { + id: "p3", + type: "phase", + position: { x: 800, y: 0 }, + data: { + label: "Phase 3 — Authentication", + status: "todo", + icon: ShieldCheck, + color: "#ec4899", + items: [ + { text: "Supabase Auth (GitHub, Google, Email)", completed: false }, + { text: "Auth server actions", completed: false }, + { text: "OAuth callback route", completed: false }, + { text: "Middleware protection", completed: false }, + { text: "Login/signup pages", completed: false }, + ], + }, + }, + { + id: "p4", + type: "phase", + position: { x: 0, y: 450 }, + data: { + label: "Phase 4 — Public UI", + status: "doing", + icon: Layout, + color: "#3b82f6", + items: [ + { text: "App shell layout", completed: false }, + { text: "Homepage Hero & Search", completed: true }, + { text: "DNS results page", completed: false }, + { text: "Save to Dashboard button", completed: false }, + ], + }, + }, + { + id: "p5", + type: "phase", + position: { x: 400, y: 450 }, + data: { + label: "Phase 5 — Dashboard", + status: "todo", + icon: Rocket, + color: "#06b6d4", + items: [ + { text: "Dashboard layout & stats", completed: false }, + { text: "Saved domains CRUD", completed: false }, + { text: "Domain detail page & history", completed: false }, + { text: "Notes & tags (auto-save)", completed: false }, + { text: "Manual re-check triggers", completed: false }, + ], + }, + }, + { + id: "p6", + type: "phase", + position: { x: 800, y: 450 }, + data: { + label: "Phase 6 — Monitoring & Alerts", + status: "todo", + icon: Activity, + color: "#10b981", + items: [ + { text: "Change detection logic", completed: false }, + { text: "Vercel Daily Cron job", completed: false }, + { text: "In-app notification system", completed: false }, + { text: "Email alerts via Resend", completed: false }, + ], + }, + }, + { + id: "p7", + type: "phase", + position: { x: 200, y: 900 }, + data: { + label: "Phase 7 — Settings & Polish", + status: "todo", + icon: Flag, + color: "#f59e0b", + items: [ + { text: "User profile & preferences", completed: false }, + { text: "Error boundaries & 404s", completed: false }, + { text: "Toast notifications (sonner)", completed: false }, + { text: "SEO & OG image generation", completed: false }, + ], + }, + }, + { + id: "p8", + type: "phase", + position: { x: 600, y: 900 }, + data: { + label: "Phase 8 — Testing & QA", + status: "todo", + icon: TestTube, + color: "#64748b", + items: [ + { text: "End-to-end integration tests", completed: false }, + { text: "Build verification (zero TS errors)", completed: false }, + { text: "Manual QA pass (Light/Dark mode)", completed: false }, + ], + }, + }, +]; + +const edges: Edge[] = [ + { + id: "e1-2", + source: "p1", + target: "p2", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8" }, + }, + { + id: "e2-3", + source: "p2", + target: "p3", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8" }, + }, + { + id: "e3-4", + source: "p3", + target: "p4", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8", strokeWidth: 2 }, + }, + { + id: "e4-5", + source: "p4", + target: "p5", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8" }, + }, + { + id: "e5-6", + source: "p5", + target: "p6", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8" }, + }, + { + id: "e6-7", + source: "p6", + target: "p7", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8", strokeWidth: 2 }, + }, + { + id: "e7-8", + source: "p7", + target: "p8", + markerEnd: { type: MarkerType.ArrowClosed, color: "#94a3b8" }, + style: { stroke: "#94a3b8" }, + }, +]; + +export function RoadmapFlowchart() { + return ( +
+ + + +
+ ); +}