commit cd2f9dfc9d8518bb2d2a3d2bc017050f24ff4ee5 Author: Alireza Hassani Date: Sun Aug 16 17:15:14 2026 +0330 Add Arjmand Pharmacy Next.js homepage. Initial RTL storefront with header, slider, product sections, and local image assets. Co-authored-by: Cursor diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bfff00 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* + +# next +/.next/ +/out/ + +# misc +.DS_Store +*.pem +npm-debug.log* +.env* +.vercel +next-env.d.ts diff --git a/app/assets/images/[...path]/route.ts b/app/assets/images/[...path]/route.ts new file mode 100644 index 0000000..42222ad --- /dev/null +++ b/app/assets/images/[...path]/route.ts @@ -0,0 +1,37 @@ +import { NextRequest } from "next/server"; +import fs from "fs"; +import path from "path"; + +const IMAGES_ROOT = path.join(process.cwd(), "src/assets/images"); + +const MIME: Record = { + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".webp": "image/webp", + ".gif": "image/gif", + ".avif": "image/avif", + ".svg": "image/svg+xml", +}; + +export async function GET( + _request: NextRequest, + { params }: { params: Promise<{ path: string[] }> }, +) { + const segments = (await params).path.map((part) => decodeURIComponent(part)); + const filePath = path.resolve(IMAGES_ROOT, ...segments); + + if (!filePath.startsWith(IMAGES_ROOT + path.sep) || !fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) { + return new Response("Not found", { status: 404 }); + } + + const ext = path.extname(filePath).toLowerCase(); + const body = fs.readFileSync(filePath); + + return new Response(body, { + headers: { + "Content-Type": MIME[ext] ?? "application/octet-stream", + "Cache-Control": "public, max-age=3600", + }, + }); +} diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..53ad06d --- /dev/null +++ b/app/globals.css @@ -0,0 +1,60 @@ +@import "tailwindcss"; + +:root { + --primary: #2261fe; + --primary-hover: #1a52e0; + --navy: #002685; + --navy-deep: #001a5c; + --sky: #e8f0fe; + --mist: #f4f7fc; + --text: #1a2332; + --muted: #64748b; + --line: #e3eaf6; + --sale: #e11d48; + --ok: #0d9488; +} + +@theme inline { + --color-primary: var(--primary); + --color-primary-hover: var(--primary-hover); + --color-navy: var(--navy); + --color-navy-deep: var(--navy-deep); + --color-sky: var(--sky); + --color-mist: var(--mist); + --color-ink: var(--text); + --color-muted: var(--muted); + --color-line: var(--line); + --color-sale: var(--sale); + --color-ok: var(--ok); + --font-sans: var(--font-vazir), Tahoma, sans-serif; + --font-latin: "Fredoka", var(--font-vazir), sans-serif; +} + +html { + scroll-behavior: smooth; +} + +body { + background: var(--mist); + color: var(--text); + font-family: var(--font-sans); +} + +.font-latin { + font-family: var(--font-latin); +} + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +.no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; +} + +input, +button, +textarea { + font-family: inherit; +} diff --git a/app/icon.svg b/app/icon.svg new file mode 100644 index 0000000..4a49710 --- /dev/null +++ b/app/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..dfb7013 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,33 @@ +import type { Metadata } from "next"; +import { Vazirmatn } from "next/font/google"; +import "./globals.css"; + +const vazir = Vazirmatn({ + subsets: ["arabic", "latin"], + variable: "--font-vazir", + display: "swap", + weight: ["300", "400", "500", "600", "700", "800"], +}); + +export const metadata: Metadata = { + title: "داروخانه دکتر ارجمند | صفحه اصلی", + description: + "خرید آنلاین دارو، مکمل، محصولات بهداشتی و آرایشی از داروخانه دکتر ارجمند در قم، سالاریه.", +}; + +export default function RootLayout({ children }: { children: React.ReactNode }) { + return ( + + + + + + + {children} + + ); +} + diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..e5dee7d --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,55 @@ +import { TopBar } from "@/components/layout/TopBar"; +import { Header } from "@/components/layout/Header"; +import { Footer } from "@/components/layout/Footer"; +import { Hero } from "@/components/home/Hero"; +import { FeaturedCategories } from "@/components/home/FeaturedCategories"; +import { SiteFeatures } from "@/components/home/SiteFeatures"; +import { ProductCarousel } from "@/components/home/ProductCarousel"; +import { BannerRow } from "@/components/home/BannerRow"; +import { AboutDoctor } from "@/components/home/AboutDoctor"; +import { BlogCarousel } from "@/components/home/BlogCarousel"; +import { FaqPreview } from "@/components/home/FaqPreview"; +import { specialSale, topSelling, twoBanners, tripleBanners, yeganehProducts } from "@/lib/data"; +import { getLogoSrc, getSlides } from "@/lib/media"; + +export default function HomePage() { + const slides = getSlides(); + const logoSrc = getLogoSrc(); + + return ( + <> + +
+
+ + + + + + + + + + + +
+