reservation style
This commit is contained in:
@@ -20,6 +20,20 @@
|
||||
"title": "دسته بندی ها",
|
||||
"description": "از بین صدها مرکز زیبایی، دقیقا همونی که میخای رو پیدا کن."
|
||||
},
|
||||
"Reservation": {
|
||||
"title": "رزرو خدمات زیبایی، ساده\u200Cتر از همیشه",
|
||||
"stations" : "مراکز معتبر",
|
||||
"online_reserve" : "رزرو انلاین سریع",
|
||||
"start_reserve" : "شروع رزرو",
|
||||
"customer" : "مشتریان",
|
||||
"customer_number" : "+100K",
|
||||
"clinic" : "کلینیک فعال",
|
||||
"clinic_number" : "+336",
|
||||
"salon" : "سالن زیبایی",
|
||||
"salon_number" : "+345",
|
||||
"score" : "امتیازدهی واقعی کاربران",
|
||||
"description": "ما این پلتفرم را ساختیم تا بتوانید بهترین سالن\u200Cهای زیبایی و کلینیک\u200Cهای معتبر را به راحتی پیدا کنید.\n مقایسه، رزرو آنلاین و تجربه\u200Cای بی\u200Cدردسر."
|
||||
},
|
||||
"Application": {
|
||||
"title": "دانلود نرم افزار تلفن همراه 141",
|
||||
"description": "نسخهی تلفن همراه اپلیکیشن مرکز مدیریت راههای کشور با قابلیتهایی نظیر نمایش تصاویر دوربینهای، نظارتی در سراسر کشور، مسیریابی همراه با نمایش مسافت و زمان تقریبی و جزئیات مسیر، مشاهده اخبار متنی و شنیداری، کروکی ترافیک استانهای کشور، دریافت اطلاعیههای مربوط به مسیرهای پرتردد و ... آماده دریافت از مارکتهای مختلف میباشد.",
|
||||
|
||||
BIN
public/images/reservation/reservation.jpg
Normal file
BIN
public/images/reservation/reservation.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 MiB |
160
src/components/Home/Desktop/Reservation/index.tsx
Normal file
160
src/components/Home/Desktop/Reservation/index.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { ArrowTopLeft } from "@/assets";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Reservation() {
|
||||
const t = useTranslations("Reservation");
|
||||
|
||||
return (
|
||||
<section className="w-full my-32 lg:my-40">
|
||||
<div className="container mx-auto px-6">
|
||||
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 80 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.8, ease: "easeOut" }}
|
||||
className="
|
||||
relative
|
||||
bg-primary-50
|
||||
rounded-tr-[60px] md:rounded-tr-[80px]
|
||||
rounded-bl-[60px] md:rounded-bl-[80px]
|
||||
p-8 md:px-12
|
||||
grid
|
||||
gap-16
|
||||
grid-cols-2
|
||||
items-center
|
||||
"
|
||||
>
|
||||
|
||||
{/* ================= TEXT CONTENT ================= */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -40 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.3, duration: 0.7 }}
|
||||
className="text-white space-y-8 order-1 w-full lg:px-10"
|
||||
>
|
||||
<h2 className="text-xl md:text-2xl lg:text-3xl font-bold leading-relaxed">
|
||||
{t("title")}
|
||||
</h2>
|
||||
|
||||
<p className="text-sm md:text-base text-primary-100 leading-8 max-w-xl">
|
||||
{t("description")}
|
||||
</p>
|
||||
|
||||
{/* Features */}
|
||||
<div className="flex flex-wrap items-center gap-x-8 gap-y-4 pt-2 text-sm">
|
||||
{[t("stations"), t("online_reserve"), t("score")].map(
|
||||
(item, i) => (
|
||||
<div key={i} className="flex items-center gap-2">
|
||||
<span className="w-3 h-3 rounded-full bg-primary-200" />
|
||||
<span className="text-xs md:text-sm">{item}</span>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Button */}
|
||||
<motion.button
|
||||
whileHover={{ scale: 1.07 }}
|
||||
whileTap={{ scale: 0.95 }}
|
||||
className="
|
||||
mt-4
|
||||
bg-white
|
||||
flex
|
||||
items-center
|
||||
gap-2
|
||||
text-primary-100
|
||||
px-6
|
||||
py-3
|
||||
rounded-xl
|
||||
font-medium
|
||||
shadow-lg
|
||||
w-fit
|
||||
"
|
||||
>
|
||||
{t("start_reserve")}
|
||||
<ArrowTopLeft className="size-5" />
|
||||
</motion.button>
|
||||
</motion.div>
|
||||
|
||||
{/* ================= IMAGE + STATS ================= */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 60 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ delay: 0.4, duration: 0.9 }}
|
||||
className="relative flex flex-col items-center order-2"
|
||||
>
|
||||
|
||||
{/* Image */}
|
||||
<div
|
||||
className="
|
||||
relative
|
||||
rounded-full
|
||||
overflow-hidden
|
||||
border-8
|
||||
border-white
|
||||
shadow-2xl
|
||||
w-[260px] h-[320px]
|
||||
md:w-[320px] md:h-[420px]
|
||||
lg:w-[450px] lg:h-[580px]
|
||||
"
|
||||
>
|
||||
<Image
|
||||
src="/images/reservation/reservation.jpg"
|
||||
alt="reservation"
|
||||
fill
|
||||
className="object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Stats Card */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ delay: 0.2, duration: 0.6 }}
|
||||
className="
|
||||
mt-8
|
||||
lg:absolute
|
||||
lg:-bottom-16
|
||||
bg-card
|
||||
w-full
|
||||
max-w-md
|
||||
rounded-[40px] md:rounded-[60px]
|
||||
shadow-2xl
|
||||
px-6
|
||||
py-6
|
||||
flex
|
||||
items-center
|
||||
justify-between
|
||||
gap-6
|
||||
"
|
||||
>
|
||||
{[
|
||||
{ number: t("customer_number"), label: t("customer") },
|
||||
{ number: t("clinic_number"), label: t("clinic") },
|
||||
{ number: t("salon_number"), label: t("salon") },
|
||||
].map((item, i) => (
|
||||
<div key={i} className="text-center flex-1">
|
||||
<p className="text-lg md:text-xl font-bold text-text-primary">
|
||||
{item.number}
|
||||
</p>
|
||||
<p className="text-xs md:text-sm text-text-muted mt-1">
|
||||
{item.label}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
|
||||
</motion.div>
|
||||
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import BannerComponent from "./Banner";
|
||||
import Categories from "@/components/Home/Desktop/Categories";
|
||||
import Reservation from "@/components/Home/Desktop/Reservation";
|
||||
|
||||
export default function DesktopHome() {
|
||||
return (
|
||||
<div className="container mx-auto h-full w-full">
|
||||
<BannerComponent />
|
||||
<Categories />
|
||||
<Reservation />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ body {
|
||||
/* =====================
|
||||
Primary (Purple)
|
||||
====================== */
|
||||
--color-primary-50: #140B4E;
|
||||
--color-primary-100: #7d34b9;
|
||||
--color-primary-200: #9a5cff;
|
||||
--color-primary-300: #b38bff;
|
||||
@@ -191,6 +192,7 @@ body {
|
||||
--color-text-muted: #9ca3af;
|
||||
|
||||
--color-primary-100: #b38bff;
|
||||
--color-primary-50: #140B4E;
|
||||
--color-primary-200: #9a5cff;
|
||||
--color-primary-300: #7d34b9;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user