feat: add route-backed project case studies
This commit is contained in:
128
src/components/CaseStudyContent.tsx
Normal file
128
src/components/CaseStudyContent.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
||||
import { messagesByLocale, type Locale } from '@/i18n/content';
|
||||
import { getProjectPath, type Project } from '@/data/projects';
|
||||
import styles from './CaseStudyDrawer.module.css';
|
||||
|
||||
export function CaseStudyContent({
|
||||
project,
|
||||
locale,
|
||||
previous,
|
||||
next,
|
||||
}: {
|
||||
project: Project;
|
||||
locale: Locale;
|
||||
previous: Project;
|
||||
next: Project;
|
||||
}) {
|
||||
const copy = messagesByLocale[locale].projects;
|
||||
const caseStudy = project.caseStudy;
|
||||
const isRtl = locale === 'fa';
|
||||
|
||||
return (
|
||||
<article className={styles.content}>
|
||||
<header className={styles.hero}>
|
||||
<p className={styles.date}>{project.date}</p>
|
||||
<h1 id="case-study-title" className={styles.title} tabIndex={-1} data-case-study-heading>
|
||||
{project.title}
|
||||
</h1>
|
||||
<p id="case-study-introduction" className={styles.introduction}>{caseStudy.introduction}</p>
|
||||
<dl className={styles.facts}>
|
||||
<div><dt>{copy.roleLabel}</dt><dd>{caseStudy.role}</dd></div>
|
||||
<div><dt>{copy.usersLabel}</dt><dd>{caseStudy.targetUsers}</dd></div>
|
||||
<div><dt>{copy.statusLabel}</dt><dd>{caseStudy.status}</dd></div>
|
||||
{caseStudy.team && <div><dt>{copy.teamLabel}</dt><dd>{caseStudy.team}</dd></div>}
|
||||
</dl>
|
||||
</header>
|
||||
|
||||
<section className={styles.section} aria-labelledby="case-study-gallery">
|
||||
<h2 id="case-study-gallery" className={styles.sectionTitle}>{copy.galleryLabel}</h2>
|
||||
<div className={styles.gallery}>
|
||||
{caseStudy.gallery.map((item, index) => (
|
||||
<figure key={`${item.image.src}-${index}`} className={index === 0 ? styles.featuredMedia : styles.media}>
|
||||
<div className={styles.imageFrame}>
|
||||
<Image
|
||||
src={item.image.src}
|
||||
width={item.image.width}
|
||||
height={item.image.height}
|
||||
alt={item.alt}
|
||||
sizes={index === 0 ? '(max-width: 650px) 100vw, 68rem' : '(max-width: 650px) 100vw, 34rem'}
|
||||
className={styles.galleryImage}
|
||||
priority={index === 0}
|
||||
/>
|
||||
</div>
|
||||
<figcaption>{item.caption}</figcaption>
|
||||
</figure>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div className={styles.storyGrid}>
|
||||
<section className={styles.section} aria-labelledby="case-study-challenge">
|
||||
<h2 id="case-study-challenge" className={styles.sectionTitle}>{copy.challengeLabel}</h2>
|
||||
<p>{caseStudy.challenge}</p>
|
||||
</section>
|
||||
<section className={styles.section} aria-labelledby="case-study-ownership">
|
||||
<h2 id="case-study-ownership" className={styles.sectionTitle}>{copy.ownershipLabel}</h2>
|
||||
<ul className={styles.list}>{caseStudy.ownership.map((item) => <li key={item}>{item}</li>)}</ul>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{caseStudy.constraints && (
|
||||
<section className={styles.section} aria-labelledby="case-study-constraints">
|
||||
<h2 id="case-study-constraints" className={styles.sectionTitle}>{copy.constraintsLabel}</h2>
|
||||
<ul className={styles.list}>{caseStudy.constraints.map((item) => <li key={item}>{item}</li>)}</ul>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<section className={styles.section} aria-labelledby="case-study-decisions">
|
||||
<h2 id="case-study-decisions" className={styles.sectionTitle}>{copy.decisionsLabel}</h2>
|
||||
<div className={styles.decisions}>
|
||||
{caseStudy.decisions.map((decision) => (
|
||||
<article key={`${decision.discipline}-${decision.title}`} className={styles.decision} data-discipline={decision.discipline}>
|
||||
<span>{copy.decisionLabels[decision.discipline]}</span>
|
||||
<h3>{decision.title}</h3>
|
||||
<p>{decision.description}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className={styles.section} aria-labelledby="case-study-outcomes">
|
||||
<h2 id="case-study-outcomes" className={styles.sectionTitle}>{copy.outcomesLabel}</h2>
|
||||
{caseStudy.metrics && <dl className={styles.metrics}>{caseStudy.metrics.map((metric) => <div key={metric.label}><dt>{metric.value}</dt><dd>{metric.label}</dd></div>)}</dl>}
|
||||
<ul className={styles.list}>{caseStudy.outcomes.map((item) => <li key={item}>{item}</li>)}</ul>
|
||||
</section>
|
||||
|
||||
<div className={styles.stackGrid}>
|
||||
<section className={styles.section} aria-labelledby="case-study-skills">
|
||||
<h2 id="case-study-skills" className={styles.sectionTitle}>{copy.skillsLabel}</h2>
|
||||
<div className={styles.badges}>{caseStudy.skills.map((skill) => <span key={skill}>{skill}</span>)}</div>
|
||||
</section>
|
||||
<section className={styles.section} aria-labelledby="case-study-tools">
|
||||
<h2 id="case-study-tools" className={styles.sectionTitle}>{copy.toolsLabel}</h2>
|
||||
<div className={`${styles.badges} ltr-token`} lang="en" dir="ltr">{caseStudy.tools.map((tool) => <span key={tool}>{tool}</span>)}</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
{caseStudy.lessons && (
|
||||
<section className={styles.section} aria-labelledby="case-study-lessons">
|
||||
<h2 id="case-study-lessons" className={styles.sectionTitle}>{copy.lessonsLabel}</h2>
|
||||
<ul className={styles.list}>{caseStudy.lessons.map((item) => <li key={item}>{item}</li>)}</ul>
|
||||
</section>
|
||||
)}
|
||||
|
||||
<nav className={styles.projectNavigation} aria-label={copy.drawerLabel}>
|
||||
<Link href={getProjectPath(locale, previous.id)} replace scroll={false} className={styles.projectNavLink}>
|
||||
{isRtl ? <ArrowRight aria-hidden="true" /> : <ArrowLeft aria-hidden="true" />}
|
||||
<span><small>{copy.previousCaseStudy}</small><strong>{previous.title}</strong></span>
|
||||
</Link>
|
||||
<Link href={getProjectPath(locale, next.id)} replace scroll={false} className={`${styles.projectNavLink} ${styles.nextProject}`}>
|
||||
<span><small>{copy.nextCaseStudy}</small><strong>{next.title}</strong></span>
|
||||
{isRtl ? <ArrowLeft aria-hidden="true" /> : <ArrowRight aria-hidden="true" />}
|
||||
</Link>
|
||||
</nav>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user