Files
my-protfolio/src/components/MilestonesSection.tsx
Amirhossein Khalili b3cfcfe057
Some checks failed
Test and deploy / Verify production build (push) Has been cancelled
Test and deploy / Deploy production (push) Has been cancelled
fix: stabilize portfolio scrolling and loading
Remove skeleton swaps and deferred layout estimates, restore reveal state, and use native proximity scrolling for project cards. Also make the Docker build npm registry configurable.
2026-09-09 17:53:48 +03:30

80 lines
2.9 KiB
TypeScript

import Image from 'next/image';
import { ExternalLink } from 'lucide-react';
import { getMilestones } from '@/data/milestones';
import { messagesByLocale, type Locale } from '@/i18n/content';
import styles from './MilestonesSection.module.css';
export const MilestonesSection = ({ locale }: { locale: Locale }) => {
const isRtl = locale === 'fa';
const milestones = getMilestones(locale);
const copy = messagesByLocale[locale].milestones;
return (
<section id="milestones" className={styles.milestonesSection}>
<div className="content-container">
{/* Section Header */}
<div className="section-header" data-reveal="soft">
<span className="section-eyebrow">{copy.eyebrow}</span>
<div className="section-title-wrap">
<h2 className="section-title">{copy.title}</h2>
<div className="section-underline" />
</div>
</div>
{/* Certificate Cards List */}
<div className={styles.cardsList} data-reveal-group>
{milestones.map((item) => (
<div key={item.id} className={styles.certCard}>
{/* Thumbnail */}
<div className={styles.thumbnailContainer} data-reveal="image">
<Image
src={item.image.src}
alt={item.title}
fill
sizes="(max-width: 650px) calc(100vw - 3rem), (max-width: 1024px) 44vw, 520px"
className={styles.certImage}
/>
</div>
{/* Content Details */}
<div className={styles.certDetails} data-reveal="soft">
<div className={styles.titleRow}>
<h3 className={styles.certTitle}>{item.title}</h3>
</div>
<div className={styles.issuerRow}>
<span className={styles.issuerText}>{item.issuer}</span>
</div>
<div className={styles.dateBadge}>{item.date}</div>
<p className={styles.description}>{item.description}</p>
{item.link && (
<div className={styles.actionRow}>
<a
href={item.link}
className={styles.viewCertLink}
target="_blank"
rel="noopener noreferrer"
aria-label={copy.viewCertificateLabel(item.title)}
>
{isRtl && (
<ExternalLink size={20} strokeWidth={2.25} aria-hidden="true" />
)}
<span>{copy.viewCertificate}</span>
{!isRtl && (
<ExternalLink size={20} strokeWidth={2.25} aria-hidden="true" />
)}
</a>
</div>
)}
</div>
</div>
))}
</div>
</div>
</section>
);
};