From 6695b5c3611bb77bd0eec8e022c21d9f704e5a2c Mon Sep 17 00:00:00 2001 From: Denshooter Date: Thu, 13 Feb 2025 15:18:46 +0100 Subject: [PATCH] refactor(page): standardize formatting and improve error handling in ProjectDetails component --- app/Projects/[slug]/page.tsx | 167 ---------------------------------- app/projects/[slug]/page.tsx | 169 +++++++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 167 deletions(-) delete mode 100644 app/Projects/[slug]/page.tsx create mode 100644 app/projects/[slug]/page.tsx diff --git a/app/Projects/[slug]/page.tsx b/app/Projects/[slug]/page.tsx deleted file mode 100644 index 7c10c0e..0000000 --- a/app/Projects/[slug]/page.tsx +++ /dev/null @@ -1,167 +0,0 @@ -"use client"; - -import { - useRouter, - useSearchParams, - useParams, - usePathname, -} from "next/navigation"; -import { useEffect, useState } from "react"; - -import Link from "next/link"; - -import Footer_Back from "@/app/components/Footer_Back"; -import Header from "@/app/components/Header"; -import Image from "next/image"; -import "@/app/styles/ghostContent.css"; // Import the global styles - -interface Project { - slug: string; - id: string; - title: string; - feature_image: string; - visibility: string; - published_at: string; - updated_at: string; - html: string; - reading_time: number; - meta_description: string; -} - -const ProjectDetails = () => { - const router = useRouter(); - const searchParams = useSearchParams(); - const params = useParams(); - const pathname = usePathname(); - const [project, setProject] = useState(null); - const [isVisible, setIsVisible] = useState(false); - const [error, setError] = useState(null); - - useEffect(() => { - setTimeout(() => { - setIsVisible(true); - }, 150); // Delay to start the animation - }, []); - - useEffect(() => { - const projectData = searchParams.get("project"); - if (projectData) { - setProject(JSON.parse(projectData as string)); - // Remove the project data from the URL without reloading the page - if (typeof window !== "undefined") { - const url = new URL(window.location.href); - url.searchParams.delete("project"); - window.history.replaceState({}, "", url.toString()); - } - } else { - // Fetch project data based on slug from URL - const slug = params.slug as string; - try { - fetchProjectData(slug); - } catch (error) { - console.log(error); - setError("Failed to fetch project data"); - } - } - }, [searchParams, router, params, pathname]); - - const fetchProjectData = async (slug: string) => { - try { - const response = await fetch(`/api/fetchProject?slug=${slug}`); - if (!response.ok) { - throw new Error("Failed to fetch project data"); - } - const projectData = (await response.json()) as { posts: Project[] }; - if (projectData.posts.length === 0) { - throw new Error("Project not found"); - } - setProject(projectData.posts[0]); - } catch (error) { - console.error("Failed to fetch project data:", error); - setError("Project not found"); - } - }; - - if (error) { - return ( -
-
-
-
-

- 404 -

-

- {error} -

- - Go Back Home - -
-
- -
- ); - } - - if (!project) { - return ( -
-
-
-
-
- -
- ); - } - - const featureImageUrl = project.feature_image - ? `/api/fetchImage?url=${encodeURIComponent(project.feature_image)}` - : ""; - - return ( -
-
-
-
- {featureImageUrl && ( -
- {project.title} -
- )} -
-
-

- {project.title} -

-
- - {/* Project Content */} -
-
-
-
-
-
- -
- ); -}; - -export default ProjectDetails; diff --git a/app/projects/[slug]/page.tsx b/app/projects/[slug]/page.tsx new file mode 100644 index 0000000..71ef87b --- /dev/null +++ b/app/projects/[slug]/page.tsx @@ -0,0 +1,169 @@ +"use client"; + +import { + useRouter, + useSearchParams, + useParams, + usePathname, +} from "next/navigation"; +import {useEffect, useState} from "react"; + +import Link from "next/link"; + +import Footer_Back from "@/app/components/Footer_Back"; +import Header from "@/app/components/Header"; +import Image from "next/image"; +import "@/app/styles/ghostContent.css"; // Import the global styles + +interface Project { + slug: string; + id: string; + title: string; + feature_image: string; + visibility: string; + published_at: string; + updated_at: string; + html: string; + reading_time: number; + meta_description: string; +} + +const ProjectDetails = () => { + const router = useRouter(); + const searchParams = useSearchParams(); + const params = useParams(); + const pathname = usePathname(); + const [project, setProject] = useState(null); + const [isVisible, setIsVisible] = useState(false); + const [error, setError] = useState(null); + + useEffect(() => { + setTimeout(() => { + setIsVisible(true); + }, 150); // Delay to start the animation + }, []); + + useEffect(() => { + const projectData = searchParams.get("project"); + if (projectData) { + setProject(JSON.parse(projectData as string)); + // Remove the project data from the URL without reloading the page + if (typeof window !== "undefined") { + const url = new URL(window.location.href); + url.searchParams.delete("project"); + window.history.replaceState({}, "", url.toString()); + } + } else { + // Fetch project data based on slug from URL + const slug = params.slug as string; + try { + fetchProjectData(slug); + } catch (error) { + console.log(error); + setError("Failed to fetch project data"); + } + } + }, [searchParams, router, params, pathname]); + + const fetchProjectData = async (slug: string) => { + try { + const response = await fetch(`/api/fetchProject?slug=${slug}`); + if (!response.ok) { + setError("Failed to fetch project Data"); + } + const projectData = (await response.json()) as { posts: Project[] }; + if (projectData.posts.length === 0) { + setError("Project not found"); + } + setProject(projectData.posts[0]); + } catch (error) { + console.error("Failed to fetch project data:", error); + setError("Project not found"); + } + }; + + if (error) { + return ( +
+
+
+
+

+ 404 +

+

+ {error} +

+ + Go Back Home + +
+
+ +
+ ); + } + + if (!project) { + return ( +
+
+
+
+
+ +
+ ); + } + + const featureImageUrl = project.feature_image + ? `/api/fetchImage?url=${encodeURIComponent(project.feature_image)}` + : ""; + + return ( +
+
+
+
+ {featureImageUrl && ( +
+ {project.title} +
+ )} +
+
+

+ {project.title} +

+
+ + {/* Project Content */} +
+
+
+
+
+
+ +
+ ); +}; + +export default ProjectDetails;