feat(blog): جدول — ستونها قابل تغییر اندازه/افزودن و حذف؛ لینک کپشن تصویر؛ هدینگهای نسخه انگلیسی بزرگتر
This commit is contained in:
@@ -21,15 +21,37 @@ export function ProjectDetail() {
|
||||
const statusLabel = useStatusLabel(project?.status ?? '')
|
||||
const [lightbox, setLightbox] = useState<number | null>(null)
|
||||
|
||||
// عنوان تب، توضیح متا و OG از خود پروژه
|
||||
// عنوان تب، توضیح متا، OG و JSON-LD از خود پروژه — همارز نسخهٔ سمت سرور (seo_pages.py)
|
||||
useEffect(() => {
|
||||
if (!project) return;
|
||||
const absolute = (path: string) => new URL(path, window.location.origin).href;
|
||||
applySeo({
|
||||
title: `${project.title} | ${brand.name}`,
|
||||
description: project.summary,
|
||||
path: href(`/projects/${project.slug}`),
|
||||
image: project.image,
|
||||
lang,
|
||||
// alternate انگلیسی فقط با وجود ترجمهٔ واقعی
|
||||
hasEn: !!(project.title_en?.trim() || project.summary_en?.trim()),
|
||||
jsonLd: [
|
||||
{
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'WebPage',
|
||||
name: project.title,
|
||||
description: project.summary,
|
||||
image: project.image ? absolute(project.image) : undefined,
|
||||
inLanguage: lang,
|
||||
},
|
||||
{
|
||||
'@context': 'https://schema.org',
|
||||
'@type': 'BreadcrumbList',
|
||||
itemListElement: [
|
||||
{ '@type': 'ListItem', position: 1, name: t('home'), item: absolute(href('/')) },
|
||||
{ '@type': 'ListItem', position: 2, name: t('projects'), item: absolute(href('/projects')) },
|
||||
{ '@type': 'ListItem', position: 3, name: project.title, item: absolute(href(`/projects/${project.slug}`)) },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}, [project?.id, lang, href]);
|
||||
|
||||
@@ -69,7 +91,7 @@ export function ProjectDetail() {
|
||||
return (
|
||||
<>
|
||||
<section className="relative flex h-[62vh] min-h-[440px] items-end overflow-hidden">
|
||||
<img src={project.image} alt="" aria-hidden="true" className="absolute inset-0 h-full w-full object-cover" />
|
||||
<img src={project.image} alt="" aria-hidden="true" className="absolute inset-0 h-full w-full object-cover" fetchPriority="high" decoding="async" />
|
||||
<div className="absolute inset-0 bg-ink/72" aria-hidden="true" />
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
@@ -147,6 +169,8 @@ export function ProjectDetail() {
|
||||
src={project.gallery[0] || project.image}
|
||||
alt=""
|
||||
className="aspect-[4/3] w-full object-cover transition-transform duration-500 ease-lux group-hover:scale-105"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</button>
|
||||
<div className="mt-4 grid grid-cols-3 gap-4">
|
||||
@@ -161,6 +185,8 @@ export function ProjectDetail() {
|
||||
src={img}
|
||||
alt=""
|
||||
className="aspect-square w-full object-cover transition-transform duration-500 ease-lux group-hover:scale-105"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user