canina/frontend/application/components/BannerPlacement.tsx
2026-08-17 09:26:05 +03:30

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>
);
}