203 lines
7.4 KiB
TypeScript
203 lines
7.4 KiB
TypeScript
/* eslint-disable @next/next/no-img-element */
|
|
"use client";
|
|
import React from "react";
|
|
import Link from "next/link";
|
|
import { Banner } from "../lib/types";
|
|
|
|
interface BannerPlacementProps {
|
|
banners: Banner[];
|
|
position: "home_middle" | "home_bottom" | "shop_top" | "category_top" | "product_sidebar";
|
|
className?: string;
|
|
}
|
|
|
|
export default function BannerPlacement({
|
|
banners,
|
|
position,
|
|
className = "",
|
|
}: BannerPlacementProps) {
|
|
const filteredBanners = (banners || []).filter(
|
|
(b) => b.position === position && b.isActive !== false && b.imageUrl
|
|
);
|
|
|
|
if (!filteredBanners || filteredBanners.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
// Multi-column layout for home_middle if 2 or more banners exist
|
|
if (position === "home_middle") {
|
|
return (
|
|
<section className={`py-8 max-w-7xl mx-auto px-4 sm:px-6 font-vazir ${className}`}>
|
|
<div
|
|
className={`grid gap-6 ${
|
|
filteredBanners.length > 1 ? "grid-cols-1 md:grid-cols-2" : "grid-cols-1"
|
|
}`}
|
|
>
|
|
{filteredBanners.map((banner) => {
|
|
const cardContent = (
|
|
<div className="group relative rounded-3xl overflow-hidden shadow-lg hover:shadow-2xl transition-all duration-300 border border-medical-gray-100 bg-white">
|
|
<div className="aspect-[16/7] sm:aspect-[16/6] md:aspect-[16/7] overflow-hidden bg-medical-gray-100 relative">
|
|
<img
|
|
src={banner.imageUrl}
|
|
alt={banner.title || "کنینا بنر"}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
|
loading="lazy"
|
|
/>
|
|
{(banner.title || banner.subtitle) && (
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent p-6 flex flex-col justify-end text-white text-right">
|
|
{banner.title && (
|
|
<h4 className="text-lg sm:text-xl font-black mb-1 leading-tight">
|
|
{banner.title}
|
|
</h4>
|
|
)}
|
|
{banner.subtitle && (
|
|
<p className="text-xs sm:text-sm text-medical-gray-200 font-bold opacity-90 line-clamp-2">
|
|
{banner.subtitle}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
if (banner.linkUrl) {
|
|
const isExternal = banner.linkUrl.startsWith("http");
|
|
if (isExternal) {
|
|
return (
|
|
<a
|
|
key={banner.id}
|
|
href={banner.linkUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block"
|
|
>
|
|
{cardContent}
|
|
</a>
|
|
);
|
|
}
|
|
return (
|
|
<Link key={banner.id} href={banner.linkUrl} className="block">
|
|
{cardContent}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
return <div key={banner.id}>{cardContent}</div>;
|
|
})}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
// Wide banner layout for home_bottom and shop_top
|
|
if (position === "home_bottom" || position === "shop_top" || position === "category_top") {
|
|
return (
|
|
<section className={`py-6 max-w-7xl mx-auto px-4 sm:px-6 font-vazir ${className}`}>
|
|
<div className="space-y-6">
|
|
{filteredBanners.map((banner) => {
|
|
const cardContent = (
|
|
<div className="group relative rounded-3xl overflow-hidden shadow-xl hover:shadow-2xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
|
<div className="aspect-[21/6] sm:aspect-[21/5] min-h-[140px] sm:min-h-[180px] overflow-hidden bg-medical-gray-100 relative">
|
|
<img
|
|
src={banner.imageUrl}
|
|
alt={banner.title || "کنینا"}
|
|
className="w-full h-full object-cover group-hover:scale-103 transition-transform duration-500"
|
|
loading="lazy"
|
|
/>
|
|
{(banner.title || banner.subtitle) && (
|
|
<div className="absolute inset-0 bg-gradient-to-l from-black/80 via-black/40 to-transparent p-6 sm:p-10 flex flex-col justify-center text-white text-right">
|
|
{banner.title && (
|
|
<h4 className="text-xl sm:text-3xl font-black mb-2 leading-tight">
|
|
{banner.title}
|
|
</h4>
|
|
)}
|
|
{banner.subtitle && (
|
|
<p className="text-xs sm:text-base text-medical-gray-200 font-bold max-w-xl">
|
|
{banner.subtitle}
|
|
</p>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
if (banner.linkUrl) {
|
|
const isExternal = banner.linkUrl.startsWith("http");
|
|
if (isExternal) {
|
|
return (
|
|
<a
|
|
key={banner.id}
|
|
href={banner.linkUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block"
|
|
>
|
|
{cardContent}
|
|
</a>
|
|
);
|
|
}
|
|
return (
|
|
<Link key={banner.id} href={banner.linkUrl} className="block">
|
|
{cardContent}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
return <div key={banner.id}>{cardContent}</div>;
|
|
})}
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
// Sidebar Banner Layout
|
|
return (
|
|
<div className={`space-y-4 font-vazir ${className}`}>
|
|
{filteredBanners.map((banner) => {
|
|
const cardContent = (
|
|
<div className="group relative rounded-2xl overflow-hidden shadow-md hover:shadow-xl transition-all duration-300 border border-medical-gray-200 bg-white">
|
|
<div className="aspect-[4/3] overflow-hidden bg-medical-gray-100 relative">
|
|
<img
|
|
src={banner.imageUrl}
|
|
alt={banner.title || "بنر کنینا"}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-500"
|
|
loading="lazy"
|
|
/>
|
|
{banner.title && (
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/80 to-transparent p-4 flex flex-col justify-end text-white text-right">
|
|
<span className="text-xs font-black">{banner.title}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
if (banner.linkUrl) {
|
|
const isExternal = banner.linkUrl.startsWith("http");
|
|
if (isExternal) {
|
|
return (
|
|
<a
|
|
key={banner.id}
|
|
href={banner.linkUrl}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="block"
|
|
>
|
|
{cardContent}
|
|
</a>
|
|
);
|
|
}
|
|
return (
|
|
<Link key={banner.id} href={banner.linkUrl} className="block">
|
|
{cardContent}
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
return <div key={banner.id}>{cardContent}</div>;
|
|
})}
|
|
</div>
|
|
);
|
|
}
|