"use client"; import { useEffect, useState, useRef } from "react"; import { fetchSettingByCode } from "@/api/serversetting"; import { X, ChevronUp, ChevronsDown } from "lucide-react"; import { ChatInputBox } from "@/components/ChatInputBox/ChatInputBox"; import { VideoCreationForm } from '@/components/pages/create-video/CreateInput'; import { useDeviceType } from '@/hooks/useDeviceType'; export const HOME_BANNER_CODE = "homeBanner"; const HOME_BANNER_COLLAPSE_KEY = "homeBannerCollapsedDate"; /** 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); const [isFlying, setIsFlying] = useState(false); const autoCollapseTimerRef = useRef | null>(null); const skipAutoCollapseRef = useRef(false); const { isMobile, isDesktop } = useDeviceType(); /** Returns YYYY-MM-DD for user's local timezone */ const getLocalDateKey = () => { const now = new Date(); const y = now.getFullYear(); const m = String(now.getMonth() + 1).padStart(2, '0'); const d = String(now.getDate()).padStart(2, '0'); return `${y}-${m}-${d}`; }; const handleDismiss = () => { setIsFlying(true); try { localStorage.setItem(HOME_BANNER_COLLAPSE_KEY, getLocalDateKey()); } catch {} }; const handleBannerClick = () => { if (isFlying) { setIsFlying(false); } }; // Initialize from persisted state: keep collapsed for the rest of the day useEffect(() => { try { const saved = localStorage.getItem(HOME_BANNER_COLLAPSE_KEY); if (saved && saved === getLocalDateKey()) { setIsFlying(true); skipAutoCollapseRef.current = true; } } catch {} }, []); // Auto collapse after mount (2s) unless already collapsed today useEffect(() => { if (skipAutoCollapseRef.current) return; if (autoCollapseTimerRef.current) return; autoCollapseTimerRef.current = setTimeout(() => { setIsFlying(true); try { localStorage.setItem(HOME_BANNER_COLLAPSE_KEY, getLocalDateKey()); } catch {} }, 2000); return () => { if (autoCollapseTimerRef.current) { clearTimeout(autoCollapseTimerRef.current); autoCollapseTimerRef.current = 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 (
{/* Banner overlay - stacked above */}
{backgroundImage ? ( ) : null} {backgroundImage ? (
) : null}
{/* Dismiss button */}
{eyebrow ? ( {eyebrow} ) : null} {title ? (

{title}

) : null} {subtitle ? (

{subtitle}

) : null} {description ? (

{description}

) : null} {ctaLabel ? ( ctaHref ? ( {ctaLabel} ) : ( ) ) : null}
{isFlying ? ( ) : null}
{/* Base content - always present under the banner */}
); }