Skip to content

Instantly share code, notes, and snippets.

@elvisxd
Created May 7, 2025 04:56
Show Gist options
  • Save elvisxd/6731af3386342984c5ade31e45982c01 to your computer and use it in GitHub Desktop.
Save elvisxd/6731af3386342984c5ade31e45982c01 to your computer and use it in GitHub Desktop.
types-banner.ts
"use server";
import { cookies } from "next/headers";
import { createClient } from "@/lib/supabase/server";
import type { Banner } from "@/types/banners";
/**
* Obtiene banners activos y dentro del rango de fechas para mostrar en la página principal
* @returns Array de banners ordenados por posición
*/
export async function getBanners(): Promise<Banner[]> {
try {
const cookieStore = cookies();
const supabase = createClient(cookieStore);
// Traer todos los banners activos
const { data, error } = await supabase
.from("banners")
.select("*")
.eq("is_active", true)
.order("position", { ascending: true });
if (error) {
console.error("Error al obtener banners:", error);
return [];
}
// Filtrar por fechas en JS (igual que en products.ts)
const now = new Date().toISOString();
const filtered = (data || []).filter((banner) => {
const startOk = !banner.start_date || banner.start_date <= now;
const endOk = !banner.end_date || banner.end_date >= now;
return startOk && endOk;
});
console.log("BANNERS FILTRADOS PARA HOME:", filtered);
return filtered as Banner[];
} catch (error) {
console.error("Error inesperado al obtener banners:", error);
return [];
}
}
/**
* Obtiene un banner específico por ID
* @param id ID del banner
* @returns Banner o null si no se encuentra o no está activo
*/
export async function getBannerById(id: string): Promise<Banner | null> {
try {
const cookieStore = cookies();
const supabase = createClient(cookieStore);
// Obtener la fecha actual para filtrar
const now = new Date().toISOString();
const { data, error } = await supabase
.from("banners")
.select("*")
.eq("id", id)
.eq("is_active", true)
.or(`start_date.is.null,start_date.lte.${now}`)
.or(`end_date.is.null,end_date.gte.${now}`)
.single();
if (error) {
console.error(`Error al obtener banner con ID ${id}:`, error);
return null;
}
return data as Banner;
} catch (error) {
console.error(`Error inesperado al obtener banner con ID ${id}:`, error);
return null;
}
}
import { getBanners } from "@/app/actions/banner";
import HeroCarousel from "@/components/home/banner-hero-carousel";
import { Skeleton } from "@/components/ui/skeleton";
export default async function HeroCarouselContainer() {
try {
// Obtener banners desde la acción del servidor
const banners = await getBanners();
// Si no hay banners, mostrar un mensaje o espacio reservado
if (!banners || banners.length === 0) {
return (
<div className="w-full h-[300px] flex items-center justify-center bg-gray-100">
<p className="text-muted-foreground">
No hay promociones disponibles
</p>
</div>
);
}
// Renderizar el carrusel con los banners obtenidos
return <HeroCarousel initialBanners={banners} />;
} catch (error) {
console.error("Error al cargar banners:", error);
// UI de fallback en caso de error
return (
<div className="w-full h-[300px] bg-gray-100">
<Skeleton className="w-full h-full" />
</div>
);
}
}
export interface Banner {
id: string;
title: string;
subtitle?: string;
image_url: string;
link_url?: string;
position: number;
is_active?: boolean;
start_date?: string;
end_date?: string;
created_at?: string;
updated_at?: string;
}
import { createServerComponentClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import type { Database } from "@/types/supabase";
export function createClient() {
return createServerComponentClient<Database>({ cookies });
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment