import Image from 'next/image'; import { FiClock, FiTag } from 'react-icons/fi'; import ReactMarkdown from 'react-markdown'; import PagesMetaHead from '../../components/PagesMetaHead'; import RelatedProjects from '../../components/projects/RelatedProjects'; const API_BASE_URL = process.env.API_INTERNAL_URL || 'http://localhost:7341'; function ProjectSingle(props) { return (
{/* Header */}

{props.project.ProjectHeader.title}

{props.project.ProjectHeader.publishDate}
{props.project.ProjectHeader.tags}
{/* Gallery */}
{props.project.ProjectImages.map((project) => { return (
{project.title}
); })}
{/* Info */}
{/* Single project client details */}

{props.project.ProjectInfo.ClientHeading}

    {props.project.ProjectInfo.CompanyInfo.map( (info) => { const isUrl = /^https?:\/\//i.test(info.details); return (
  • {info.title}: {isUrl ? ( {info.details} ) : ( {info.details} )}
  • ); } )}
{/* Single project objectives */}

{props.project.ProjectInfo.ObjectivesHeading}

{props.project.ProjectInfo.ObjectivesDetails}

{/* Single project technologies */}

{props.project.ProjectInfo.Technologies[0].title}

{props.project.ProjectInfo.Technologies[0].techs.join( ', ' )}

{/* Single project right section details */}

{props.project.ProjectInfo.ProjectDetailsHeading}

{props.project.ProjectInfo.ProjectDetails.map((details) => { return (
{details.details}
); })}
); } export async function getServerSideProps({ query }) { const { url } = query; try { const res = await fetch(`${API_BASE_URL}/api/projects/${url}`); if (res.status === 404) { // 존재하지 않는 슬러그는 Next.js 404 로 응답 return { notFound: true }; } if (!res.ok) { // 5xx 등 비정상 응답은 404 로 위장하지 않고 Next.js 에러 페이지로 드러낸다 throw new Error(`[project detail] API returned ${res.status}`); } const body = await res.json(); const project = body?.data; if (!project) { return { notFound: true }; } // Related projects 는 보조 섹션이므로 실패해도 메인 페이지 렌더를 막지 않는다 let relatedProjects = []; try { const category = encodeURIComponent(project.category); const relRes = await fetch( `${API_BASE_URL}/api/projects?category=${category}` ); if (relRes.ok) { const relBody = await relRes.json(); relatedProjects = (relBody?.data ?? []) .filter((p) => p.url !== url) .slice(0, 4); } } catch (relErr) { console.error('[project detail] fetch related failed', relErr); } return { props: { project, relatedProjects } }; } catch (err) { console.error('[project detail] fetch failed', err); throw err; } } export default ProjectSingle;