"use client"; import { useEffect, useState } from "react"; import { fetchSettingByCode } from "@/api/serversetting"; export const HOME_BANNER_CODE = "homeBanner"; /** CTA config for banner */ export interface HomeBannerCTAConfig { label?: string; href?: string; [key: string]: unknown; } /** Configuration payload for `HomeBanner` */ export interface HomeBannerConfig { eyebrow?: string; title?: string; subtitle?: string; description?: string; backgroundImage?: string; cta?: HomeBannerCTAConfig; ctaText?: string; ctaLink?: string; [key: string]: unknown; } /** * Renders the home banner with optional background image and CTA. * Pulls configuration from server settings keyed by `HOME_BANNER_CODE`. * @returns React.ReactElement | null */ export default function HomeBanner() { const [config, setConfig] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let active = true; async function load() { setLoading(true); setError(null); try { const value = await fetchSettingByCode(HOME_BANNER_CODE); if (!active) return; setConfig(value ?? null); } catch (err) { if (!active) return; const message = err instanceof Error ? err.message : "Failed to load home banner"; setError(message); setConfig(null); } finally { if (active) { setLoading(false); } } } load(); return () => { active = false; }; }, []); if (loading || error || !config) { // Render nothing until configuration schema is finalized. return null; } const title = typeof config.title === "string" ? config.title : undefined; const subtitle = typeof config.subtitle === "string" ? config.subtitle : undefined; const description = typeof config.description === "string" ? config.description : undefined; const eyebrow = typeof config.eyebrow === "string" ? config.eyebrow : undefined; const backgroundImage = typeof config.backgroundImage === "string" ? config.backgroundImage : undefined; let ctaLabel: string | undefined; let ctaHref: string | undefined; if (config.cta && typeof config.cta === "object") { const { label, href } = config.cta as Record; if (typeof label === "string") ctaLabel = label; if (typeof href === "string") ctaHref = href; } // Support legacy field names until the API contract is confirmed. if (!ctaLabel && typeof config.ctaText === "string") { ctaLabel = config.ctaText; } if (!ctaHref && typeof config.ctaLink === "string") { ctaHref = config.ctaLink; } const hasContent = Boolean(title || subtitle || description || ctaLabel || backgroundImage); if (!hasContent) { return null; } return (
{backgroundImage ? ( ) : null} {backgroundImage ? (
) : null}
{eyebrow ? ( {eyebrow} ) : null} {title ? (

{title}

) : null} {subtitle ? (

{subtitle}

) : null} {description ? (

{description}

) : null} {ctaLabel ? ( ctaHref ? ( {ctaLabel} ) : ( ) ) : null}
); }