Polish product/blog detail pages: gallery, tabs, Persian names, image fixes
- Product detail: interactive image gallery (thumbnails, prev/next,
hover-zoom), tabbed spec/review/comments section matching the site's
standard pattern, variations/options display, and an availability
label instead of duplicating the contact-store message.
- Fix product.images normalization — the API returns {url} media objects,
not plain strings, so galleries were silently rendering empty.
- Prefer the Persian name (nameFa/productNameFa) everywhere a product
name is shown.
- Product cards: padded, rounded images instead of edge-to-edge with a
dashed divider.
- Blog: wire the homepage carousel to real posts (was static sample
data), drop the detail page's separate cover image, and make images
embedded in article/description HTML fill their container with
rounded corners.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2b5f4e437b
commit
7fb1f5a60f
@@ -1,9 +1,15 @@
|
||||
import { Placeholder } from "@/components/ui/Placeholder";
|
||||
import { SectionTitle } from "@/components/ui/SectionTitle";
|
||||
import { Carousel } from "@/components/ui/Carousel";
|
||||
import { blogPosts } from "@/data/sample";
|
||||
import { EmptyState } from "@/components/ui/EmptyState";
|
||||
import type { BlogSummary } from "@/lib/meshkee";
|
||||
|
||||
export function BlogCarousel() {
|
||||
function formatDate(iso?: string) {
|
||||
if (!iso) return "";
|
||||
return new Intl.DateTimeFormat("fa-IR", { dateStyle: "long" }).format(new Date(iso));
|
||||
}
|
||||
|
||||
export function BlogCarousel({ posts }: { posts: BlogSummary[] }) {
|
||||
return (
|
||||
<section className="py-10 md:py-14">
|
||||
<div className="mx-auto max-w-7xl px-4">
|
||||
@@ -12,42 +18,46 @@ export function BlogCarousel() {
|
||||
enTitle="Latest Blog"
|
||||
action="وبلاگ"
|
||||
/>
|
||||
<Carousel ariaLabel="کاروسل وبلاگ">
|
||||
{blogPosts.map((post) => (
|
||||
<article
|
||||
key={post.id}
|
||||
className="w-[280px] shrink-0 overflow-hidden rounded-xl border border-border bg-surface transition-shadow hover:shadow-md md:w-[300px]"
|
||||
>
|
||||
<Placeholder
|
||||
src={post.image}
|
||||
alt={post.title}
|
||||
width="100%"
|
||||
height="160px"
|
||||
label="300×160"
|
||||
className="w-full rounded-none border-0 border-b border-dashed"
|
||||
/>
|
||||
<div className="p-4">
|
||||
<div className="mb-2 flex items-center gap-2 text-[11px] text-muted">
|
||||
<span>{post.date}</span>
|
||||
<span>•</span>
|
||||
<span>{post.readTime} مطالعه</span>
|
||||
</div>
|
||||
<h3 className="mb-2 line-clamp-2 text-sm font-bold leading-relaxed">
|
||||
{post.title}
|
||||
</h3>
|
||||
<p className="line-clamp-2 text-xs leading-relaxed text-muted">
|
||||
{post.excerpt}
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
className="mt-3 text-xs font-medium text-red transition-colors hover:text-red-dark"
|
||||
>
|
||||
ادامه مطلب ←
|
||||
</button>
|
||||
</div>
|
||||
</article>
|
||||
))}
|
||||
</Carousel>
|
||||
{posts.length === 0 ? (
|
||||
<EmptyState message="هنوز مطلبی ثبت نشده است." />
|
||||
) : (
|
||||
<Carousel ariaLabel="کاروسل وبلاگ">
|
||||
{posts.map((post) => (
|
||||
<article
|
||||
key={post.id}
|
||||
className="w-[280px] shrink-0 overflow-hidden rounded-xl border border-border bg-surface transition-shadow hover:shadow-md md:w-[300px]"
|
||||
>
|
||||
<a href={`/blog/${post.slug}`}>
|
||||
<div className="p-[10px]">
|
||||
<Placeholder
|
||||
src={post.image ?? "/images/placeholder.svg"}
|
||||
alt={post.title}
|
||||
width="100%"
|
||||
fit="contain"
|
||||
className="aspect-square w-full rounded-lg border-0"
|
||||
/>
|
||||
</div>
|
||||
<div className="p-4 pt-0">
|
||||
{post.publishedAt && (
|
||||
<div className="mb-2 text-[11px] text-muted">{formatDate(post.publishedAt)}</div>
|
||||
)}
|
||||
<h3 className="mb-2 line-clamp-2 text-sm font-bold leading-relaxed">
|
||||
{post.title}
|
||||
</h3>
|
||||
{post.abstract && (
|
||||
<p className="line-clamp-2 text-xs leading-relaxed text-muted">
|
||||
{post.abstract}
|
||||
</p>
|
||||
)}
|
||||
<span className="mt-3 block text-xs font-medium text-red">
|
||||
ادامه مطلب ←
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
))}
|
||||
</Carousel>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user