96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useState } from "react";
|
||
|
|
import { ChevronLeft, ChevronRight, X } from "lucide-react";
|
||
|
|
import type { CmsPopupContent } from "@/types/cms-landing";
|
||
|
|
|
||
|
|
export default function PopupNewsBanner({
|
||
|
|
popups,
|
||
|
|
}: {
|
||
|
|
popups?: CmsPopupContent[] | null;
|
||
|
|
}) {
|
||
|
|
const list = popups?.filter((p) => p.primary_title?.trim()) ?? [];
|
||
|
|
const [open, setOpen] = useState(true);
|
||
|
|
const [idx, setIdx] = useState(0);
|
||
|
|
|
||
|
|
if (!open || list.length === 0) return null;
|
||
|
|
|
||
|
|
const popup = list[idx % list.length];
|
||
|
|
const img = popup.images?.[0]?.media_url?.trim();
|
||
|
|
|
||
|
|
return (
|
||
|
|
<div className="fixed bottom-6 left-4 right-4 z-[120] mx-auto max-w-lg md:left-auto md:right-6 md:mx-0">
|
||
|
|
<div className="relative overflow-hidden rounded-2xl border border-amber-200 bg-white shadow-2xl">
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
onClick={() => setOpen(false)}
|
||
|
|
className="absolute right-3 top-3 z-10 rounded-full bg-black/5 p-1 text-gray-600 hover:bg-black/10"
|
||
|
|
aria-label="Close"
|
||
|
|
>
|
||
|
|
<X size={18} />
|
||
|
|
</button>
|
||
|
|
{list.length > 1 ? (
|
||
|
|
<>
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
onClick={() => setIdx((i) => (i - 1 + list.length) % list.length)}
|
||
|
|
className="absolute left-2 top-1/2 z-10 -translate-y-1/2 rounded-full bg-black/5 p-1.5 text-gray-700 hover:bg-black/10"
|
||
|
|
aria-label="Previous"
|
||
|
|
>
|
||
|
|
<ChevronLeft size={18} />
|
||
|
|
</button>
|
||
|
|
<button
|
||
|
|
type="button"
|
||
|
|
onClick={() => setIdx((i) => (i + 1) % list.length)}
|
||
|
|
className="absolute right-2 top-1/2 z-10 -translate-y-1/2 rounded-full bg-black/5 p-1.5 text-gray-700 hover:bg-black/10"
|
||
|
|
aria-label="Next"
|
||
|
|
>
|
||
|
|
<ChevronRight size={18} />
|
||
|
|
</button>
|
||
|
|
</>
|
||
|
|
) : null}
|
||
|
|
{img ? (
|
||
|
|
// eslint-disable-next-line @next/next/no-img-element
|
||
|
|
<img src={img} alt="" className="h-32 w-full object-cover md:h-40" />
|
||
|
|
) : null}
|
||
|
|
<div className="p-4 pr-10">
|
||
|
|
<p className="text-xs font-semibold uppercase tracking-wider text-amber-800">
|
||
|
|
{popup.secondary_title || "News"}
|
||
|
|
</p>
|
||
|
|
<h3 className="mt-1 text-lg font-bold text-gray-900">{popup.primary_title}</h3>
|
||
|
|
{popup.description ? (
|
||
|
|
<p className="mt-2 line-clamp-3 text-sm text-gray-600">{popup.description}</p>
|
||
|
|
) : null}
|
||
|
|
<div className="mt-3 flex flex-wrap gap-2">
|
||
|
|
{popup.primary_cta ? (
|
||
|
|
<span className="inline-flex rounded-full bg-[#966314] px-4 py-2 text-xs font-semibold text-white">
|
||
|
|
{popup.primary_cta}
|
||
|
|
</span>
|
||
|
|
) : null}
|
||
|
|
{popup.secondary_cta_text ? (
|
||
|
|
<span className="inline-flex rounded-full border border-[#966314] px-4 py-2 text-xs font-semibold text-[#966314]">
|
||
|
|
{popup.secondary_cta_text}
|
||
|
|
</span>
|
||
|
|
) : null}
|
||
|
|
</div>
|
||
|
|
{list.length > 1 ? (
|
||
|
|
<div className="mt-3 flex justify-center gap-1.5">
|
||
|
|
{list.map((_, i) => (
|
||
|
|
<button
|
||
|
|
key={i}
|
||
|
|
type="button"
|
||
|
|
onClick={() => setIdx(i)}
|
||
|
|
className={`h-1.5 w-1.5 rounded-full ${
|
||
|
|
i === idx % list.length ? "bg-[#966314]" : "bg-gray-300"
|
||
|
|
}`}
|
||
|
|
aria-label={`Go to item ${i + 1}`}
|
||
|
|
/>
|
||
|
|
))}
|
||
|
|
</div>
|
||
|
|
) : null}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|