"use client"; import { motion, AnimatePresence } from "framer-motion"; import { X, MapPin, Calendar, Leaf, CheckCircle2, Factory, Presentation, Image as ImageIcon } from "lucide-react"; import Image from "next/image"; import { useEffect, useState } from "react"; import { useTranslations } from "next-intl"; export interface CaseStudyData { id: string; title: string; location: string; nodeType: string; application: string; stats: string; mediaFileName?: string | null; projectOverview?: string | null; energySavings?: string | null; galleryJson?: string | null; eventDate?: string | null; } interface ModalProps { isOpen: boolean; onClose: () => void; data: CaseStudyData | null; } function nodeToSlug(title: string): string { return title.toLowerCase().trim().replace(/[^\w\s-]/g, '').replace(/[\s_-]+/g, '-').replace(/^-+|-+$/g, ''); } const renderMarkdown = (text: string) => { if (!text) return null; const lines = text.split('\n'); const elements: React.ReactNode[] = []; let listItems: React.ReactNode[] = []; let isOrderedList = false; let inTable = false; let tableHeaders: string[] = []; let tableRows: string[][] = []; const pushTable = () => { if (inTable) { elements.push(
{tableHeaders.map((th, i) => ( ))} {tableRows.map((row, rIdx) => ( {row.map((cell, cIdx) => ( ))} ))}
{parseInline(th)}
{parseInline(cell)}
); inTable = false; tableHeaders = []; tableRows = []; } }; const pushList = () => { if (listItems.length > 0) { elements.push( isOrderedList ? (
    {listItems}
) : ( ) ); listItems = []; } }; const parseInline = (str: string) => { const boldRegex = /\*\*(.*?)\*\*/g; const italicRegex = /\*(.*?)\*/g; let parts = str.split(boldRegex); return parts.map((part, i) => { if (i % 2 === 1) return {part}; let subParts = part.split(italicRegex); return subParts.map((subPart, j) => { if (j % 2 === 1) return {subPart}; return subPart; }); }); }; lines.forEach((line, idx) => { const trimmed = line.trim(); if (!trimmed) { pushList(); pushTable(); return; } if (trimmed.startsWith('|') && trimmed.endsWith('|')) { pushList(); const cells = trimmed.split('|').filter((_, i, arr) => i !== 0 && i !== arr.length - 1).map(c => c.trim()); if (!inTable) { inTable = true; tableHeaders = cells; } else if (cells.every(c => c.match(/^[-:]+$/))) { } else { tableRows.push(cells); } return; } else { pushTable(); } const imgMatch = trimmed.match(/^!\[(.*?)\]\((.*?)\)$/); if (imgMatch) { pushList(); pushTable(); elements.push(
{imgMatch[1]}
); return; } const h3Match = trimmed.match(/^###\s*(.*)/); if (h3Match) { pushList(); pushTable(); elements.push(

{parseInline(h3Match[1])}

); return; } const h2Match = trimmed.match(/^##\s*(.*)/); if (h2Match) { pushList(); pushTable(); elements.push(

{parseInline(h2Match[1])}

); return; } const h1Match = trimmed.match(/^#\s*(.*)/); if (h1Match) { pushList(); pushTable(); elements.push(

{parseInline(h1Match[1])}

); return; } const quoteMatch = trimmed.match(/^>\s*(.*)/); if (quoteMatch) { pushList(); pushTable(); elements.push(
{parseInline(quoteMatch[1])}
); return; } const ulMatch = trimmed.match(/^[-*]\s+(.*)/); if (ulMatch) { isOrderedList = false; listItems.push(
  • {parseInline(ulMatch[1])}
  • ); return; } const olMatch = trimmed.match(/^\d+\.\s*(.*)/); if (olMatch) { isOrderedList = true; listItems.push(
  • {parseInline(olMatch[1])}
  • ); return; } pushList(); elements.push(

    {parseInline(trimmed)}

    ); }); pushList(); pushTable(); return <>{elements}; }; export default function CaseStudyModal({ isOpen, onClose, data }: ModalProps) { const [gallery, setGallery] = useState([]); const t = useTranslations("CaseStudyModal"); useEffect(() => { if (isOpen) document.body.style.overflow = "hidden"; else document.body.style.overflow = "unset"; return () => { document.body.style.overflow = "unset"; }; }, [isOpen]); useEffect(() => { if (data?.galleryJson) { try { setGallery(JSON.parse(data.galleryJson)); } catch (e) { setGallery([]); } } else { setGallery([]); } }, [data]); if (!data) return null; const isEvent = data.nodeType === "event"; const isHQ = data.nodeType === "hq"; const nodeSlug = nodeToSlug(data.title); const coverImage = data.mediaFileName ? `/cases/${nodeSlug}/${data.mediaFileName}` : null; let formattedDate = null; let isUpcoming = false; if (data.eventDate) { const eventD = new Date(data.eventDate); formattedDate = eventD.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); isUpcoming = eventD > new Date(); } return ( {isOpen && (
    {coverImage ? ( {data.title} ) : (
    )}
    {isEvent ? : isHQ ? : } {isEvent ? t("typeEvent") : isHQ ? t("typeHQ") : t("typeInstall")}
    {data.application.replace("-", " ")}

    {data.title}

    {data.location} {formattedDate && ( {formattedDate} {isUpcoming && "(Upcoming)"} )}
    {isEvent ? t("keyHighlight") : t("keyMetric")} {data.stats}
    {data.energySavings && (
    {isEvent ? : } {isEvent ? t("locationStand") : t("energyImpact")} {data.energySavings}
    )}
    {t("systemStatus")} {/* šŸ”„ AQUƍ ESTABA EL ERROR: Simplificamos la lógica šŸ”„ */} {isEvent ? (isUpcoming ? t("scheduled") : t("concluded")) : t("operational")}
    {data.projectOverview ? (

    {isEvent ? t("eventOverview") : t("projectChronicle")}

    {renderMarkdown(data.projectOverview)}
    ) : (

    {t("pendingData")}

    )} {gallery.length > 0 && (

    {t("mediaGallery")}

    {gallery.map((imgSrc, idx) => (
    {`Gallery
    ))}
    )}
    )} ); }