88 lines
3.8 KiB
TypeScript
88 lines
3.8 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import Link from 'next/link';
|
|
import MetricObserver from './MetricObserver';
|
|
import { ExternalLink } from 'lucide-react';
|
|
|
|
export default function TopBanner({ initialBanners, rotationSeconds }: { initialBanners: any[], rotationSeconds: number }) {
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
useEffect(() => {
|
|
if (!initialBanners || initialBanners.length <= 1) return;
|
|
|
|
const delay = (rotationSeconds && rotationSeconds > 0) ? rotationSeconds * 1000 : 5000;
|
|
|
|
const interval = setInterval(() => {
|
|
setCurrentIndex(prev => (prev + 1) % initialBanners.length);
|
|
}, delay);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [initialBanners, rotationSeconds]);
|
|
|
|
if (!initialBanners || initialBanners.length === 0) return null;
|
|
|
|
const activeBanner = initialBanners[currentIndex];
|
|
|
|
if (!activeBanner.imagen_destacada_id && !activeBanner.og_image_url) return null;
|
|
|
|
const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT || 'https://appwrite.almeira.com.co/v1';
|
|
const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID || '69b84df5003bd8957c5c';
|
|
|
|
let imgUrl = activeBanner.og_image_url || null;
|
|
|
|
if (activeBanner.imagen_destacada_id) {
|
|
if (typeof activeBanner.imagen_destacada_id === 'object' && activeBanner.imagen_destacada_id.bucket_id) {
|
|
imgUrl = `${ENDPOINT}/storage/buckets/${activeBanner.imagen_destacada_id.bucket_id}/files/${activeBanner.imagen_destacada_id.file_id}/preview?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
|
|
} else if (typeof activeBanner.imagen_destacada_id === 'string') {
|
|
// Fallback to 'media' bucket if we only have the ID
|
|
imgUrl = `${ENDPOINT}/storage/buckets/media/files/${activeBanner.imagen_destacada_id}/preview?project=${PROJECT_ID}&width=1920&height=500&quality=85`;
|
|
}
|
|
}
|
|
|
|
if (!imgUrl) return null;
|
|
|
|
const recordClickAndGo = () => {
|
|
fetch('/api/metrics', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ postId: activeBanner.$id, tipo: 'click' })
|
|
});
|
|
if (activeBanner.url_destino) {
|
|
window.open(activeBanner.url_destino, '_blank');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="w-full relative bg-slate-900 border-b border-cyan-500/30 overflow-hidden group">
|
|
|
|
{/* Metric Impression Observer resets key on change to fire new impression */}
|
|
<MetricObserver key={activeBanner.$id} postId={activeBanner.$id} />
|
|
|
|
<div onClick={recordClickAndGo} className={`w-full block flex justify-center ${activeBanner.url_destino ? 'cursor-pointer' : ''}`}>
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img
|
|
key={activeBanner.$id}
|
|
src={imgUrl}
|
|
alt={activeBanner.titulo}
|
|
className="w-full h-auto max-h-[180px] sm:max-h-[250px] md:max-h-[350px] lg:max-h-[450px] object-contain block animate-fade-in"
|
|
/>
|
|
|
|
{activeBanner.url_destino && (
|
|
<div className="absolute top-4 right-4 bg-black/50 backdrop-blur-md p-2 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity">
|
|
<ExternalLink className="text-cyan-400" size={20} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Indicadores */}
|
|
{initialBanners.length > 1 && (
|
|
<div className="absolute bottom-2 left-0 right-0 flex justify-center gap-2">
|
|
{initialBanners.map((_: any, idx: number) => (
|
|
<div key={idx} className={`h-1.5 rounded-full transition-all ${idx === currentIndex ? 'w-6 bg-cyan-400' : 'w-2 bg-slate-400/50'}`}></div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|