almeira-web/src/components/TopBanner.tsx

85 lines
3.5 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 interval = setInterval(() => {
setCurrentIndex(prev => (prev + 1) % initialBanners.length);
}, rotationSeconds * 1000);
return () => clearInterval(interval);
}, [initialBanners, rotationSeconds]);
if (!initialBanners || initialBanners.length === 0) return null;
const activeBanner = initialBanners[currentIndex];
if (!activeBanner.imagen_destacada_id) 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}/view?project=${PROJECT_ID}`;
} 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}/view?project=${PROJECT_ID}`;
}
}
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 h-[120px] md:h-[180px] lg:h-[220px] 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 h-full ${activeBanner.url_destino ? 'cursor-pointer' : ''}`}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src={imgUrl}
alt={activeBanner.titulo}
className="w-full h-full object-cover 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>
);
}