Add Arjmand Pharmacy Next.js homepage.
Initial RTL storefront with header, slider, product sections, and local image assets. Co-authored-by: Cursor <cursoragent@cursor.com>
@@ -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
|
||||||
@@ -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<string, string> = {
|
||||||
|
".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",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||||
|
<rect width="32" height="32" rx="8" fill="#002685"/>
|
||||||
|
<path d="M16 6.5c.6 0 1.1.3 1.4.8l7.2 12.4c.6 1-.1 2.3-1.4 2.3H8.8c-1.3 0-2-1.3-1.4-2.3L14.6 7.3c.3-.5.8-.8 1.4-.8z" fill="#2261FE"/>
|
||||||
|
<circle cx="16" cy="18.2" r="2.1" fill="#fff"/>
|
||||||
|
<rect x="15.2" y="11.4" width="1.6" height="4.2" rx="0.8" fill="#fff"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 383 B |
@@ -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 (
|
||||||
|
<html lang="fa" dir="rtl" className={vazir.variable}>
|
||||||
|
<head>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
|
||||||
|
<link
|
||||||
|
href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap"
|
||||||
|
rel="stylesheet"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body className={`${vazir.className} min-h-screen antialiased`}>{children}</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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 (
|
||||||
|
<>
|
||||||
|
<TopBar />
|
||||||
|
<Header logoSrc={logoSrc} />
|
||||||
|
<main className="pb-12">
|
||||||
|
<Hero slides={slides} />
|
||||||
|
<FeaturedCategories />
|
||||||
|
<SiteFeatures />
|
||||||
|
<ProductCarousel
|
||||||
|
id="special-sale"
|
||||||
|
title="فروش ویژه"
|
||||||
|
subtitle="تخفیفهای منتخب امروز داروخانه"
|
||||||
|
products={specialSale}
|
||||||
|
accent="sale"
|
||||||
|
/>
|
||||||
|
<BannerRow banners={twoBanners} columns={2} />
|
||||||
|
<ProductCarousel
|
||||||
|
id="top-selling"
|
||||||
|
title="پرفروشترین محصولات"
|
||||||
|
subtitle="پیشنهاد ویژه مشتریان"
|
||||||
|
products={topSelling}
|
||||||
|
/>
|
||||||
|
<BannerRow banners={tripleBanners} columns={3} />
|
||||||
|
<ProductCarousel
|
||||||
|
id="yeganeh"
|
||||||
|
title="محصولات برند یگانه"
|
||||||
|
subtitle="مکملهای منتخب Yeganeh"
|
||||||
|
products={yeganehProducts}
|
||||||
|
/>
|
||||||
|
<AboutDoctor />
|
||||||
|
<BlogCarousel />
|
||||||
|
<FaqPreview />
|
||||||
|
</main>
|
||||||
|
<Footer logoSrc={logoSrc} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
export function Container({
|
||||||
|
children,
|
||||||
|
className = "",
|
||||||
|
}: {
|
||||||
|
children: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div className={`mx-auto w-full max-w-[1280px] px-4 sm:px-6 ${className}`}>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
type PlaceholderProps = {
|
||||||
|
src: string;
|
||||||
|
alt?: string;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Placeholder({ src, alt = "", className }: PlaceholderProps) {
|
||||||
|
return (
|
||||||
|
// eslint-disable-next-line @next/next/no-img-element
|
||||||
|
<img src={src} alt={alt} className={className} />
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { about } from "@/lib/data";
|
||||||
|
|
||||||
|
export function AboutDoctor() {
|
||||||
|
return (
|
||||||
|
<section id="about" className="pt-10">
|
||||||
|
<Container>
|
||||||
|
<div className="grid items-center gap-8 overflow-hidden rounded-2xl bg-white p-5 sm:p-8 lg:grid-cols-[0.9fr_1.1fr]">
|
||||||
|
<div className="overflow-hidden rounded-2xl bg-sky">
|
||||||
|
<Placeholder src="/placeholders/doctor.svg" className="aspect-[4/5] w-full object-cover lg:aspect-[4/4.4]" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p className="text-[13px] font-medium text-primary">{about.subtitle}</p>
|
||||||
|
<h2 className="mt-2 text-[22px] font-bold text-navy">{about.title}</h2>
|
||||||
|
{about.body.map((paragraph) => (
|
||||||
|
<p key={paragraph} className="mt-4 text-[14px] leading-8 text-muted">
|
||||||
|
{paragraph}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
<div className="mt-7 grid grid-cols-3 gap-3">
|
||||||
|
{about.stats.map((stat) => (
|
||||||
|
<div key={stat.label} className="rounded-xl bg-sky px-3 py-4 text-center">
|
||||||
|
<p className="font-latin text-[18px] font-bold text-navy">{stat.value}</p>
|
||||||
|
<p className="mt-1 text-[12px] text-muted">{stat.label}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
|
||||||
|
type Banner = { id: string; image: string; href: string };
|
||||||
|
|
||||||
|
export function BannerRow({ banners, columns }: { banners: Banner[]; columns: 2 | 3 }) {
|
||||||
|
return (
|
||||||
|
<section className="pt-8">
|
||||||
|
<Container>
|
||||||
|
<div className={`grid gap-3 ${columns === 3 ? "sm:grid-cols-3" : "sm:grid-cols-2"}`}>
|
||||||
|
{banners.map((banner) => (
|
||||||
|
<Link key={banner.id} href={banner.href} className="overflow-hidden rounded-xl bg-sky">
|
||||||
|
<Placeholder src={banner.image} className="h-[100px] w-full object-cover sm:h-[118px]" />
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRef } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { blogs } from "@/lib/data";
|
||||||
|
|
||||||
|
export function BlogCarousel() {
|
||||||
|
const scroller = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id="blog" className="pt-10">
|
||||||
|
<Container>
|
||||||
|
<div className="mb-4 flex items-center justify-between">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-[18px] font-bold text-navy">آخرین مطالب مجله سلامت</h2>
|
||||||
|
<p className="mt-1 text-[13px] text-muted">نکتههای کاربردی از داروسازان داروخانه</p>
|
||||||
|
</div>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => scroller.current?.scrollBy({ left: 320, behavior: "smooth" })}
|
||||||
|
className="grid size-9 place-items-center rounded-full border border-line bg-white"
|
||||||
|
aria-label="قبلی"
|
||||||
|
>
|
||||||
|
<ChevronRight className="size-4" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => scroller.current?.scrollBy({ left: -320, behavior: "smooth" })}
|
||||||
|
className="grid size-9 place-items-center rounded-full border border-line bg-white"
|
||||||
|
aria-label="بعدی"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div ref={scroller} className="no-scrollbar flex snap-x gap-4 overflow-x-auto">
|
||||||
|
{blogs.map((post) => (
|
||||||
|
<article key={post.id} className="w-[280px] shrink-0 snap-start overflow-hidden rounded-2xl bg-white sm:w-[320px]">
|
||||||
|
<Link href="#" className="block overflow-hidden bg-sky">
|
||||||
|
<Placeholder src={post.image} className="aspect-[16/10] w-full object-cover" />
|
||||||
|
</Link>
|
||||||
|
<div className="p-4">
|
||||||
|
<p className="text-[12px] text-muted">{post.date}</p>
|
||||||
|
<h3 className="mt-2 text-[14px] font-bold leading-7 text-navy">
|
||||||
|
<Link href="#">{post.title}</Link>
|
||||||
|
</h3>
|
||||||
|
<p className="mt-2 line-clamp-2 text-[12.5px] leading-6 text-muted">{post.excerpt}</p>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { faqs } from "@/lib/data";
|
||||||
|
|
||||||
|
export function FaqPreview() {
|
||||||
|
return (
|
||||||
|
<section id="faq" className="pt-10">
|
||||||
|
<Container>
|
||||||
|
<h2 className="mb-4 text-[18px] font-bold text-navy">سوالات متداول</h2>
|
||||||
|
<div className="space-y-3">
|
||||||
|
{faqs.map((item) => (
|
||||||
|
<details key={item.q} className="rounded-2xl bg-white px-5 py-4">
|
||||||
|
<summary className="cursor-pointer list-none text-[14px] font-bold text-navy">
|
||||||
|
{item.q}
|
||||||
|
</summary>
|
||||||
|
<p className="mt-3 text-[13px] leading-7 text-muted">{item.a}</p>
|
||||||
|
</details>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { categories } from "@/lib/data";
|
||||||
|
|
||||||
|
export function FeaturedCategories() {
|
||||||
|
return (
|
||||||
|
<section id="categories" className="pt-10">
|
||||||
|
<Container>
|
||||||
|
<div className="mb-5 flex items-end justify-between">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-[18px] font-bold text-navy">دستهبندیهای منتخب</h2>
|
||||||
|
<p className="mt-1 text-[13px] text-muted">خرید سریع از دستههای پرمخاطب داروخانه</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-4 gap-3 md:grid-cols-8">
|
||||||
|
{categories.map((category) => (
|
||||||
|
<Link
|
||||||
|
key={category.id}
|
||||||
|
href={category.href}
|
||||||
|
className="group flex flex-col items-center gap-2 rounded-2xl bg-white p-3 text-center transition hover:-translate-y-0.5"
|
||||||
|
>
|
||||||
|
<span className="grid size-[72px] place-items-center overflow-hidden rounded-2xl bg-sky sm:size-[84px]">
|
||||||
|
<Placeholder src={category.image} className="size-full object-cover" />
|
||||||
|
</span>
|
||||||
|
<span className="text-[12px] font-medium text-ink group-hover:text-primary sm:text-[13px]">
|
||||||
|
{category.title}
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { heroBanners } from "@/lib/data";
|
||||||
|
import type { Slide } from "@/lib/media";
|
||||||
|
|
||||||
|
export function Hero({ slides }: { slides: Slide[] }) {
|
||||||
|
const [index, setIndex] = useState(0);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (slides.length <= 1) return;
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
setIndex((current) => (current + 1) % slides.length);
|
||||||
|
}, 5000);
|
||||||
|
return () => clearInterval(timer);
|
||||||
|
}, [slides.length]);
|
||||||
|
|
||||||
|
const go = (direction: number) => {
|
||||||
|
if (slides.length <= 1) return;
|
||||||
|
setIndex((current) => (current + direction + slides.length) % slides.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="pt-5">
|
||||||
|
<Container>
|
||||||
|
<div className="relative overflow-hidden rounded-2xl bg-sky">
|
||||||
|
<div className="relative aspect-[16/6] sm:aspect-[16/5.2]">
|
||||||
|
{slides.map((slide, i) => (
|
||||||
|
<Link
|
||||||
|
key={slide.id}
|
||||||
|
href={slide.href}
|
||||||
|
className={`absolute inset-0 transition-opacity duration-500 ${i === index ? "opacity-100" : "pointer-events-none opacity-0"}`}
|
||||||
|
>
|
||||||
|
<Placeholder src={slide.image} className="h-full w-full object-cover" />
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{slides.length > 1 ? (
|
||||||
|
<>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => go(-1)}
|
||||||
|
className="absolute top-1/2 right-3 grid size-9 -translate-y-1/2 place-items-center rounded-full bg-white/90 text-navy"
|
||||||
|
aria-label="اسلاید قبلی"
|
||||||
|
>
|
||||||
|
<ChevronRight className="size-5" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => go(1)}
|
||||||
|
className="absolute top-1/2 left-3 grid size-9 -translate-y-1/2 place-items-center rounded-full bg-white/90 text-navy"
|
||||||
|
aria-label="اسلاید بعدی"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="size-5" />
|
||||||
|
</button>
|
||||||
|
<div className="absolute bottom-3 left-1/2 flex -translate-x-1/2 gap-1.5">
|
||||||
|
{slides.map((slide, i) => (
|
||||||
|
<button
|
||||||
|
key={slide.id}
|
||||||
|
type="button"
|
||||||
|
onClick={() => setIndex(i)}
|
||||||
|
className={`h-1.5 rounded-full transition-all ${i === index ? "w-6 bg-primary" : "w-2 bg-white/80"}`}
|
||||||
|
aria-label={`اسلاید ${i + 1}`}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
|
||||||
|
{heroBanners.map((banner) => (
|
||||||
|
<Link key={banner.id} href={banner.href} className="overflow-hidden rounded-xl bg-sky">
|
||||||
|
<Placeholder src={banner.image} className="h-[92px] w-full object-cover sm:h-[110px]" />
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useRef } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { ProductCard } from "@/components/ui/ProductCard";
|
||||||
|
import type { Product } from "@/lib/data";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
id?: string;
|
||||||
|
title: string;
|
||||||
|
subtitle?: string;
|
||||||
|
href?: string;
|
||||||
|
products: Product[];
|
||||||
|
accent?: "default" | "sale";
|
||||||
|
};
|
||||||
|
|
||||||
|
export function ProductCarousel({
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
subtitle,
|
||||||
|
href = "#",
|
||||||
|
products,
|
||||||
|
accent = "default",
|
||||||
|
}: Props) {
|
||||||
|
const scroller = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const scrollBy = (dir: number) => {
|
||||||
|
scroller.current?.scrollBy({ left: dir * -280, behavior: "smooth" });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section id={id} className="pt-10">
|
||||||
|
<Container>
|
||||||
|
<div
|
||||||
|
className={`rounded-2xl p-4 sm:p-5 ${accent === "sale" ? "bg-[#fff1f4]" : "bg-transparent"}`}
|
||||||
|
>
|
||||||
|
<div className="mb-4 flex items-center justify-between gap-3">
|
||||||
|
<div>
|
||||||
|
<h2 className={`text-[18px] font-bold ${accent === "sale" ? "text-sale" : "text-navy"}`}>
|
||||||
|
{title}
|
||||||
|
</h2>
|
||||||
|
{subtitle ? <p className="mt-1 text-[13px] text-muted">{subtitle}</p> : null}
|
||||||
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => scrollBy(-1)}
|
||||||
|
className="grid size-9 place-items-center rounded-full border border-line bg-white text-navy"
|
||||||
|
aria-label="قبلی"
|
||||||
|
>
|
||||||
|
<ChevronRight className="size-4" />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => scrollBy(1)}
|
||||||
|
className="grid size-9 place-items-center rounded-full border border-line bg-white text-navy"
|
||||||
|
aria-label="بعدی"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="size-4" />
|
||||||
|
</button>
|
||||||
|
<Link href={href} className="hidden text-[13px] text-primary sm:block">
|
||||||
|
مشاهده همه
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
ref={scroller}
|
||||||
|
className="no-scrollbar flex snap-x snap-mandatory gap-3 overflow-x-auto pb-1"
|
||||||
|
>
|
||||||
|
{products.map((product) => (
|
||||||
|
<div key={product.id} className="w-[210px] shrink-0 snap-start sm:w-[230px]">
|
||||||
|
<ProductCard product={product} />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import { Headphones, RefreshCw, ShieldCheck, Truck } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { siteFeatures } from "@/lib/data";
|
||||||
|
|
||||||
|
const icons = {
|
||||||
|
headset: Headphones,
|
||||||
|
shield: ShieldCheck,
|
||||||
|
refresh: RefreshCw,
|
||||||
|
truck: Truck,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function SiteFeatures() {
|
||||||
|
return (
|
||||||
|
<section className="pt-8">
|
||||||
|
<Container>
|
||||||
|
<div className="overflow-hidden rounded-2xl border border-line bg-white">
|
||||||
|
<div className="grid grid-cols-2 divide-x divide-x-reverse divide-line lg:grid-cols-4">
|
||||||
|
{siteFeatures.map((feature) => {
|
||||||
|
const Icon = icons[feature.icon];
|
||||||
|
return (
|
||||||
|
<div key={feature.title} className="flex items-center gap-3 px-5 py-5">
|
||||||
|
<span className="grid size-12 shrink-0 place-items-center rounded-xl bg-sky text-primary">
|
||||||
|
<Icon className="size-6" strokeWidth={1.75} />
|
||||||
|
</span>
|
||||||
|
<div>
|
||||||
|
<h3 className="text-[13.5px] font-bold text-navy">{feature.title}</h3>
|
||||||
|
<p className="mt-0.5 text-[12px] leading-5 text-muted">{feature.text}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { Instagram, MapPin, Phone, Send } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { footerLinks, site } from "@/lib/data";
|
||||||
|
|
||||||
|
export function Footer({ logoSrc }: { logoSrc: string }) {
|
||||||
|
return (
|
||||||
|
<footer id="contact" className="mt-6 bg-navy-deep text-white">
|
||||||
|
<Container className="grid gap-10 py-12 sm:grid-cols-2 lg:grid-cols-4">
|
||||||
|
<div>
|
||||||
|
<Placeholder src={logoSrc} alt={site.name} className="h-10 w-auto object-contain" />
|
||||||
|
<p className="mt-4 text-[13px] leading-7 text-white/75">{site.tagline}. مشاوره دارویی، اصالت کالا و ارسال سریع از سالاریه قم.</p>
|
||||||
|
<div className="mt-5 flex gap-2">
|
||||||
|
<a href={site.instagram} className="grid size-9 place-items-center rounded-lg bg-white/10" aria-label="اینستاگرام">
|
||||||
|
<Instagram className="size-4" />
|
||||||
|
</a>
|
||||||
|
<a href={site.eitaa} className="grid size-9 place-items-center rounded-lg bg-white/10" aria-label="ایتا">
|
||||||
|
<Send className="size-4" />
|
||||||
|
</a>
|
||||||
|
<a href={site.whatsapp} className="grid size-9 place-items-center rounded-lg bg-white/10" aria-label="واتساپ">
|
||||||
|
<Phone className="size-4" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="mb-4 text-[14px] font-bold">فروشگاه</h3>
|
||||||
|
<ul className="space-y-2.5 text-[13px] text-white/75">
|
||||||
|
{footerLinks.shop.map((item) => (
|
||||||
|
<li key={item.title}>
|
||||||
|
<Link href={item.href} className="hover:text-white">
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="mb-4 text-[14px] font-bold">صفحات</h3>
|
||||||
|
<ul className="space-y-2.5 text-[13px] text-white/75">
|
||||||
|
{footerLinks.pages.map((item) => (
|
||||||
|
<li key={item.title}>
|
||||||
|
<Link href={item.href} className="hover:text-white">
|
||||||
|
{item.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h3 className="mb-4 text-[14px] font-bold">تماس با ما</h3>
|
||||||
|
<p className="flex items-start gap-2 text-[13px] leading-7 text-white/75">
|
||||||
|
<MapPin className="mt-1 size-4 shrink-0" />
|
||||||
|
{site.address}
|
||||||
|
</p>
|
||||||
|
<a href={site.phoneHref} className="font-latin mt-3 flex items-center gap-2 text-[13px] text-white/90" dir="ltr">
|
||||||
|
<Phone className="size-4" />
|
||||||
|
{site.phone}
|
||||||
|
</a>
|
||||||
|
<div className="mt-5 flex gap-3">
|
||||||
|
<span className="overflow-hidden rounded-lg bg-white">
|
||||||
|
<Placeholder src="/placeholders/enamad.svg" className="size-16 object-cover" />
|
||||||
|
</span>
|
||||||
|
<span className="overflow-hidden rounded-lg bg-white">
|
||||||
|
<Placeholder src="/placeholders/samandehi.svg" className="size-16 object-cover" />
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
<div className="border-t border-white/10">
|
||||||
|
<Container className="flex h-12 items-center justify-center text-[12px] text-white/55">
|
||||||
|
کلیه حقوق این فروشگاه متعلق به {site.name} است.
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
|
import Link from "next/link";
|
||||||
|
import {
|
||||||
|
ChevronDown,
|
||||||
|
Heart,
|
||||||
|
Menu,
|
||||||
|
Search,
|
||||||
|
ShoppingBag,
|
||||||
|
UserRound,
|
||||||
|
X,
|
||||||
|
} from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { MegaMenu } from "@/components/layout/MegaMenu";
|
||||||
|
import { categories, navLinks, site } from "@/lib/data";
|
||||||
|
|
||||||
|
export function Header({ logoSrc }: { logoSrc: string }) {
|
||||||
|
const [megaOpen, setMegaOpen] = useState(false);
|
||||||
|
const [mobileOpen, setMobileOpen] = useState(false);
|
||||||
|
const [mobileCats, setMobileCats] = useState(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<header className="sticky top-0 z-40 border-b border-line bg-white">
|
||||||
|
<Container className="flex h-[72px] items-center gap-4">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="grid size-10 place-items-center rounded-xl text-navy lg:hidden"
|
||||||
|
onClick={() => setMobileOpen(true)}
|
||||||
|
aria-label="منو"
|
||||||
|
>
|
||||||
|
<Menu className="size-5" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Link href="/" className="flex h-11 shrink-0 items-center">
|
||||||
|
<Placeholder src={logoSrc} alt={site.name} className="h-11 w-auto object-contain" />
|
||||||
|
</Link>
|
||||||
|
|
||||||
|
<form className="relative hidden min-w-0 flex-1 md:block">
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder="جستجوی دارو، مکمل و محصولات بهداشتی..."
|
||||||
|
className="h-11 w-full rounded-xl border border-line bg-mist pr-4 pl-11 text-[13px] outline-none transition focus:border-primary focus:bg-white"
|
||||||
|
/>
|
||||||
|
<Search className="pointer-events-none absolute top-1/2 left-3.5 size-4 -translate-y-1/2 text-muted" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div className="ms-auto flex items-center gap-1">
|
||||||
|
<Link
|
||||||
|
href="#"
|
||||||
|
className="hidden items-center gap-2 rounded-xl px-3 py-2 text-[13px] text-ink hover:bg-mist lg:flex"
|
||||||
|
>
|
||||||
|
<UserRound className="size-5 text-navy" />
|
||||||
|
ورود / ثبتنام
|
||||||
|
</Link>
|
||||||
|
<Link href="#" className="grid size-10 place-items-center rounded-xl hover:bg-mist" aria-label="علاقهمندی">
|
||||||
|
<Heart className="size-5 text-navy" />
|
||||||
|
</Link>
|
||||||
|
<Link href="#" className="relative grid size-10 place-items-center rounded-xl hover:bg-mist" aria-label="سبد خرید">
|
||||||
|
<ShoppingBag className="size-5 text-navy" />
|
||||||
|
<span className="absolute top-1.5 left-1.5 grid size-4 place-items-center rounded-full bg-primary text-[10px] text-white">
|
||||||
|
۰
|
||||||
|
</span>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
|
||||||
|
<div className="hidden border-t border-line lg:block">
|
||||||
|
<Container className="flex h-12 items-center gap-1">
|
||||||
|
<div
|
||||||
|
className="relative"
|
||||||
|
onMouseEnter={() => setMegaOpen(true)}
|
||||||
|
onMouseLeave={() => setMegaOpen(false)}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex h-9 items-center gap-2 rounded-lg bg-navy px-3.5 text-[13px] font-medium text-white"
|
||||||
|
>
|
||||||
|
<Menu className="size-4" />
|
||||||
|
دستهبندیها
|
||||||
|
<ChevronDown className={`size-4 transition ${megaOpen ? "rotate-180" : ""}`} />
|
||||||
|
</button>
|
||||||
|
<MegaMenu open={megaOpen} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
className="rounded-lg px-3 py-2 text-[13px] text-ink transition hover:bg-sky hover:text-primary"
|
||||||
|
>
|
||||||
|
{link.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{mobileOpen && (
|
||||||
|
<div className="fixed inset-0 z-50 lg:hidden">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="absolute inset-0 bg-navy/40"
|
||||||
|
aria-label="بستن"
|
||||||
|
onClick={() => setMobileOpen(false)}
|
||||||
|
/>
|
||||||
|
<aside className="absolute inset-y-0 right-0 flex w-[86%] max-w-sm flex-col bg-white">
|
||||||
|
<div className="flex items-center justify-between border-b border-line px-4 py-3">
|
||||||
|
<Placeholder src={logoSrc} alt={site.name} className="h-9 w-auto object-contain" />
|
||||||
|
<button type="button" onClick={() => setMobileOpen(false)} aria-label="بستن">
|
||||||
|
<X className="size-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<form className="px-4 pt-4">
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
placeholder="جستجو..."
|
||||||
|
className="h-11 w-full rounded-xl border border-line bg-mist px-3 text-[13px] outline-none"
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
<nav className="flex-1 overflow-y-auto px-2 py-3">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="flex w-full items-center justify-between rounded-xl px-3 py-2.5 text-right text-[14px] font-medium text-navy"
|
||||||
|
onClick={() => setMobileCats((v) => !v)}
|
||||||
|
>
|
||||||
|
دستهبندیها
|
||||||
|
<ChevronDown className={`size-4 ${mobileCats ? "rotate-180" : ""}`} />
|
||||||
|
</button>
|
||||||
|
{mobileCats && (
|
||||||
|
<ul className="mb-2 space-y-1 pr-3">
|
||||||
|
{categories.map((cat) => (
|
||||||
|
<li key={cat.id}>
|
||||||
|
<Link href={cat.href} className="block rounded-lg px-3 py-1.5 text-[13px] text-muted">
|
||||||
|
{cat.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
{navLinks.map((link) => (
|
||||||
|
<Link
|
||||||
|
key={link.href}
|
||||||
|
href={link.href}
|
||||||
|
className="block rounded-xl px-3 py-2.5 text-[14px]"
|
||||||
|
onClick={() => setMobileOpen(false)}
|
||||||
|
>
|
||||||
|
{link.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import Link from "next/link";
|
||||||
|
import { categories } from "@/lib/data";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
|
||||||
|
export function MegaMenu({ open }: { open: boolean }) {
|
||||||
|
if (!open) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="absolute top-full right-0 z-50 mt-2 w-[min(920px,calc(100vw-2rem))] rounded-2xl border border-line bg-white p-5 shadow-[0_16px_40px_rgba(0,38,133,0.12)]">
|
||||||
|
<div className="grid grid-cols-2 gap-5 md:grid-cols-4">
|
||||||
|
{categories.map((category) => (
|
||||||
|
<div key={category.id}>
|
||||||
|
<Link
|
||||||
|
href={category.href}
|
||||||
|
className="mb-3 flex items-center gap-2 text-[13.5px] font-semibold text-navy"
|
||||||
|
>
|
||||||
|
<span className="grid size-9 place-items-center overflow-hidden rounded-xl bg-sky">
|
||||||
|
<Placeholder src={category.image} className="size-full object-cover" />
|
||||||
|
</span>
|
||||||
|
{category.title}
|
||||||
|
</Link>
|
||||||
|
<ul className="space-y-1.5 pr-1">
|
||||||
|
{category.children.map((child) => (
|
||||||
|
<li key={child.title}>
|
||||||
|
<Link
|
||||||
|
href={child.href}
|
||||||
|
className="block rounded-lg px-2 py-1 text-[12.5px] text-muted transition hover:bg-sky hover:text-primary"
|
||||||
|
>
|
||||||
|
{child.title}
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { Headphones, MapPin, Truck } from "lucide-react";
|
||||||
|
import { Container } from "@/components/Container";
|
||||||
|
import { site } from "@/lib/data";
|
||||||
|
|
||||||
|
export function TopBar() {
|
||||||
|
return (
|
||||||
|
<div className="bg-navy text-white">
|
||||||
|
<Container className="flex h-10 items-center justify-between gap-4 text-[12px]">
|
||||||
|
<div className="flex min-w-0 items-center gap-4">
|
||||||
|
<span className="hidden items-center gap-1.5 sm:flex">
|
||||||
|
<Truck className="size-3.5 shrink-0" />
|
||||||
|
ارسال رایگان سفارشهای بالای ۵۰۰ هزار تومان
|
||||||
|
</span>
|
||||||
|
<span className="flex items-center gap-1.5">
|
||||||
|
<Headphones className="size-3.5 shrink-0" />
|
||||||
|
{site.hours}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex shrink-0 items-center gap-4">
|
||||||
|
<span className="hidden items-center gap-1.5 md:flex">
|
||||||
|
<MapPin className="size-3.5" />
|
||||||
|
قم، سالاریه
|
||||||
|
</span>
|
||||||
|
<a href={site.phoneHref} className="font-latin tracking-wide" dir="ltr">
|
||||||
|
{site.phone}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import Link from "next/link";
|
||||||
|
import { ShoppingBag } from "lucide-react";
|
||||||
|
import { Placeholder } from "@/components/Placeholder";
|
||||||
|
import { faDigits, formatPrice } from "@/lib/format";
|
||||||
|
import type { Product } from "@/lib/data";
|
||||||
|
|
||||||
|
export function ProductCard({ product }: { product: Product }) {
|
||||||
|
return (
|
||||||
|
<article className="group flex h-full flex-col rounded-2xl bg-white p-3">
|
||||||
|
<Link href="#" className="relative overflow-hidden rounded-xl bg-sky">
|
||||||
|
{product.discount ? (
|
||||||
|
<span className="absolute top-2 right-2 z-10 rounded-md bg-sale px-1.5 py-0.5 text-[11px] font-bold text-white">
|
||||||
|
{faDigits(product.discount)}٪
|
||||||
|
</span>
|
||||||
|
) : null}
|
||||||
|
<Placeholder src={product.image} className="aspect-square w-full object-cover transition group-hover:scale-[1.03]" />
|
||||||
|
</Link>
|
||||||
|
<p className="font-latin mt-3 text-[11px] tracking-wide text-primary">{product.brand}</p>
|
||||||
|
<h3 className="mt-1 line-clamp-2 min-h-[40px] text-[13px] leading-5 text-ink">
|
||||||
|
<Link href="#">{product.title}</Link>
|
||||||
|
</h3>
|
||||||
|
<div className="mt-auto pt-3">
|
||||||
|
{product.oldPrice ? (
|
||||||
|
<p className="text-[11px] text-muted line-through">{formatPrice(product.oldPrice)} تومان</p>
|
||||||
|
) : (
|
||||||
|
<p className="h-[16px]" />
|
||||||
|
)}
|
||||||
|
<div className="mt-1 flex items-end justify-between gap-2">
|
||||||
|
<p className="text-[14px] font-bold text-navy">
|
||||||
|
{formatPrice(product.price)}
|
||||||
|
<span className="mr-1 text-[11px] font-medium text-muted">تومان</span>
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="grid size-9 place-items-center rounded-xl bg-primary text-white transition hover:bg-primary-hover"
|
||||||
|
aria-label="افزودن به سبد خرید"
|
||||||
|
>
|
||||||
|
<ShoppingBag className="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { defineConfig, globalIgnores } from "eslint/config";
|
||||||
|
import nextVitals from "eslint-config-next/core-web-vitals";
|
||||||
|
import nextTs from "eslint-config-next/typescript";
|
||||||
|
|
||||||
|
const eslintConfig = defineConfig([
|
||||||
|
...nextVitals,
|
||||||
|
...nextTs,
|
||||||
|
globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
@@ -0,0 +1,399 @@
|
|||||||
|
export type Product = {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
brand: string;
|
||||||
|
price: number;
|
||||||
|
oldPrice?: number;
|
||||||
|
discount?: number;
|
||||||
|
image: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Category = {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
image: string;
|
||||||
|
href: string;
|
||||||
|
children: { title: string; href: string }[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const site = {
|
||||||
|
name: "داروخانه دکتر ارجمند",
|
||||||
|
englishName: "Arjmand Pharmacy",
|
||||||
|
tagline: "همراه همیشگی سلامت شما",
|
||||||
|
phone: "025-32926171",
|
||||||
|
phoneHref: "tel:+982532926171",
|
||||||
|
whatsapp: "https://wa.me/989123000000",
|
||||||
|
instagram: "https://instagram.com",
|
||||||
|
eitaa: "https://eitaa.com",
|
||||||
|
address: "قم، سالاریه، خیابان بوعلی، پلاک ۲۶۳",
|
||||||
|
hours: "همهروزه ۹ صبح تا ۲۱",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const navLinks = [
|
||||||
|
{ title: "فروش ویژه", href: "#special-sale" },
|
||||||
|
{ title: "درباره ما", href: "#about" },
|
||||||
|
{ title: "سوالات متداول", href: "#faq" },
|
||||||
|
{ title: "تماس با ما", href: "#contact" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const categories: Category[] = [
|
||||||
|
{
|
||||||
|
id: "diet",
|
||||||
|
title: "مکمل رژیمی",
|
||||||
|
image: "/placeholders/category-1.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "کاهش وزن", href: "#" },
|
||||||
|
{ title: "چربیسوز", href: "#" },
|
||||||
|
{ title: "فیبر و پروبیوتیک", href: "#" },
|
||||||
|
{ title: "دتاکس", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sport",
|
||||||
|
title: "مکمل ورزشی",
|
||||||
|
image: "/placeholders/category-2.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "پروتئین وی", href: "#" },
|
||||||
|
{ title: "کراتین", href: "#" },
|
||||||
|
{ title: "آمینو اسید", href: "#" },
|
||||||
|
{ title: "گینر", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hygiene",
|
||||||
|
title: "لوازم بهداشتی",
|
||||||
|
image: "/placeholders/category-3.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "شامپو و بدن", href: "#" },
|
||||||
|
{ title: "دهان و دندان", href: "#" },
|
||||||
|
{ title: "بهداشت بانوان", href: "#" },
|
||||||
|
{ title: "ضدتعریق", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "beauty",
|
||||||
|
title: "لوازم آرایشی",
|
||||||
|
image: "/placeholders/category-4.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "ضدآفتاب", href: "#" },
|
||||||
|
{ title: "مراقبت پوست", href: "#" },
|
||||||
|
{ title: "آرایش صورت", href: "#" },
|
||||||
|
{ title: "آبرسان", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "food",
|
||||||
|
title: "مکمل غذایی",
|
||||||
|
image: "/placeholders/category-5.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "مولتی ویتامین", href: "#" },
|
||||||
|
{ title: "ویتامین D", href: "#" },
|
||||||
|
{ title: "امگا ۳", href: "#" },
|
||||||
|
{ title: "کلسیم و آهن", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "mom",
|
||||||
|
title: "مادر و کودک",
|
||||||
|
image: "/placeholders/category-6.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "شیر خشک", href: "#" },
|
||||||
|
{ title: "قطره آهن کودک", href: "#" },
|
||||||
|
{ title: "پوشک و بهداشتی", href: "#" },
|
||||||
|
{ title: "مکمل بارداری", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "electric",
|
||||||
|
title: "لوازم برقی",
|
||||||
|
image: "/placeholders/category-7.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "فشارسنج", href: "#" },
|
||||||
|
{ title: "تبسنج", href: "#" },
|
||||||
|
{ title: "نبولایزر", href: "#" },
|
||||||
|
{ title: "ماساژور", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "hair",
|
||||||
|
title: "محصولات مو",
|
||||||
|
image: "/placeholders/category-8.svg",
|
||||||
|
href: "#",
|
||||||
|
children: [
|
||||||
|
{ title: "ضدشوره", href: "#" },
|
||||||
|
{ title: "تقویت مو", href: "#" },
|
||||||
|
{ title: "رنگ مو", href: "#" },
|
||||||
|
{ title: "روغن و سرم", href: "#" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const heroBanners = [
|
||||||
|
{ id: "hb1", image: "/placeholders/banner-hero-1.svg", href: "#" },
|
||||||
|
{ id: "hb2", image: "/placeholders/banner-hero-2.svg", href: "#" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const twoBanners = [
|
||||||
|
{ id: "tb1", image: "/placeholders/banner-row-1.svg", href: "#" },
|
||||||
|
{ id: "tb2", image: "/placeholders/banner-row-2.svg", href: "#" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const tripleBanners = [
|
||||||
|
{ id: "tr1", image: "/placeholders/banner-triple-1.svg", href: "#" },
|
||||||
|
{ id: "tr2", image: "/placeholders/banner-triple-2.svg", href: "#" },
|
||||||
|
{ id: "tr3", image: "/placeholders/banner-triple-3.svg", href: "#" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export const siteFeatures = [
|
||||||
|
{
|
||||||
|
title: "پشتیبانی ۲۴ ساعته",
|
||||||
|
text: "آماده پاسخگویی به سوالات شما",
|
||||||
|
icon: "headset",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "اصالت کالا",
|
||||||
|
text: "محصولات تضمینشده و دارای اصالت",
|
||||||
|
icon: "shield",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "مرجوع کالا",
|
||||||
|
text: "امکان مرجوعی کالا طبق شرایط فروشگاه",
|
||||||
|
icon: "refresh",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "تحویل اکسپرس",
|
||||||
|
text: "سریع و مطابق زمانبندی",
|
||||||
|
icon: "truck",
|
||||||
|
},
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
export const specialSale: Product[] = [
|
||||||
|
{
|
||||||
|
id: "sp1",
|
||||||
|
title: "ویتامین D3 یگانه ۱۰۰۰ واحدی ۶۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 248000,
|
||||||
|
oldPrice: 310000,
|
||||||
|
discount: 20,
|
||||||
|
image: "/placeholders/product-1.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sp2",
|
||||||
|
title: "کرم ضدآفتاب لایسل SPF50 بیرنگ ۵۰ میل",
|
||||||
|
brand: "Lisel",
|
||||||
|
price: 389000,
|
||||||
|
oldPrice: 485000,
|
||||||
|
discount: 20,
|
||||||
|
image: "/placeholders/product-2.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sp3",
|
||||||
|
title: "شربت ویتاگلوبین ویتان ۲۰۰ میلیلیتر",
|
||||||
|
brand: "Vitan",
|
||||||
|
price: 265000,
|
||||||
|
oldPrice: 300000,
|
||||||
|
discount: 12,
|
||||||
|
image: "/placeholders/product-3.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sp4",
|
||||||
|
title: "قطره آهن لیپوزوفر فورت بی اس کی ۳۰ میل",
|
||||||
|
brand: "BSK",
|
||||||
|
price: 218000,
|
||||||
|
oldPrice: 250000,
|
||||||
|
discount: 13,
|
||||||
|
image: "/placeholders/product-4.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sp5",
|
||||||
|
title: "امگا ۳ یوروناتال ۶۰ کپسول نرم",
|
||||||
|
brand: "Euronal",
|
||||||
|
price: 412000,
|
||||||
|
oldPrice: 490000,
|
||||||
|
discount: 16,
|
||||||
|
image: "/placeholders/product-5.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "sp6",
|
||||||
|
title: "شامپو ضدشوره سیکاسیر ۲۵۰ میل",
|
||||||
|
brand: "Cicasir",
|
||||||
|
price: 178000,
|
||||||
|
oldPrice: 225000,
|
||||||
|
discount: 21,
|
||||||
|
image: "/placeholders/product-6.svg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const topSelling: Product[] = [
|
||||||
|
{
|
||||||
|
id: "ts1",
|
||||||
|
title: "مولتی ویتامین سنتروم بزرگسالان ۳۰ عددی",
|
||||||
|
brand: "Centrum",
|
||||||
|
price: 534600,
|
||||||
|
oldPrice: 594000,
|
||||||
|
discount: 10,
|
||||||
|
image: "/placeholders/product-7.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ts2",
|
||||||
|
title: "ژل آبرسان هیالورونیک اسید ۵۰ میل",
|
||||||
|
brand: "CeraVe",
|
||||||
|
price: 295000,
|
||||||
|
image: "/placeholders/product-8.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ts3",
|
||||||
|
title: "فشارسنج بازویی دیجیتال امرون M3",
|
||||||
|
brand: "Omron",
|
||||||
|
price: 1890000,
|
||||||
|
image: "/placeholders/product-9.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ts4",
|
||||||
|
title: "پوشک پریما سایز ۴ بسته ۴۶ عددی",
|
||||||
|
brand: "Prima",
|
||||||
|
price: 428000,
|
||||||
|
image: "/placeholders/product-10.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ts5",
|
||||||
|
title: "مسواک برقی اورال بی Vitality",
|
||||||
|
brand: "Oral-B",
|
||||||
|
price: 975000,
|
||||||
|
image: "/placeholders/product-11.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ts6",
|
||||||
|
title: "مام رولی ضدتعریق ۵۰ میل",
|
||||||
|
brand: "Rexona",
|
||||||
|
price: 145000,
|
||||||
|
image: "/placeholders/product-12.svg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const yeganehProducts: Product[] = [
|
||||||
|
{
|
||||||
|
id: "yg1",
|
||||||
|
title: "مولتی ویتامین یگانه بزرگسالان ۳۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 265000,
|
||||||
|
image: "/placeholders/product-13.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "yg2",
|
||||||
|
title: "ویتامین C یگانه ۱۰۰۰ میلیگرم ۶۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 198000,
|
||||||
|
image: "/placeholders/product-14.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "yg3",
|
||||||
|
title: "کلسیم منیزیم زینک یگانه ۶۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 312000,
|
||||||
|
image: "/placeholders/product-15.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "yg4",
|
||||||
|
title: "آهن یگانه ۳۰ میلیگرم ۳۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 187000,
|
||||||
|
image: "/placeholders/product-16.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "yg5",
|
||||||
|
title: "امگا ۳ یگانه ۱۰۰۰ میلیگرم ۶۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 356000,
|
||||||
|
image: "/placeholders/product-17.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "yg6",
|
||||||
|
title: "زینک پلاس یگانه ۱۵ میلیگرم ۳۰ عددی",
|
||||||
|
brand: "Yeganeh",
|
||||||
|
price: 164000,
|
||||||
|
image: "/placeholders/product-18.svg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const blogs = [
|
||||||
|
{
|
||||||
|
id: "b1",
|
||||||
|
title: "راهنمای مصرف ویتامین D در فصل پاییز",
|
||||||
|
excerpt: "چرا کمبود ویتامین D در ماههای کمآفتاب شایع میشود و چطور دوز مناسب را انتخاب کنیم.",
|
||||||
|
date: "۲۴ مرداد ۱۴۰۵",
|
||||||
|
image: "/placeholders/blog-1.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "b2",
|
||||||
|
title: "ضدآفتاب روزانه؛ انتخاب درست برای پوست ایرانی",
|
||||||
|
excerpt: "تفاوت SPF، بافت ژلی و کرم، و نکاتی که قبل از خرید ضدآفتاب باید بدانید.",
|
||||||
|
date: "۱۸ مرداد ۱۴۰۵",
|
||||||
|
image: "/placeholders/blog-2.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "b3",
|
||||||
|
title: "مکملهای ضروری دوران بارداری",
|
||||||
|
excerpt: "فولیک اسید، آهن و امگا ۳؛ چه زمانی و با مشورت داروساز مصرف شوند.",
|
||||||
|
date: "۱۰ مرداد ۱۴۰۵",
|
||||||
|
image: "/placeholders/blog-3.svg",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "b4",
|
||||||
|
title: "تقویت سیستم ایمنی کودکان در مهد و مدرسه",
|
||||||
|
excerpt: "نقش تغذیه، خواب و مکملهای مجاز برای افزایش مقاومت بدن خردسالان.",
|
||||||
|
date: "۲ مرداد ۱۴۰۵",
|
||||||
|
image: "/placeholders/blog-4.svg",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const about = {
|
||||||
|
title: "درباره دکتر ارجمند",
|
||||||
|
subtitle: "داروساز و بنیانگذار داروخانه دکتر ارجمند",
|
||||||
|
body: [
|
||||||
|
"داروخانه دکتر ارجمند با مدیریت دکتر حسین ارجمند، سالهاست در محله سالاریه قم همراه خانوادههاست؛ از مشاوره دارویی دقیق تا تأمین مکمل، بهداشتی و محصولات مادر و کودک.",
|
||||||
|
"هدف ما این است که خرید دارو و محصولات سلامت، هم حضوری و هم آنلاین، ساده، مطمئن و با اصالت کالا باشد. تیم داروسازی ما قبل از ارسال، موجودی و شرایط نگهداری را بررسی میکند تا همان کیفیتی را دریافت کنید که در داروخانه انتظار دارید.",
|
||||||
|
],
|
||||||
|
stats: [
|
||||||
|
{ value: "+۹۰۰۰", label: "تنوع محصول" },
|
||||||
|
{ value: "+۸۵۰۰", label: "مشتری راضی" },
|
||||||
|
{ value: "۲۴/۷", label: "پشتیبانی" },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const faqs = [
|
||||||
|
{
|
||||||
|
q: "ارسال سفارشها چقدر طول میکشد؟",
|
||||||
|
a: "سفارشهای قم معمولاً همانروز یا حداکثر روز بعد ارسال میشوند. برای سایر شهرها ارسال پست پیشتاز بین ۲ تا ۴ روز کاری است.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: "آیا محصولات دارای اصالت هستند؟",
|
||||||
|
a: "بله. تمام داروها و مکملها از توزیعکنندگان مجاز تهیه میشوند و در شرایط استاندارد داروخانه نگهداری میگردند.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
q: "چطور میتوانم مشاوره دارویی بگیرم؟",
|
||||||
|
a: "از طریق تماس تلفنی، واتساپ یا فرم تماس با ما میتوانید با داروساز داروخانه گفتگو کنید.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export const footerLinks = {
|
||||||
|
shop: [
|
||||||
|
{ title: "فروش ویژه", href: "#special-sale" },
|
||||||
|
{ title: "پرفروشترینها", href: "#top-selling" },
|
||||||
|
{ title: "محصولات یگانه", href: "#yeganeh" },
|
||||||
|
{ title: "دستهبندیها", href: "#categories" },
|
||||||
|
],
|
||||||
|
pages: [
|
||||||
|
{ title: "درباره ما", href: "#about" },
|
||||||
|
{ title: "سوالات متداول", href: "#faq" },
|
||||||
|
{ title: "تماس با ما", href: "#contact" },
|
||||||
|
{ title: "مجله سلامت", href: "#blog" },
|
||||||
|
],
|
||||||
|
};
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
export function faDigits(value: string | number) {
|
||||||
|
return String(value).replace(/\d/g, (digit) => "۰۱۲۳۴۵۶۷۸۹"[Number(digit)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatPrice(value: number) {
|
||||||
|
return faDigits(value.toLocaleString("en-US"));
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const IMAGES_ROOT = path.join(process.cwd(), "src/assets/images");
|
||||||
|
const IMAGE_EXT = /\.(jpe?g|png|webp|gif|avif|svg)$/i;
|
||||||
|
|
||||||
|
export type Slide = {
|
||||||
|
id: string;
|
||||||
|
image: string;
|
||||||
|
href: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function listImages(subdir: string) {
|
||||||
|
const dir = path.join(IMAGES_ROOT, subdir);
|
||||||
|
if (!fs.existsSync(dir)) return [];
|
||||||
|
|
||||||
|
return fs
|
||||||
|
.readdirSync(dir)
|
||||||
|
.filter((name) => IMAGE_EXT.test(name) && !name.startsWith("."))
|
||||||
|
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }))
|
||||||
|
.map((file) => `/assets/images/${subdir}/${encodeURIComponent(file)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSlides(): Slide[] {
|
||||||
|
return listImages("slides").map((image, index) => ({
|
||||||
|
id: `slide-${index + 1}`,
|
||||||
|
image,
|
||||||
|
href: "#",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLogoSrc() {
|
||||||
|
return listImages("logo")[0] ?? "/placeholders/logo.svg";
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
|
const nextConfig: NextConfig = {
|
||||||
|
images: {
|
||||||
|
unoptimized: true,
|
||||||
|
},
|
||||||
|
agentRules: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nextConfig;
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "arjmand-pharmacy",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next dev --turbopack",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "eslint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lucide-react": "^0.539.0",
|
||||||
|
"next": "^16.3.1",
|
||||||
|
"react": "^19.2.0",
|
||||||
|
"react-dom": "^19.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@tailwindcss/postcss": "^4.1.12",
|
||||||
|
"@types/node": "^24.3.0",
|
||||||
|
"@types/react": "^19.1.12",
|
||||||
|
"@types/react-dom": "^19.1.9",
|
||||||
|
"eslint": "^9.34.0",
|
||||||
|
"eslint-config-next": "^16.3.1",
|
||||||
|
"tailwindcss": "^4.1.12",
|
||||||
|
"typescript": "^5.9.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
const config = {
|
||||||
|
plugins: {
|
||||||
|
"@tailwindcss/postcss": {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
Create a website for drug store - pharmacy
|
||||||
|
You can inspire from this old website: arjmandpharmacy.com
|
||||||
|
You can use banners, icon and color Pallete from this website
|
||||||
|
|
||||||
|
Create sample content
|
||||||
|
Lang:fa
|
||||||
|
Directions: rtl
|
||||||
|
Use next js
|
||||||
|
Color palette like website
|
||||||
|
use flat design
|
||||||
|
|
||||||
|
Design only homepage
|
||||||
|
Use Persian font like iran-yekan or kalameh or iran sans and some cool kids like English font
|
||||||
|
Do not use images - show only placeholders images - use empty image file so they can be replace easily
|
||||||
|
Do not use text over the images or banners - even slider
|
||||||
|
|
||||||
|
Sections are:
|
||||||
|
1.Top header bar
|
||||||
|
2. Header
|
||||||
|
3. Slider with two banner below - banner height should be small
|
||||||
|
4. Featured categories
|
||||||
|
5. Four features of our website - like old website frame
|
||||||
|
|
||||||
|
6. Product Special sale carousel
|
||||||
|
7. Two banner
|
||||||
|
8. Product Top selling carousel
|
||||||
|
9. 3 banner
|
||||||
|
10. Yeganeh brand product carousel
|
||||||
|
11. About Dr Arjmand
|
||||||
|
12. Latest blog carousel
|
||||||
|
13. footer
|
||||||
|
|
||||||
|
For header, as first item add a categories, show a mega menu for categories
|
||||||
|
Other link are: special sale - about us - faq - contact us
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="200" viewBox="0 0 560 200">
|
||||||
|
<rect width="560" height="200" fill="#E6EEFF"/>
|
||||||
|
<rect x="255.7" y="82.0" width="48.6" height="36.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.2" opacity="0.35"/>
|
||||||
|
<circle cx="280.0" cy="102.2" r="6.5" fill="none" stroke="#2261FE" stroke-width="2.2" opacity="0.35"/>
|
||||||
|
<circle cx="266.4" cy="92.1" r="2.3" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 449 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="560" height="200" viewBox="0 0 560 200">
|
||||||
|
<rect width="560" height="200" fill="#DCE8FF"/>
|
||||||
|
<rect x="255.7" y="82.0" width="48.6" height="36.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.2" opacity="0.35"/>
|
||||||
|
<circle cx="280.0" cy="102.2" r="6.5" fill="none" stroke="#2261FE" stroke-width="2.2" opacity="0.35"/>
|
||||||
|
<circle cx="266.4" cy="92.1" r="2.3" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 449 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="780" height="160" viewBox="0 0 780 160">
|
||||||
|
<rect width="780" height="160" fill="#E8F0FE"/>
|
||||||
|
<rect x="370.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="390.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="379.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="780" height="160" viewBox="0 0 780 160">
|
||||||
|
<rect width="780" height="160" fill="#DDE8FF"/>
|
||||||
|
<rect x="370.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="390.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="379.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="520" height="150" viewBox="0 0 520 150">
|
||||||
|
<rect width="520" height="150" fill="#E4EEFF"/>
|
||||||
|
<rect x="241.8" y="61.5" width="36.5" height="27.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="260.0" cy="76.6" r="4.9" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="249.8" cy="69.1" r="1.7" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="520" height="150" viewBox="0 0 520 150">
|
||||||
|
<rect width="520" height="150" fill="#DCE8FF"/>
|
||||||
|
<rect x="241.8" y="61.5" width="36.5" height="27.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="260.0" cy="76.6" r="4.9" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="249.8" cy="69.1" r="1.7" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="520" height="150" viewBox="0 0 520 150">
|
||||||
|
<rect width="520" height="150" fill="#E8F0FE"/>
|
||||||
|
<rect x="241.8" y="61.5" width="36.5" height="27.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="260.0" cy="76.6" r="4.9" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="249.8" cy="69.1" r="1.7" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 448 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400">
|
||||||
|
<rect width="640" height="400" fill="#EEF3FF"/>
|
||||||
|
<rect x="271.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="320.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="292.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400">
|
||||||
|
<rect width="640" height="400" fill="#EEF3FF"/>
|
||||||
|
<rect x="271.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="320.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="292.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400">
|
||||||
|
<rect width="640" height="400" fill="#EEF3FF"/>
|
||||||
|
<rect x="271.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="320.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="292.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400">
|
||||||
|
<rect width="640" height="400" fill="#EEF3FF"/>
|
||||||
|
<rect x="271.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="320.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="292.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="640" height="400" viewBox="0 0 640 400">
|
||||||
|
<rect width="640" height="400" fill="#EEF3FF"/>
|
||||||
|
<rect x="271.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="320.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="292.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" viewBox="0 0 160 160">
|
||||||
|
<rect width="160" height="160" fill="#EEF3FF"/>
|
||||||
|
<rect x="60.6" y="65.6" width="38.9" height="28.8" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="80.0" cy="81.7" r="5.2" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="69.1" cy="73.7" r="1.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="520" height="640" viewBox="0 0 520 640">
|
||||||
|
<rect width="520" height="640" fill="#E6EEFF"/>
|
||||||
|
<rect x="196.8" y="273.2" width="126.4" height="93.6" rx="7.5" fill="none" stroke="#2261FE" stroke-width="5.6" opacity="0.35"/>
|
||||||
|
<circle cx="260.0" cy="325.6" r="16.8" fill="none" stroke="#2261FE" stroke-width="5.6" opacity="0.35"/>
|
||||||
|
<circle cx="224.6" cy="299.4" r="5.9" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 453 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="90" viewBox="0 0 90 90">
|
||||||
|
<rect width="90" height="90" fill="#F3F7FF"/>
|
||||||
|
<rect x="34.1" y="36.9" width="21.9" height="16.2" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="45.0" cy="46.0" r="2.9" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="38.9" cy="41.4" r="1.0" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 439 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="64" viewBox="0 0 220 64">
|
||||||
|
<rect width="220" height="64" fill="#F5F8FF"/>
|
||||||
|
<rect x="102.2" y="26.2" width="15.6" height="11.5" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="110.0" cy="32.7" r="2.1" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="105.6" cy="29.5" r="0.7" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 445 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
|
||||||
|
<rect width="400" height="400" fill="#F3F7FF"/>
|
||||||
|
<rect x="151.4" y="164.0" width="97.2" height="72.0" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="200.0" cy="204.3" r="13.0" fill="none" stroke="#2261FE" stroke-width="4.3" opacity="0.35"/>
|
||||||
|
<circle cx="172.8" cy="184.2" r="4.5" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 452 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="90" height="90" viewBox="0 0 90 90">
|
||||||
|
<rect width="90" height="90" fill="#F3F7FF"/>
|
||||||
|
<rect x="34.1" y="36.9" width="21.9" height="16.2" rx="6.0" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="45.0" cy="46.0" r="2.9" fill="none" stroke="#2261FE" stroke-width="2.0" opacity="0.35"/>
|
||||||
|
<circle cx="38.9" cy="41.4" r="1.0" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 439 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="420" viewBox="0 0 1200 420">
|
||||||
|
<rect width="1200" height="420" fill="#DCE8FF"/>
|
||||||
|
<rect x="549.0" y="172.2" width="102.1" height="75.6" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="600.0" cy="214.5" r="13.6" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="571.4" cy="193.4" r="4.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 456 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="420" viewBox="0 0 1200 420">
|
||||||
|
<rect width="1200" height="420" fill="#E4EEFF"/>
|
||||||
|
<rect x="549.0" y="172.2" width="102.1" height="75.6" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="600.0" cy="214.5" r="13.6" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="571.4" cy="193.4" r="4.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 456 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="420" viewBox="0 0 1200 420">
|
||||||
|
<rect width="1200" height="420" fill="#D7E4FF"/>
|
||||||
|
<rect x="549.0" y="172.2" width="102.1" height="75.6" rx="6.0" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="600.0" cy="214.5" r="13.6" fill="none" stroke="#2261FE" stroke-width="4.5" opacity="0.35"/>
|
||||||
|
<circle cx="571.4" cy="193.4" r="4.8" fill="#2261FE" opacity="0.28"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 456 B |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 1.7 MiB |
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2017",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"incremental": true,
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"./*"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx",
|
||||||
|
".next/types/**/*.ts",
|
||||||
|
".next/dev/types/**/*.ts"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
||||||