diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..10fb0fc --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "simode-dev", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "dev"], + "port": 3000, + "autoPort": true + } + ] +} diff --git a/connect-backend-prompt.txt b/connect-backend-prompt.txt new file mode 100644 index 0000000..e9d0997 --- /dev/null +++ b/connect-backend-prompt.txt @@ -0,0 +1,15 @@ +Domain: simode.shop +Documentation for backend is:https://api.meshkee.com/docs/website + + +Login or user icon should go to customer.simode.shop + +Create product page and details >> connect to store items +Create blog page and details >> connect to blog + +Product Menu should be a mega menu with level 2 and 3 of categories - skip level 1 + +Search input should be instant search - activate when type more than 2 char + +First carousel >> special-discount +Second carousel >> top-selling diff --git a/images-slot-prompt.txt b/images-slot-prompt.txt new file mode 100644 index 0000000..ea51cf6 --- /dev/null +++ b/images-slot-prompt.txt @@ -0,0 +1,13 @@ +Wire this page to simode.shop static-image slots. + +Read http://meshkee.com/docs/website (static-images). Env is already set. + +Fetch slots, match by key: +- slider > duplicatable +- two-banner-row > two slot +- one-banner-row → one slot +- aboutus-row → one slot + +Use slot.images (all of them if kind=list, first if kind=single). +url → . linkUrl → wrap in . Empty or fail → keep current placeholder. +Use slot.aspectRatio from the API. Do not invent upload APIs. \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 69cf187..349dde5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "next": "16.3.1", "react": "19.2.8", - "react-dom": "19.2.8" + "react-dom": "19.2.8", + "swiper": "^14.1.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -6258,6 +6259,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/swiper": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-14.1.0.tgz", + "integrity": "sha512-ppit/AqmGvThKlXy4I1/9N/gEyb9s/BDHWciWNeIxbfteFKUhPQXrYuOMKszomXKd9WiLd+/0vKdPHW+0N0mhA==", + "funding": [ + { + "type": "custom", + "url": "https://sponsors.nolimits4web.com" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nolimits4web" + } + ], + "license": "MIT", + "engines": { + "node": ">= 4.7.0" + } + }, "node_modules/tailwindcss": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", diff --git a/package.json b/package.json index bebd39b..0a002e7 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "dependencies": { "next": "16.3.1", "react": "19.2.8", - "react-dom": "19.2.8" + "react-dom": "19.2.8", + "swiper": "^14.1.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", diff --git a/public/fonts/iranyekanwebboldfanum.woff b/public/fonts/iranyekanwebboldfanum.woff new file mode 100644 index 0000000..07f9756 Binary files /dev/null and b/public/fonts/iranyekanwebboldfanum.woff differ diff --git a/public/fonts/iranyekanweblightfanum.woff b/public/fonts/iranyekanweblightfanum.woff new file mode 100644 index 0000000..9e6d42c Binary files /dev/null and b/public/fonts/iranyekanweblightfanum.woff differ diff --git a/public/images/about/about.svg b/public/images/about/about.svg new file mode 100644 index 0000000..46803a4 --- /dev/null +++ b/public/images/about/about.svg @@ -0,0 +1,10 @@ + + + + + + + + + ABOUT US · 720×640 + \ No newline at end of file diff --git a/public/images/banners/banner-1.svg b/public/images/banners/banner-1.svg new file mode 100644 index 0000000..af4cd0e --- /dev/null +++ b/public/images/banners/banner-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + BANNER · 770×360 + \ No newline at end of file diff --git a/public/images/banners/banner-2.svg b/public/images/banners/banner-2.svg new file mode 100644 index 0000000..f814f5b --- /dev/null +++ b/public/images/banners/banner-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + BANNER · 770×360 + \ No newline at end of file diff --git a/public/images/banners/full-banner.svg b/public/images/banners/full-banner.svg new file mode 100644 index 0000000..5cea160 --- /dev/null +++ b/public/images/banners/full-banner.svg @@ -0,0 +1,10 @@ + + + + + + + + + FULL BANNER · 1600×420 + \ No newline at end of file diff --git a/public/images/blog/post-1.svg b/public/images/blog/post-1.svg new file mode 100644 index 0000000..71fd354 --- /dev/null +++ b/public/images/blog/post-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + BLOG · 520×380 + \ No newline at end of file diff --git a/public/images/blog/post-2.svg b/public/images/blog/post-2.svg new file mode 100644 index 0000000..2c315d5 --- /dev/null +++ b/public/images/blog/post-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + BLOG · 520×380 + \ No newline at end of file diff --git a/public/images/blog/post-3.svg b/public/images/blog/post-3.svg new file mode 100644 index 0000000..71fd354 --- /dev/null +++ b/public/images/blog/post-3.svg @@ -0,0 +1,10 @@ + + + + + + + + + BLOG · 520×380 + \ No newline at end of file diff --git a/public/images/blog/post-4.svg b/public/images/blog/post-4.svg new file mode 100644 index 0000000..2c315d5 --- /dev/null +++ b/public/images/blog/post-4.svg @@ -0,0 +1,10 @@ + + + + + + + + + BLOG · 520×380 + \ No newline at end of file diff --git a/public/images/categories/baby.svg b/public/images/categories/baby.svg new file mode 100644 index 0000000..036d825 --- /dev/null +++ b/public/images/categories/baby.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/categories/boys.svg b/public/images/categories/boys.svg new file mode 100644 index 0000000..593a069 --- /dev/null +++ b/public/images/categories/boys.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/categories/girls.svg b/public/images/categories/girls.svg new file mode 100644 index 0000000..036d825 --- /dev/null +++ b/public/images/categories/girls.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/categories/outerwear.svg b/public/images/categories/outerwear.svg new file mode 100644 index 0000000..593a069 --- /dev/null +++ b/public/images/categories/outerwear.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/categories/party.svg b/public/images/categories/party.svg new file mode 100644 index 0000000..593a069 --- /dev/null +++ b/public/images/categories/party.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/categories/sets.svg b/public/images/categories/sets.svg new file mode 100644 index 0000000..036d825 --- /dev/null +++ b/public/images/categories/sets.svg @@ -0,0 +1,10 @@ + + + + + + + + + CATEGORY · 520×600 + \ No newline at end of file diff --git a/public/images/hero/slide-1.svg b/public/images/hero/slide-1.svg new file mode 100644 index 0000000..54c8e05 --- /dev/null +++ b/public/images/hero/slide-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + HERO SLIDE · 1600×560 + \ No newline at end of file diff --git a/public/images/hero/slide-2.svg b/public/images/hero/slide-2.svg new file mode 100644 index 0000000..f791594 --- /dev/null +++ b/public/images/hero/slide-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + HERO SLIDE · 1600×560 + \ No newline at end of file diff --git a/public/images/hero/slide-3.svg b/public/images/hero/slide-3.svg new file mode 100644 index 0000000..54c8e05 --- /dev/null +++ b/public/images/hero/slide-3.svg @@ -0,0 +1,10 @@ + + + + + + + + + HERO SLIDE · 1600×560 + \ No newline at end of file diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..2d73ff8 Binary files /dev/null and b/public/images/logo.png differ diff --git a/public/images/products/product-1.svg b/public/images/products/product-1.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-10.svg b/public/images/products/product-10.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-10.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-11.svg b/public/images/products/product-11.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-11.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-12.svg b/public/images/products/product-12.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-12.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-2.svg b/public/images/products/product-2.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-3.svg b/public/images/products/product-3.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-3.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-4.svg b/public/images/products/product-4.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-4.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-5.svg b/public/images/products/product-5.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-5.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-6.svg b/public/images/products/product-6.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-6.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-7.svg b/public/images/products/product-7.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-7.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-8.svg b/public/images/products/product-8.svg new file mode 100644 index 0000000..f3dc943 --- /dev/null +++ b/public/images/products/product-8.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/products/product-9.svg b/public/images/products/product-9.svg new file mode 100644 index 0000000..d2eeac3 --- /dev/null +++ b/public/images/products/product-9.svg @@ -0,0 +1,10 @@ + + + + + + + + + PRODUCT · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/banner.svg b/public/images/special-sale/banner.svg new file mode 100644 index 0000000..131d999 --- /dev/null +++ b/public/images/special-sale/banner.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE BANNER · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-1.svg b/public/images/special-sale/product-1.svg new file mode 100644 index 0000000..4900f79 --- /dev/null +++ b/public/images/special-sale/product-1.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-2.svg b/public/images/special-sale/product-2.svg new file mode 100644 index 0000000..746b064 --- /dev/null +++ b/public/images/special-sale/product-2.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-3.svg b/public/images/special-sale/product-3.svg new file mode 100644 index 0000000..4900f79 --- /dev/null +++ b/public/images/special-sale/product-3.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-4.svg b/public/images/special-sale/product-4.svg new file mode 100644 index 0000000..746b064 --- /dev/null +++ b/public/images/special-sale/product-4.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-5.svg b/public/images/special-sale/product-5.svg new file mode 100644 index 0000000..4900f79 --- /dev/null +++ b/public/images/special-sale/product-5.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-6.svg b/public/images/special-sale/product-6.svg new file mode 100644 index 0000000..746b064 --- /dev/null +++ b/public/images/special-sale/product-6.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-7.svg b/public/images/special-sale/product-7.svg new file mode 100644 index 0000000..4900f79 --- /dev/null +++ b/public/images/special-sale/product-7.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/public/images/special-sale/product-8.svg b/public/images/special-sale/product-8.svg new file mode 100644 index 0000000..746b064 --- /dev/null +++ b/public/images/special-sale/product-8.svg @@ -0,0 +1,10 @@ + + + + + + + + + SALE ITEM · 480×620 + \ No newline at end of file diff --git a/scripts/gen-placeholders.mjs b/scripts/gen-placeholders.mjs new file mode 100644 index 0000000..0056c93 --- /dev/null +++ b/scripts/gen-placeholders.mjs @@ -0,0 +1,85 @@ +// Generates flat, neutral placeholder SVG images so every image slot on the +// homepage has a real file on disk that can be swapped later without any +// code changes. Run with: node scripts/gen-placeholders.mjs +import { mkdirSync, writeFileSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const PUBLIC = join(__dirname, "..", "public", "images"); + +// Two flat, muted tones so placeholders alternate subtly instead of being +// one flat wall of gray. +const TONES = ["#EBEDE9", "#E4E7E2"]; + +function icon(cx, cy, s, stroke) { + // Simple flat "image" glyph: rounded frame + mountain + sun dot. + return ` + + + + + `; +} + +function svgPlaceholder({ w, h, label, tone }) { + const s = Math.min(w, h) * 0.22; + const cx = w / 2; + const cy = h / 2 - s * 0.12; + return ` + + ${icon(cx, cy, s, "#B9BEB4")} + ${label} · ${w}×${h} +`; +} + +let toneIndex = 0; +function nextTone() { + const t = TONES[toneIndex % TONES.length]; + toneIndex += 1; + return t; +} + +function write(relPath, w, h, label) { + const full = join(PUBLIC, relPath); + mkdirSync(dirname(full), { recursive: true }); + writeFileSync(full, svgPlaceholder({ w, h, label, tone: nextTone() }), "utf8"); + console.log("wrote", relPath); +} + +// Hero slider — full width slides +for (let i = 1; i <= 3; i++) write(`hero/slide-${i}.svg`, 1600, 560, "HERO SLIDE"); + +// Special sale carousel — first card is a banner image, rest are product shots +write("special-sale/banner.svg", 480, 620, "SALE BANNER"); +for (let i = 1; i <= 8; i++) write(`special-sale/product-${i}.svg`, 480, 620, "SALE ITEM"); + +// Categories +const categories = ["girls", "boys", "baby", "party", "sets", "outerwear"]; +for (const key of categories) write(`categories/${key}.svg`, 520, 600, "CATEGORY"); + +// Two-banner section +write("banners/banner-1.svg", 770, 360, "BANNER"); +write("banners/banner-2.svg", 770, 360, "BANNER"); + +// Single full-width banner +write("banners/full-banner.svg", 1600, 420, "FULL BANNER"); + +// Top selling products carousel +for (let i = 1; i <= 12; i++) write(`products/product-${i}.svg`, 480, 620, "PRODUCT"); + +// About us +write("about/about.svg", 720, 640, "ABOUT US"); + +// Blog carousel +for (let i = 1; i <= 4; i++) write(`blog/post-${i}.svg`, 520, 380, "BLOG"); + +console.log("Done. Placeholder images generated in public/images/"); diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx new file mode 100644 index 0000000..223c840 --- /dev/null +++ b/src/app/blog/[slug]/page.tsx @@ -0,0 +1,59 @@ +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { getBlog } from "@/lib/api"; + +export default async function BlogDetailPage({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + + let blog; + try { + ({ blog } = await getBlog(slug)); + } catch { + notFound(); + } + + const title = blog.title || blog.nameFa || ""; + const cover = blog.thumbnailUrl || blog.image; + const date = blog.publishedAt || blog.createdAt; + const content = blog.contentHtml || blog.descriptionHtml; + + return ( +
+ + +
+ {date && ( + + {date.slice(0, 10)} + + )} +

{title}

+ + {cover && ( + + )} + + {blog.summary &&

{blog.summary}

} + + {content && ( +
+ )} +
+
+ ); +} diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx new file mode 100644 index 0000000..b613268 --- /dev/null +++ b/src/app/blog/page.tsx @@ -0,0 +1,86 @@ +import Link from "next/link"; +import { getBlogs, safe } from "@/lib/api"; +import Pagination from "@/components/ui/Pagination"; + +const PAGE_SIZE = 12; + +export const metadata = { + title: "وبلاگ | کودکانه", +}; + +export default async function BlogPage({ + searchParams, +}: { + searchParams: Promise<{ page?: string }>; +}) { + const params = await searchParams; + const page = Math.max(1, Number(params.page) || 1); + + const result = await safe(getBlogs({ page, pageSize: PAGE_SIZE }), { + items: [], + total: 0, + page, + pageSize: PAGE_SIZE, + }); + + const totalPages = Math.max(1, Math.ceil(result.total / PAGE_SIZE)); + + return ( +
+
+ + Our Blog + +

مقالات وبلاگ

+
+ + {result.items.length === 0 ? ( +

+ هنوز مطلبی در وبلاگ منتشر نشده است. به‌زودی برمی‌گردیم. +

+ ) : ( + <> +
+ {result.items.map((post) => { + const date = post.publishedAt || post.createdAt; + return ( + + +
+ {date && ( + + {date.slice(0, 10)} + + )} +

+ {post.title || post.nameFa} +

+ {post.summary && ( +

+ {post.summary} +

+ )} +
+ + ); + })} +
+ + `/blog${p > 1 ? `?page=${p}` : ""}`} + /> + + )} +
+ ); +} diff --git a/src/app/fonts.ts b/src/app/fonts.ts new file mode 100644 index 0000000..ff32118 --- /dev/null +++ b/src/app/fonts.ts @@ -0,0 +1,21 @@ +import localFont from "next/font/local"; + +// Site-provided IRANYekan files (public/fonts) — light for body copy, bold +// for headings. Both register under one CSS variable so font-weight alone +// picks the right file. +export const iranYekan = localFont({ + src: [ + { + path: "../../public/fonts/iranyekanweblightfanum.woff", + weight: "300", + style: "normal", + }, + { + path: "../../public/fonts/iranyekanwebboldfanum.woff", + weight: "700", + style: "normal", + }, + ], + variable: "--font-fa", + display: "swap", +}); diff --git a/src/app/globals.css b/src/app/globals.css index a2dc41e..99f3014 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,25 +2,128 @@ :root { --background: #ffffff; - --foreground: #171717; + --foreground: #232323; + + /* Brand palette — lifted from the reference store (deep green + gold on + off-white, dark ink for header/footer). Flat, no gradients. */ + --color-brand: #00593d; + --color-brand-dark: #013d2a; + --color-brand-light: #e7f0ec; + --color-ink: #232323; + --color-ink-soft: #3a3a3a; + --color-body: #5c6873; + --color-gold: #d3a907; + --color-gold-dark: #a98704; + --color-surface: #f9f9f9; + --color-line: #e7e7e7; } @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); - --font-sans: var(--font-geist-sans); - --font-mono: var(--font-geist-mono); -} -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } + --color-brand: var(--color-brand); + --color-brand-dark: var(--color-brand-dark); + --color-brand-light: var(--color-brand-light); + --color-ink: var(--color-ink); + --color-ink-soft: var(--color-ink-soft); + --color-body: var(--color-body); + --color-gold: var(--color-gold); + --color-gold-dark: var(--color-gold-dark); + --color-surface: var(--color-surface); + --color-line: var(--color-line); + + --font-fa: var(--font-fa); + --font-en: var(--font-en); + + --container-boxed: 1320px; } body { background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + color: var(--color-body); + font-family: var(--font-fa), Tahoma, sans-serif; + font-weight: 300; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + color: var(--color-ink); +} + +.font-en { + font-family: var(--font-en), sans-serif; +} + +.boxed { + width: 100%; + max-width: var(--container-boxed); + margin-inline: auto; + padding-inline: 1rem; +} + +@media (min-width: 768px) { + .boxed { + padding-inline: 1.5rem; + } +} + +/* Swiper flat-styling overrides */ +.swiper { + overflow: visible; +} + +.swiper-pagination-bullet { + background: var(--color-line) !important; + opacity: 1 !important; + width: 7px !important; + height: 7px !important; +} + +.swiper-pagination-bullet-active { + background: var(--color-brand) !important; + width: 20px !important; + border-radius: 4px !important; +} + +.hero-swiper .swiper-pagination-bullet { + background: rgba(255, 255, 255, 0.55) !important; +} + +.hero-swiper .swiper-pagination-bullet-active { + background: var(--color-gold) !important; +} + +/* Minimal styling for CMS-authored HTML (product/blog descriptions) */ +.rich-text p { + margin-bottom: 1em; +} + +.rich-text ul, +.rich-text ol { + margin-bottom: 1em; + padding-inline-start: 1.25em; +} + +.rich-text li { + margin-bottom: 0.4em; +} + +.rich-text a { + color: var(--color-brand); + text-decoration: underline; +} + +.rich-text img { + max-width: 100%; + border-radius: 0.75rem; + margin-block: 1em; +} + +.rich-text strong { + color: var(--color-ink); } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9852c15..43eeea4 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,29 +1,38 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import { Rajdhani } from "next/font/google"; import "./globals.css"; +import { iranYekan } from "./fonts"; +import Header from "@/components/Header"; +import Footer from "@/components/Footer"; +import { getCategories, safe } from "@/lib/api"; +import { getMegaMenuColumns } from "@/lib/categoryTree"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", +const rajdhani = Rajdhani({ + variable: "--font-en", subsets: ["latin"], + weight: ["500", "600", "700"], + display: "swap", }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "کودکانه | پوشاک بچگانه", + description: "فروشگاه اینترنتی پوشاک بچگانه، دخترانه و پسرانه با جدیدترین مدل‌ها", }; -export default function RootLayout({ children }: LayoutProps<"/">) { +export default async function RootLayout({ children }: LayoutProps<"/">) { + const categoryColumns = await safe(getCategories().then(getMegaMenuColumns), []); + return ( - {children} + +
+ {children} +