diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index a676623..f2fac72 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -4,6 +4,7 @@ import { Features } from "@/components/sections/features"; import { Architecture } from "@/components/sections/architecture"; import { TechStack } from "@/components/sections/tech-stack"; import { Roadmap } from "@/components/sections/roadmap"; +import { AlgorithmChecklist } from "@/components/sections/algorithm-checklist"; import { FAQ } from "@/components/sections/faq"; import { OpenSource } from "@/components/sections/open-source"; import { Footer } from "@/components/sections/footer"; @@ -24,6 +25,7 @@ export default function Home() { + diff --git a/apps/web/src/components/animations/array-search.tsx b/apps/web/src/components/animations/array-search.tsx index 0285ed0..689a89b 100644 --- a/apps/web/src/components/animations/array-search.tsx +++ b/apps/web/src/components/animations/array-search.tsx @@ -3,17 +3,40 @@ import { motion } from "framer-motion"; import { useEffect, useState } from "react"; -const array = [2, 5, 8, 11, 12, 16, 23, 28, 38, 56, 60, 67, 72, 81, 91, 99, 123, 212]; +const DESKTOP_ARRAY = [2, 5, 8, 11, 12, 16, 23, 28, 38, 56, 60, 67, 72, 81, 91, 99, 123, 212]; +const MOBILE_ARRAY = [67, 69, 70, 77, 81, 98]; export function ArraySearch() { + const [array, setArray] = useState(DESKTOP_ARRAY); const target = 67; const [currentIndex, setCurrentIndex] = useState(-1); const [left, setLeft] = useState(0); - const [right, setRight] = useState(array.length - 1); + const [right, setRight] = useState(DESKTOP_ARRAY.length - 1); const [found, setFound] = useState(false); + // Handle responsive array useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 768) { + setArray(MOBILE_ARRAY); + } else { + setArray(DESKTOP_ARRAY); + } + }; + + // Initial check + handleResize(); + + window.addEventListener("resize", handleResize); + return () => window.removeEventListener("resize", handleResize); + }, []); + + useEffect(() => { + let isCancelled = false; + const animateBinarySearch = async () => { + if (isCancelled) return; + setCurrentIndex(-1); setLeft(0); setRight(array.length - 1); @@ -23,6 +46,8 @@ export function ArraySearch() { let r = array.length - 1; while (l <= r) { + if (isCancelled) return; + const mid = Math.floor((l + r) / 2); setCurrentIndex(mid); setLeft(l); @@ -39,14 +64,19 @@ export function ArraySearch() { } } - await new Promise((resolve) => setTimeout(resolve, 2500)); + if (!isCancelled) { + await new Promise((resolve) => setTimeout(resolve, 2500)); + } }; const interval = setInterval(animateBinarySearch, 8000); animateBinarySearch(); - return () => clearInterval(interval); - }, []); + return () => { + isCancelled = true; + clearInterval(interval); + }; + }, [array]); // Restart animation when array changes return (
@@ -58,7 +88,7 @@ export function ArraySearch() { return ( t.implemented).length; + + return ( +
+ + + + {isOpen && ( + + {topics.map((item, index) => ( +
+ + + {index === topics.length - 1 ? "└─" : "├─"} + + {item.name} + + + {item.implemented ? ( + + ) : ( + + )} + +
+ ))} +
+ )} +
+
+ ); +} + +interface CategorySectionProps { + category: Category; + visible: boolean; + setVisible: (visible: boolean) => void; +} + +function CategorySection({ category, visible, setVisible }: CategorySectionProps) { + const { total, implemented } = getCategoryCount(category); + + return ( +
+ + + + {visible && ( + + {Object.entries(category.items).map(([topic, { topics }]) => ( + + ))} + + )} + +
+ ); +} + +export function AlgorithmChecklist() { + const [dsVisible, setDsVisible] = useState(true); + const [algoVisible, setAlgoVisible] = useState(true); + const { total, implemented } = getTotalCount(); + const progress = Math.round((implemented / total) * 100); + + return ( +
+ {/* Background */} +
+
+
+ + {/* Noise overlay */} +
+
+
+ +
+ {/* Section header */} + +
+ + / Implementation Roadmap +
+ +

+ THE AMBITIOUS LIST +

+ +

+ {total}+ algorithms and data structures. This is what we're building together. + Pick one and contribute, or suggest new ones. ML/DL, algorithms from other fields, and visualizers are all welcome. +

+ + {/* Progress bar */} +
+
+ Progress + {implemented}/{total} ({progress}%) +
+
+ +
+
+
+ + {/* Terminal-style container */} + + {/* Terminal header */} +
+
+
+
+
+
+
+ +
+ + opendsa@roadmap ~ $ + +
+ + {/* Terminal content */} +
+ {/* Header banner */} +
+
+ + OpenDSA Implementation Roadmap + +
+

+ Click on any category to expand/collapse +

+
+ + {/* Two columns */} +
+
+ +
+ +
+ +
+
+ + {/* Legend */} +
+ Status: + + Implemented + + + Pending + +
+ + {/* Cursor */} +
+ $ + +
+
+ + + {/* Future plans */} + +

+ Open to Contributions:{" "} + Machine Learning & Deep Learning Algorithm Visualizers etc... +

+
+
+
+ ); +} diff --git a/apps/web/src/components/sections/footer.tsx b/apps/web/src/components/sections/footer.tsx index 14cf254..9919bad 100644 --- a/apps/web/src/components/sections/footer.tsx +++ b/apps/web/src/components/sections/footer.tsx @@ -20,6 +20,7 @@ const footerLinks = { { label: "GitHub", href: "https://github.com/soloshun/opendsa" }, { label: "Discord", href: "#" }, { label: "Twitter", href: "#" }, + { label: "Support Us ☕", href: "https://docs.opendsa.dev/sponsors" }, ], }; @@ -46,10 +47,10 @@ export function Footer() { {/* Gradient from bottom */}
- + {/* Background */}
- + {/* Noise overlay */}
diff --git a/apps/web/src/components/sections/header.tsx b/apps/web/src/components/sections/header.tsx index 59b70c7..e453214 100644 --- a/apps/web/src/components/sections/header.tsx +++ b/apps/web/src/components/sections/header.tsx @@ -1,14 +1,19 @@ "use client"; import { motion } from "framer-motion"; -import { Github, Menu, X, Sun } from "lucide-react"; +import { + Github, + Menu, + X, + // Sun +} from "lucide-react"; import Link from "next/link"; import { useState } from "react"; const navLinks = [ { href: "#features", label: "Features" }, { href: "#roadmap", label: "Roadmap" }, - { href: "#open-source", label: "Open Source" }, + // { href: "#open-source", label: "Open Source" }, { href: "https://docs.opendsa.dev", label: "Docs", external: true }, ]; @@ -20,7 +25,7 @@ export function Header() { initial={{ y: -100, opacity: 0 }} animate={{ y: 0, opacity: 1 }} transition={{ duration: 0.6, ease: "easeOut" }} - className="fixed top-4 left-1/2 -translate-x-1/2 z-50 w-[95%] max-w-5xl" + className="fixed top-4 left-1/2 -translate-x-1/2 z-50 w-[95%] max-w-6xl" > {/* Main nav container - rounded pill style */}