112 lines
4.7 KiB
TypeScript
112 lines
4.7 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import MetricObserver from './MetricObserver';
|
|
import { ExternalLink, Tag } from 'lucide-react';
|
|
|
|
export default function ClientSidebars({ groupedAds, rotationSeconds }: { groupedAds: Record<string, any>, rotationSeconds: number }) {
|
|
|
|
// Si no hay grupos, no mostrar nada
|
|
const groups = Object.keys(groupedAds);
|
|
if (groups.length === 0) return null;
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{groups.map(eslogan => (
|
|
<ClientCarouselGroup
|
|
key={eslogan}
|
|
eslogan={eslogan}
|
|
ads={groupedAds[eslogan]}
|
|
rotationSeconds={rotationSeconds}
|
|
/>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function ClientCarouselGroup({ eslogan, ads, rotationSeconds }: { eslogan: string, ads: any[], rotationSeconds: number }) {
|
|
const [currentIndex, setCurrentIndex] = useState(0);
|
|
|
|
useEffect(() => {
|
|
if (!ads || ads.length <= 1) return;
|
|
|
|
const interval = setInterval(() => {
|
|
setCurrentIndex(prev => (prev + 1) % ads.length);
|
|
}, rotationSeconds * 1000);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [ads, rotationSeconds]);
|
|
|
|
if (!ads || ads.length === 0) return null;
|
|
|
|
const activeAd = ads[currentIndex];
|
|
if (!activeAd.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 = activeAd.og_image_url || null;
|
|
if (activeAd.imagen_destacada_id) {
|
|
if (typeof activeAd.imagen_destacada_id === 'object' && activeAd.imagen_destacada_id.bucket_id) {
|
|
imgUrl = `${ENDPOINT}/storage/buckets/${activeAd.imagen_destacada_id.bucket_id}/files/${activeAd.imagen_destacada_id.file_id}/view?project=${PROJECT_ID}`;
|
|
} else if (typeof activeAd.imagen_destacada_id === 'string') {
|
|
imgUrl = `${ENDPOINT}/storage/buckets/media/files/${activeAd.imagen_destacada_id}/view?project=${PROJECT_ID}`;
|
|
}
|
|
}
|
|
|
|
const recordClickAndGo = () => {
|
|
fetch('/api/metrics', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ postId: activeAd.$id, tipo: 'click' })
|
|
});
|
|
if (activeAd.url_destino) {
|
|
window.open(activeAd.url_destino, '_blank');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="bg-slate-900 border border-slate-800 rounded-2xl overflow-hidden shadow-xl shadow-purple-500/5 group">
|
|
|
|
{/* Eslogan del Contrato / Patrocinador */}
|
|
<div className="bg-slate-950 px-4 py-2 flex items-center gap-2 border-b border-slate-800">
|
|
<Tag size={12} className="text-pink-500" />
|
|
<span className="text-xs font-bold uppercase tracking-widest text-slate-300 truncate">
|
|
{eslogan !== 'General' ? eslogan : 'Patrocinado'}
|
|
</span>
|
|
</div>
|
|
|
|
{/* Slider de Anuncios */}
|
|
<div className={`relative h-[250px] sm:h-[300px] w-full bg-slate-950 ${activeAd.url_destino ? 'cursor-pointer' : ''}`} onClick={recordClickAndGo}>
|
|
<MetricObserver key={activeAd.$id} postId={activeAd.$id} />
|
|
|
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
<img
|
|
src={imgUrl}
|
|
alt={activeAd.titulo}
|
|
className="w-full h-full object-cover animate-fade-in"
|
|
/>
|
|
|
|
{/* Badge Overlay */}
|
|
<div className="absolute top-2 right-2 bg-black/60 backdrop-blur-md px-2 py-1 rounded text-[10px] font-bold text-cyan-400 uppercase tracking-widest border border-cyan-500/30">
|
|
{activeAd.tipo_publicacion_id?.descripcion || 'Promoción'}
|
|
</div>
|
|
|
|
{activeAd.url_destino && (
|
|
<div className="absolute bottom-2 right-2 bg-black/70 p-1.5 rounded-lg opacity-0 group-hover:opacity-100 transition-opacity">
|
|
<ExternalLink className="text-pink-500" size={16} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Progress/Dots */}
|
|
{ads.length > 1 && (
|
|
<div className="bg-slate-950 py-1.5 flex justify-center gap-1.5 border-t border-slate-800">
|
|
{ads.map((_: any, idx: number) => (
|
|
<div key={idx} className={`h-1 rounded-full transition-all ${idx === currentIndex ? 'w-4 bg-pink-500' : 'w-1 bg-slate-600'}`}></div>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|