feat: use MarkdownContent on project detail page
This commit is contained in:
@@ -1,12 +1,11 @@
|
|||||||
import { projects } from "@/lib/data";
|
import { projects } from "@/lib/data";
|
||||||
import { Project } from "@/lib/types";
|
import { Project } from "@/lib/types";
|
||||||
import Chip from "@/components/chip";
|
import Chip from "@/components/chip";
|
||||||
|
import MarkdownContent from "@/components/markdown-content";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { Github, Eye, CloudDownload } from "lucide-react";
|
import { Github, Eye, CloudDownload } from "lucide-react";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
import { remark } from "remark";
|
|
||||||
import html from "remark-html";
|
|
||||||
|
|
||||||
function getProjectByName(name: string): Project | undefined {
|
function getProjectByName(name: string): Project | undefined {
|
||||||
const decodedName = decodeURIComponent(name.replace(/\+/g, " "));
|
const decodedName = decodeURIComponent(name.replace(/\+/g, " "));
|
||||||
@@ -54,13 +53,6 @@ export async function generateMetadata({
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getProjectData(project: Project) {
|
|
||||||
const processedContent = await remark()
|
|
||||||
.use(html)
|
|
||||||
.process(project.description);
|
|
||||||
return processedContent.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function ProjectDetailPage({
|
export default async function ProjectDetailPage({
|
||||||
params,
|
params,
|
||||||
}: {
|
}: {
|
||||||
@@ -68,7 +60,6 @@ export default async function ProjectDetailPage({
|
|||||||
}) {
|
}) {
|
||||||
const { projectName } = await params;
|
const { projectName } = await params;
|
||||||
const project = getProjectByName(projectName);
|
const project = getProjectByName(projectName);
|
||||||
const descriptionHtml = project ? await getProjectData(project) : "";
|
|
||||||
|
|
||||||
if (!project) {
|
if (!project) {
|
||||||
notFound();
|
notFound();
|
||||||
@@ -79,14 +70,16 @@ export default async function ProjectDetailPage({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-full h-full min-h-screen gap-4 p-4 pt-24">
|
<div className="flex flex-col w-full h-full min-h-screen gap-4 p-4 pt-24">
|
||||||
<div className="prose prose-invert lg:prose-lg xl:prose-xl max-w-4xl mx-auto">
|
<div className="max-w-4xl mx-auto w-full">
|
||||||
<h1>{project.name}</h1>
|
<h1 className="text-4xl font-extrabold mb-6 bg-gradient-to-r from-yellow-400 to-blue-400 bg-clip-text text-transparent tracking-tight">
|
||||||
|
{project.name}
|
||||||
|
</h1>
|
||||||
|
|
||||||
<section dangerouslySetInnerHTML={{ __html: descriptionHtml }} />
|
<MarkdownContent content={project.description} />
|
||||||
|
|
||||||
<section className="not-prose mt-12 flex flex-col items-center">
|
<section className="mt-12 flex flex-col items-center">
|
||||||
<h2>Technologies</h2>
|
<h2 className="text-xl font-bold text-white mb-4">Technologies</h2>
|
||||||
<div className="flex flex-wrap justify-center gap-2 mt-4">
|
<div className="flex flex-wrap justify-center gap-2">
|
||||||
{project.technologies.map((tech) => (
|
{project.technologies.map((tech) => (
|
||||||
<Chip key={tech} text={tech} />
|
<Chip key={tech} text={tech} />
|
||||||
))}
|
))}
|
||||||
@@ -94,9 +87,9 @@ export default async function ProjectDetailPage({
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
{project.thumbnails && project.thumbnails.length > 0 && (
|
{project.thumbnails && project.thumbnails.length > 0 && (
|
||||||
<section className="not-prose mt-12 flex flex-col items-center">
|
<section className="mt-12 flex flex-col items-center">
|
||||||
<h2>Gallery</h2>
|
<h2 className="text-xl font-bold text-white mb-4">Gallery</h2>
|
||||||
<div className="flex flex-col gap-4 mt-4">
|
<div className="flex flex-col gap-4">
|
||||||
{project.thumbnails.map((thumb, index) => (
|
{project.thumbnails.map((thumb, index) => (
|
||||||
<Image
|
<Image
|
||||||
key={index}
|
key={index}
|
||||||
@@ -112,9 +105,9 @@ export default async function ProjectDetailPage({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{hasLinks && (
|
{hasLinks && (
|
||||||
<section className="not-prose mt-12 flex flex-col items-center">
|
<section className="mt-12 flex flex-col items-center">
|
||||||
<h2>Links</h2>
|
<h2 className="text-xl font-bold text-white mb-4">Links</h2>
|
||||||
<div className="flex flex-col sm:flex-row gap-4 mt-4">
|
<div className="flex flex-col sm:flex-row gap-4">
|
||||||
{project.github_url && (
|
{project.github_url && (
|
||||||
<a
|
<a
|
||||||
href={project.github_url}
|
href={project.github_url}
|
||||||
|
|||||||
Reference in New Issue
Block a user