Farsi RTL Next.js 16 storefront for استاد علی عالمی, cloned from the original Meshkee web-builder site and rebuilt with Tailwind 4, live Meshkee API integration (products, store items, portfolios, blog, workshops, comments, cart, customer auth), and standalone production output for the shared-VM deploy. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { PageHeader } from "@/components/PageHeader";
|
|
import { EntityCard } from "@/components/catalog/EntityCard";
|
|
import { EmptyState } from "@/components/catalog/EmptyState";
|
|
import { normalizeImage, pickText } from "@/lib/meshkee/format";
|
|
import { safe } from "@/lib/meshkee/client";
|
|
import { getWorkshops } from "@/lib/meshkee/workshops";
|
|
import type { WorkshopListResponse } from "@/lib/meshkee/types";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "دوره های آموزشی",
|
|
description: "دورهها و کارگاههای آموزشی استاد علی عالمی برای ریاضی و حسابان کنکور.",
|
|
};
|
|
|
|
const EMPTY: WorkshopListResponse = { items: [], total: 0, page: 1, pageSize: 24 };
|
|
|
|
export default async function WorkshopsPage() {
|
|
const { items } = await safe(getWorkshops({ pageSize: 24 }), EMPTY);
|
|
|
|
return (
|
|
<>
|
|
<PageHeader title="دوره های آموزشی" current="دوره های آموزشی" />
|
|
<section className="boxed py-16">
|
|
{items.length === 0 ? (
|
|
<EmptyState
|
|
title="در حال حاضر دورهای برای ثبتنام باز نیست"
|
|
text="برای اطلاع از زمان برگزاری دورههای بعدی از طریق صفحه تماس با ما در ارتباط باشید."
|
|
/>
|
|
) : (
|
|
<div className="grid grid-cols-2 gap-5 sm:grid-cols-3 lg:grid-cols-4">
|
|
{items.map((workshop) => (
|
|
<EntityCard
|
|
key={workshop.id}
|
|
href={`/workshops/${workshop.slug ?? workshop.id}`}
|
|
image={normalizeImage(workshop.titleImageUrl)}
|
|
title={pickText(workshop.titleFa, workshop.title, workshop.titleEn)}
|
|
price={workshop.discountedPrice ?? workshop.price}
|
|
originalPrice={workshop.discountedPrice ? workshop.price : undefined}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
</section>
|
|
</>
|
|
);
|
|
}
|