Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions frontend/src/pages/GraphVisualizer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Play, Pause, RotateCcw, Zap, Settings, ChevronDown, ChevronUp, BookOpen, Network, Download, Search, Moon, Sun, User, Palette } from 'lucide-react';
import toast from 'react-hot-toast';
import { useTheme } from '../contexts/ThemeContext';
import { AlgorithmSettingsProvider } from '../contexts/AlgorithmSettingsContext';
import GraphCanvas from '../components/Graph/GraphCanvas';
import GraphInput from '../components/Graph/GraphInput';
import ControlPanel from '../components/Sorting/ControlPanel';
Expand Down Expand Up @@ -525,9 +526,10 @@ const GraphVisualizer = () => {
const [darkMode,setDarkMode]=useState(false);

return (
<div className={`min-h-screen transition-all duration-500 ${classes.bgGradient}`}>
{/* Conditional Particle Background */}
{showParticles && !timeoutDetected && (
<AlgorithmSettingsProvider>
<div className={`min-h-screen transition-all duration-500 ${classes.bgGradient}`}>
{/* Conditional Particle Background */}
{showParticles && !timeoutDetected && (
<canvas
ref={particleCanvasRef}
className="fixed inset-0 pointer-events-none z-0"
Expand Down Expand Up @@ -985,7 +987,8 @@ const GraphVisualizer = () => {
to { opacity: 1; transform: translateY(0); }
}
`}} />
</div>
</div>
</AlgorithmSettingsProvider>
);
};

Expand Down
169 changes: 132 additions & 37 deletions frontend/src/pages/NotFoundPage.jsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,144 @@
import { Link } from "react-router-dom";
import { AlertCircle, Cpu, ArrowLeft } from "lucide-react";
import { ArrowLeft, Home, BookOpen, GitBranch, Activity } from "lucide-react";
import { useTheme } from "../contexts/ThemeContext";
import { motion } from "framer-motion";
import { useState, useEffect } from "react";

const NotFoundPage = () => {
const { isDark, classes, getThemedGradient } = useTheme();
const { isDark, classes } = useTheme();
const [pathSearching, setPathSearching] = useState(true);

useEffect(() => {
const timer = setTimeout(() => setPathSearching(false), 3000);
return () => clearTimeout(timer);
}, []);

// Quick links for algorithm visualizer platform
const quickLinks = [
{ to: "/", icon: Home, label: "Home", color: "blue" },
{ to: "/sorting", icon: Activity, label: "Sorting Visualizer", color: "purple" },
{ to: "/graph", icon: GitBranch, label: "Graph Algorithms", color: "teal" },
{ to: "/tutorials", icon: BookOpen, label: "Tutorials", color: "green" },
];

return (
<div
className={`relative flex-1 flex flex-col items-center justify-center p-6 transition-all duration-500 ${classes.bgGradient} ${classes.textPrimary}`}
<main
role="main"
className={`min-h-[calc(100vh-80px)] flex items-center justify-center px-4 py-4 sm:px-6 sm:py-6 transition-all duration-500 ${classes.bgGradient} ${classes.textPrimary}`}
>
{/* Floating icons for tech vibe */}
<div className="absolute top-20 left-10 opacity-40 animate-bounce-slow">
<AlertCircle
className={`${classes.textSecondary} w-12 h-12`}
/>
</div>
<div className="absolute bottom-20 right-32 opacity-40 animate-spin-slow">
<Cpu
className={`${classes.textSecondary} w-20 h-20`}
/>
</div>
<div className="w-full max-w-4xl mx-auto">
<div className={`p-6 sm:p-8 md:p-10 rounded-2xl shadow-2xl ${classes.card}`}>
<motion.div
className="text-center space-y-5"
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
>
{/* 404 Title Section */}
<div className="space-y-2">
<motion.h1
className={`text-6xl sm:text-7xl font-extrabold ${classes.brandPrimary}`}
animate={{
scale: [1, 1.02, 1],
}}
transition={{
duration: 2,
repeat: Infinity,
ease: "easeInOut"
}}
>
404
</motion.h1>
<motion.div
className={`h-1.5 w-32 mx-auto rounded-full ${isDark ? 'bg-gradient-to-r from-blue-500 to-purple-500' : 'bg-gradient-to-r from-blue-600 to-purple-600'}`}
initial={{ width: 0, opacity: 0 }}
animate={{ width: 128, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.3 }}
/>
</div>

{/* Error Message Section */}
<div className="space-y-2 max-w-2xl mx-auto">
<h2 className={`text-xl sm:text-2xl font-bold ${classes.textPrimary}`}>
Path Not Found
</h2>
<p className={`text-sm sm:text-base ${classes.textSecondary} leading-relaxed`}>
{pathSearching
? "Searching through the algorithm tree..."
: "No valid path exists to this route. The algorithm couldn't find a solution here."}
</p>
<motion.p
className={`text-sm ${classes.textTertiary} font-mono italic`}
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.8 }}
>
Error Code: ROUTE_NOT_FOUND | Stack Trace: /404
</motion.p>
</div>

{/* Primary CTA Buttons */}
<div className="flex flex-col sm:flex-row gap-3 justify-center items-center">
<Link
to="/"
className={`${classes.btnPrimary} gap-2 min-w-[160px] justify-center`}
aria-label="Return to home page"
>
<ArrowLeft className="w-5 h-5" aria-hidden />
Back to Home
</Link>
<Link
to="/docs"
className={`${classes.btnSecondary} min-w-[160px] justify-center`}
>
<BookOpen className="w-5 h-5 inline mr-2" aria-hidden />
View Docs
</Link>
</div>

{/* Quick Navigation Section */}
<div className="pt-4 space-y-2.5">
<div className={`h-px w-full max-w-md mx-auto ${classes.borderPrimary}`} />
<p className={`text-xs sm:text-sm font-semibold ${classes.textSecondary}`}>
Explore Our Visualizers
</p>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-2 max-w-2xl mx-auto">
{quickLinks.map((link) => (
<Link
key={link.to}
to={link.to}
className={`flex items-center gap-2.5 p-2.5 rounded-lg border-2 transition-all duration-300 hover:scale-105 hover:shadow-lg ${
isDark
? 'border-gray-700 hover:border-blue-500 hover:bg-gray-800/70'
: 'border-gray-200 hover:border-blue-400 hover:bg-blue-50/50'
}`}
>
<div className={`p-1.5 rounded-lg ${isDark ? 'bg-gray-700' : 'bg-gray-100'}`}>
<link.icon className={`w-5 h-5 ${classes.brandPrimary}`} aria-hidden />
</div>
<span className={`text-sm font-semibold ${classes.textPrimary}`}>
{link.label}
</span>
</Link>
))}
</div>
</div>

{/* Main content */}
<div className="relative z-10 text-center max-w-xl">
<h1 className="text-7xl font-extrabold mb-4 animate-pulse">404</h1>
<p className="text-2xl mb-6">
Uh-oh! This algorithm didn't find a solution here.
</p>
<p className="text-lg mb-8">
Looks like this page isn't in the visualization. Try going back and
exploring!
</p>
<Link
to="/"
className={`inline-flex items-center gap-2 px-6 py-4 rounded-lg font-semibold shadow-lg transition-transform transform hover:scale-105 ${
isDark
? "bg-blue-600 hover:bg-blue-700 text-white"
: "bg-blue-500 hover:bg-blue-600 text-white"
}`}
>
<ArrowLeft className="w-5 h-5" />
Go Back to Visualizer
</Link>
{/* Bottom Hint */}
<motion.div
className="pt-3"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.6, delay: 1.2 }}
>
<p className={`text-sm ${classes.textTertiary}`}>
💡 Tip: Use breadth-first search to navigate back to familiar routes
</p>
</motion.div>
</motion.div>
</div>
</div>
</div>
</main>
);
};

Expand Down
Loading