Skip to content

Commit c95067d

Browse files
authored
Merge pull request #42 from BeyteFlow/not-found-page
add error page
2 parents c77658a + 676657c commit c95067d

7 files changed

Lines changed: 309 additions & 94 deletions

File tree

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"eslint": "^9",
3434
"eslint-config-next": "16.1.6",
3535
"tailwindcss": "^4",
36+
"tailwindcss-animate": "^1.0.7",
3637
"typescript": "5.9.3",
3738
"vitest": "^4.0.18"
3839
}

src/app/error.tsx

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
"use client";
2+
3+
import React, { useEffect, useState } from "react";
4+
import {
5+
AlertCircle,
6+
RefreshCw,
7+
Home,
8+
Terminal,
9+
ShieldAlert,
10+
} from "lucide-react";
11+
import Link from "next/link";
12+
13+
interface ErrorProps {
14+
error?: Error & { digest?: string };
15+
reset?: () => void;
16+
}
17+
18+
// In this environment, the main component must be named App and be the default export
19+
export default function App({ error, reset }: ErrorProps) {
20+
const [errorTime] = useState(
21+
() => new Date().toISOString().split("T")[1].split(".")[0],
22+
);
23+
24+
useEffect(() => {
25+
if (error) {
26+
console.error("Captured Error:", error);
27+
}
28+
}, [error]);
29+
30+
// Fallback values in case props are undefined during a manual preview or direct render
31+
const errorMessage =
32+
error?.message || "An unexpected system interruption occurred.";
33+
const errorDigest = error?.digest || "N/A";
34+
const handleReset = reset || (() => window.location.reload());
35+
36+
return (
37+
<div className="min-h-screen bg-black text-white selection:bg-red-500/30 font-sans antialiased flex flex-col items-center justify-center relative overflow-hidden px-6">
38+
{/* Background Glows - Red/Amber for Error Context */}
39+
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] bg-red-500/10 rounded-full blur-[120px] pointer-events-none"></div>
40+
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-orange-500/5 rounded-full blur-[120px] pointer-events-none"></div>
41+
42+
<main className="z-10 flex flex-col items-center justify-center text-center max-w-4xl py-20">
43+
{/* Error Badge - Replicating the style from mainpage.png */}
44+
<div className="mb-8 flex items-center gap-2 px-3 py-1 rounded-full border border-red-500/20 bg-red-500/5 text-red-400 text-xs font-semibold uppercase tracking-wider animate-pulse">
45+
<AlertCircle size={14} />
46+
Runtime Exception Detected
47+
</div>
48+
49+
{/* Hero Title with Gradient Text */}
50+
<h1 className="text-6xl md:text-8xl font-black tracking-tighter mb-6 leading-[0.9]">
51+
Something went <br />
52+
<span className="bg-linear-to-b from-white to-red-600 bg-clip-text text-transparent">
53+
wrong.
54+
</span>
55+
</h1>
56+
57+
<p className="max-w-md mx-auto text-gray-400 text-lg md:text-xl mb-10 leading-relaxed">
58+
An unexpected error occurred during the generation process. The
59+
codebase remains secure, but the current operation was halted.
60+
</p>
61+
62+
{/* Action Buttons */}
63+
<div className="flex flex-col sm:flex-row items-center gap-4 mb-16">
64+
<button
65+
onClick={handleReset}
66+
className="group flex items-center gap-2 px-8 py-3 bg-white text-black rounded-full font-bold text-lg hover:bg-gray-200 transition-all shadow-[0_0_30px_rgba(255,55,55,0.25)] active:scale-95"
67+
>
68+
<RefreshCw
69+
size={20}
70+
className="group-hover:rotate-180 transition-transform duration-700"
71+
/>
72+
Try Again
73+
</button>
74+
<Link
75+
href="/"
76+
className="flex items-center gap-2 px-8 py-3 bg-transparent text-white border border-white/20 rounded-full font-bold text-lg hover:bg-white/5 transition-all active:scale-95"
77+
>
78+
<Home size={20} />
79+
Return Home
80+
</Link>
81+
</div>
82+
83+
{/* Debugging Terminal - Visual match for terminal in mainpage.png */}
84+
<div className="w-full max-w-2xl bg-[#0a0a0a] border border-red-500/20 rounded-xl overflow-hidden shadow-2xl animate-in fade-in slide-in-from-bottom-4 duration-700">
85+
<div className="flex items-center justify-between px-4 py-3 bg-white/5 border-b border-white/5 text-[10px] font-mono text-gray-500 tracking-widest uppercase">
86+
<div className="flex gap-1.5">
87+
<div className="w-3 h-3 rounded-full bg-red-500/70"></div>
88+
<div className="w-3 h-3 rounded-full bg-gray-700"></div>
89+
<div className="w-3 h-3 rounded-full bg-gray-700"></div>
90+
</div>
91+
<div className="flex items-center gap-2">
92+
<Terminal size={12} />
93+
<span>STACK_TRACE_SNAPSHOT</span>
94+
</div>
95+
</div>
96+
<div className="p-6 font-mono text-sm text-left space-y-3 leading-relaxed">
97+
<div className="flex gap-2">
98+
<span className="text-red-400 font-bold shrink-0">
99+
[CRITICAL]
100+
</span>
101+
<span className="text-gray-300 wrap-break-word">
102+
{errorMessage}
103+
</span>
104+
</div>
105+
<div className="pl-4 border-l border-red-500/30 space-y-1">
106+
<div className="text-gray-500 text-xs flex justify-between">
107+
<span>digest:</span>
108+
<span className="text-gray-400">{errorDigest}</span>
109+
</div>
110+
<div className="text-gray-500 text-xs flex justify-between">
111+
<span>timestamp:</span>
112+
<span className="text-gray-400">{errorTime} UTC</span>
113+
</div>
114+
<div className="text-gray-500 text-xs flex justify-between">
115+
<span>module:</span>
116+
<span className="text-gray-400">{error?.name ?? "Error"}</span>
117+
</div>
118+
</div>
119+
{process.env.NODE_ENV === "development" && (
120+
<>
121+
<div className="flex gap-2 text-blue-400/80 pt-2">
122+
<span></span>
123+
<span className="text-gray-400 italic">
124+
Self-healing protocol initiated...
125+
</span>
126+
</div>
127+
<div className="flex gap-2 text-green-400/80">
128+
<span></span>
129+
<span>
130+
Workspace state preserved. Ready for manual reset.
131+
</span>
132+
</div>
133+
</>
134+
)}
135+
</div>
136+
</div>
137+
138+
{/* Replicating feature-page.png style for secondary info */}
139+
<div className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-4 w-full max-w-2xl">
140+
<div className="p-4 rounded-xl border border-white/5 bg-white/2 flex items-center gap-4 text-left group hover:border-red-500/20 transition-colors">
141+
<div className="w-10 h-10 rounded-lg bg-red-500/10 flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform">
142+
<ShieldAlert size={20} className="text-red-400" />
143+
</div>
144+
<div>
145+
<h4 className="font-bold text-sm">IP Protected</h4>
146+
<p className="text-xs text-gray-500">
147+
Your code was not compromised during this crash.
148+
</p>
149+
</div>
150+
</div>
151+
<div className="p-4 rounded-xl border border-white/5 bg-white/2 flex items-center gap-4 text-left group hover:border-orange-500/20 transition-colors">
152+
<div className="w-10 h-10 rounded-lg bg-orange-500/10 flex items-center justify-center shrink-0 group-hover:scale-110 transition-transform">
153+
<RefreshCw size={20} className="text-orange-400" />
154+
</div>
155+
<div>
156+
<h4 className="font-bold text-sm">State Recovery</h4>
157+
<p className="text-xs text-gray-500">
158+
Click &quot;Try Again&quot; to retry the failed operation.
159+
</p>
160+
</div>
161+
</div>
162+
</div>
163+
</main>
164+
165+
{/* Brand Footer */}
166+
<div className="absolute bottom-8 left-1/2 -translate-x-1/2 flex items-center gap-2 opacity-20 hover:opacity-100 transition-opacity cursor-default">
167+
<div className="w-5 h-5 bg-white rounded flex items-center justify-center">
168+
<span className="text-black font-black text-xs">R</span>
169+
</div>
170+
<span className="font-bold text-xs tracking-tight">ReadmeGenAI</span>
171+
</div>
172+
</div>
173+
);
174+
}

src/app/generate/GeneratePageClient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Navbar } from "@/components/layout/Navbar";
44
import { Footer } from "@/components/layout/Footer";
55
import { SearchInput } from "@/components/Generator/SearchInput";
66
import { MarkdownPreview } from "@/components/Generator/MarkdownPreview";
7-
import { LoadingOverlay } from "@/components/Generator/LoadingOverlay";
7+
import LoadingOverlay from "@/components/Generator/LoadingOverlay";
88
import { navLinks } from "@/constants/navLinks";
99
import { TerminalMockup } from "@/components/sections/TerminalMockup";
1010

src/app/globals.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@import "tailwindcss";
2+
@plugin "tailwindcss-animate";
23

34
:root {
45
--background: #ffffff;

src/app/not-found.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,15 @@ export default function NotFound() {
3838

3939
{/* CTA Buttons */}
4040
<div className="flex flex-col sm:flex-row items-center justify-center gap-4 mb-20 animate-in fade-in slide-in-from-bottom-6 duration-1000">
41-
<Button
42-
asChild
43-
variant="primary"
44-
className="w-full sm:w-auto px-10 py-4 text-lg shadow-xl shadow-white/5"
45-
>
46-
<Link href="/">
41+
<Link href="/">
42+
<Button
43+
variant="primary"
44+
className="w-full sm:w-auto px-10 py-4 text-lg shadow-xl shadow-white/5"
45+
>
4746
<Home size={20} />
4847
Back to Safety
49-
</Link>
50-
</Button>
48+
</Button>
49+
</Link>
5150

5251
<Button
5352
variant="outline"

0 commit comments

Comments
 (0)