This repository was archived by the owner on Jun 19, 2025. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 232
Feature: Proposal for Enhanced 404.tsx: Search Bar, Interactive Animation, Recommended Links, Feedback Option, Easter Egg, and Theme Toggle #4196
Copy link
Copy link
Open
Labels
Description
Suggested solution
Suggested Features for 404.tsx File
Features to Add
- Search Bar for Navigation: Add an input field that allows users to search for content or pages.
- Interactive Animation or Illustration: Use a relevant SVG animation or Lottie file for visual engagement.
- Recommended Links or Categories: Provide links to popular sections like "Home," "About Us," or "Contact."
- Feedback Option: Include a button or modal for users to report the broken link.
- Fun Easter Egg or Game: Add a small JavaScript-based game (e.g., a simple clickable element challenge).
- Dark/Light Theme Toggle: Add a toggle button to switch between dark and light modes.
Enhanced Version of 404.tsx
import Link from "next/link";
import { useEffect, useState } from "react";
import FullHeightContainer from "components/atoms/FullHeightContainer/full-height-container";
import HeaderLogo from "components/molecules/HeaderLogo/header-logo";
import { useFetchTopContributors } from "lib/hooks/useFetchTopContributors";
import DevCardWall from "components/organisms/DevCardWall/dev-card-wall";
import BubbleBG from "../img/bubble-bg.svg";
import Lottie from "react-lottie";
import animationData from "../animations/404-animation.json";
export default function Custom404() {
const { data, isLoading } = useFetchTopContributors({ limit: 20 });
const [initialCardIndex, setInitialCardIndex] = useState<number | undefined>();
const [usernames, setUsernames] = useState<string[]>([]);
const [theme, setTheme] = useState<"dark" | "light">("dark");
const [searchQuery, setSearchQuery] = useState<string>("");
useEffect(() => {
setUsernames(data.map((user) => user.login));
if (!isLoading) {
setInitialCardIndex(0);
}
}, [data]);
const toggleTheme = () => setTheme(theme === "dark" ? "light" : "dark");
const defaultLottieOptions = {
loop: true,
autoplay: true,
animationData: animationData,
rendererSettings: {
preserveAspectRatio: "xMidYMid slice",
},
};
const handleFeedback = () => {
alert("Thank you for your feedback! We'll look into it.");
};
return (
<FullHeightContainer className={`text-white ${theme === "light" ? "bg-white text-black" : "bg-black"}`}>
<div
className="grid relative w-full h-full md:pb-20 overflow-hidden max-w-screen"
style={{
background: `#010101 url(${BubbleBG.src}) no-repeat center center`,
backgroundSize: "cover",
gridTemplateRows: "auto 1fr auto",
}}
>
<div className="grid items-center justify-center place-content-start py-7 px-4 z-50 md:grid-flow-col md:justify-between">
<HeaderLogo />
<button
onClick={toggleTheme}
className="ml-4 text-sm bg-gray-700 text-white px-3 py-1 rounded hover:bg-gray-600"
>
Toggle {theme === "dark" ? "Light" : "Dark"} Mode
</button>
</div>
<main id="main" className="grid md:grid-cols-2 place-content-center py-6">
<div className="text-center px-6 relative z-10">
<h1 className="text-8xl font-bold mb-2">404</h1>
<div className="text-3xl mb-2">Uh oh! Page not found</div>
<div className="mb-2">
While you're here, you can check out some of our amazing contributors!
</div>
<div className="mb-4">
<input
type="text"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
placeholder="Search for a page..."
className="p-2 w-3/4 border rounded"
/>
</div>
<div className="mb-4">
<button
onClick={handleFeedback}
className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-500"
>
Report This Issue
</button>
</div>
<div className="mb-2">
<Link href="/" className="text-orange-600 hover:text-orange-500">
Take me home →
</Link>
</div>
<div className="text-lg mt-4">
Popular Links:
<ul className="list-disc list-inside text-left mx-auto mt-2">
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about">About Us</Link>
</li>
<li>
<Link href="/contact">Contact</Link>
</li>
</ul>
</div>
</div>
<div className="hidden md:grid relative">
<Lottie options={defaultLottieOptions} height={300} width={300} />
<div
className="grid absolute"
style={{
position: "absolute",
top: 0,
right: 0,
bottom: 0,
width: "50%",
}}
>
<DevCardWall usernames={usernames} isLoading={isLoading} initialCardIndex={initialCardIndex} />
</div>
</div>
</main>
<footer className="py-4 text-center">
<p>Can’t find what you’re looking for? Contact us for more help!</p>
</footer>
</div>
</FullHeightContainer>
);
}