Add NotFound page with picture
- Create NotFound component that displays not-found.png - Add SCSS styles for the NotFound page - Update App.jsx to show NotFound page for invalid routes instead of redirecting Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
26
src/App.jsx
26
src/App.jsx
@@ -7,6 +7,7 @@ import Hero from './components/Hero';
|
|||||||
import About from './components/About';
|
import About from './components/About';
|
||||||
import Projects from './components/Projects';
|
import Projects from './components/Projects';
|
||||||
import Contact from './components/Contact';
|
import Contact from './components/Contact';
|
||||||
|
import NotFound from './components/NotFound';
|
||||||
import Footer from './components/Footer';
|
import Footer from './components/Footer';
|
||||||
import styles from './App.module.scss';
|
import styles from './App.module.scss';
|
||||||
|
|
||||||
@@ -27,18 +28,15 @@ export default function App() {
|
|||||||
const [displayedSection, setDisplayedSection] = useState(activeSection);
|
const [displayedSection, setDisplayedSection] = useState(activeSection);
|
||||||
const timerRef = useRef(null);
|
const timerRef = useRef(null);
|
||||||
|
|
||||||
|
const path = location.pathname.substring(1) || 'home';
|
||||||
|
const notFound = !Object.keys(SECTIONS).includes(path);
|
||||||
|
|
||||||
// Sync URL path with activeSection
|
// Sync URL path with activeSection
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const path = location.pathname.substring(1) || 'home';
|
if (!notFound && path !== activeSection) {
|
||||||
if (Object.keys(SECTIONS).includes(path)) {
|
|
||||||
if (path !== activeSection) {
|
|
||||||
setActiveSection(path);
|
setActiveSection(path);
|
||||||
}
|
}
|
||||||
} else {
|
}, [location.pathname, activeSection, setActiveSection, navigate, path, notFound]);
|
||||||
// Invalid path, redirect to home
|
|
||||||
navigate('/');
|
|
||||||
}
|
|
||||||
}, [location.pathname, activeSection, setActiveSection, navigate]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (theme === 'light') {
|
if (theme === 'light') {
|
||||||
@@ -59,6 +57,18 @@ export default function App() {
|
|||||||
const isExiting = activeSection !== displayedSection;
|
const isExiting = activeSection !== displayedSection;
|
||||||
const Section = SECTIONS[displayedSection] ?? Hero;
|
const Section = SECTIONS[displayedSection] ?? Hero;
|
||||||
|
|
||||||
|
if (notFound) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navbar />
|
||||||
|
<main className={styles.enter}>
|
||||||
|
<NotFound />
|
||||||
|
</main>
|
||||||
|
<Footer />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|||||||
15
src/components/NotFound.jsx
Normal file
15
src/components/NotFound.jsx
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import styles from '../styles/components/NotFound.module.scss';
|
||||||
|
|
||||||
|
export default function NotFound() {
|
||||||
|
return (
|
||||||
|
<section id="not-found" className={styles.notFound}>
|
||||||
|
<div className={styles.inner}>
|
||||||
|
<div className={styles.imageContainer}>
|
||||||
|
<img src="/not-found.png" alt="Not found" className={styles.image} />
|
||||||
|
</div>
|
||||||
|
<h1 className={styles.title}>Page Not Found</h1>
|
||||||
|
<p className={styles.message}>The page you're looking for doesn't exist.</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
39
src/styles/components/NotFound.module.scss
Normal file
39
src/styles/components/NotFound.module.scss
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
@use '../variables' as *;
|
||||||
|
|
||||||
|
.notFound {
|
||||||
|
padding: $space-24 $space-6;
|
||||||
|
min-height: 70vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inner {
|
||||||
|
max-width: $max-width;
|
||||||
|
margin: 0 auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imageContainer {
|
||||||
|
margin-bottom: $space-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: $radius-lg;
|
||||||
|
box-shadow: 0 0 30px rgb(var(--color-primary-mid) / 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: $text-4xl;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $color-text;
|
||||||
|
margin-bottom: $space-4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
font-size: $text-lg;
|
||||||
|
color: $color-text-muted;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user