"use client"; import Image from "next/image"; import React, { useEffect, useState } from "react"; export type EditorJsBlock = { id: string; type: string; data: { text?: string; level?: number; style?: "ordered" | "unordered"; items?: string[]; }; }; type DealerItem = { image: string; url: string; description: string; title: string; }; // Helper function to decode HTML entities function decodeHtmlEntities(text: string): string { const textarea = typeof document !== "undefined" ? document.createElement("textarea") : null; if (textarea) { textarea.innerHTML = text; return textarea.value; } // Fallback for server-side rendering return text .replace(/</g, "<") .replace(/>/g, ">") .replace(/&/g, "&") .replace(/"/g, '"') .replace(/'/g, "'") .replace(/ /g, " "); } // Helper function to check if text contains HTML table elements function isTableFragment(text: string): boolean { const tablePatterns = [ //i, //i, //i, //i, //i, /pattern.test(text)); } // Helper function to parse table HTML and extract dealer data function parseTableToDealers(html: string): DealerItem[] { if (typeof document === "undefined") return []; const parser = new DOMParser(); const doc = parser.parseFromString(html, "text/html"); const rows = doc.querySelectorAll("tr"); const dealers: DealerItem[] = []; rows.forEach((row) => { const cells = row.querySelectorAll("td"); if (cells.length >= 2) { const firstCell = cells[0]; const secondCell = cells[1]; const thirdCell = cells[2]; // Extract image const img = firstCell.querySelector("img"); const imgSrc = img?.getAttribute("src") || ""; // Extract URL and description from second cell const link = secondCell.querySelector("a"); const url = link?.getAttribute("href") || ""; const description = secondCell.textContent?.trim() || ""; const title = thirdCell?.textContent?.trim() || ""; if (imgSrc && url) { dealers.push({ image: imgSrc, url: url, description: description, title: title, }); } } }); return dealers; } // Helper function to merge table fragments function mergeTableBlocks(blocks: EditorJsBlock[]): EditorJsBlock[] { const merged: EditorJsBlock[] = []; let tableBuffer: string[] = []; let tableStartId: string | null = null; let isInTable = false; for (let i = 0; i < blocks.length; i++) { const block = blocks[i]; const text = block.data?.text || ""; const decodedText = decodeHtmlEntities(text); // Check if this starts a table if (/
/i, //i, /
tags and preserve whitespace const cleanedText = decodedText .replace(//gi, "") .replace(/^\s+|\s+$/g, ""); if (cleanedText) { tableBuffer.push(cleanedText); } // Check if this closes the table if (/<\/table>/i.test(decodedText)) { isInTable = false; // Create merged table block const mergedHTML = tableBuffer.join(""); merged.push({ id: tableStartId || block.id, type: "table", data: { text: mergedHTML, }, }); tableBuffer = []; tableStartId = null; } } else { // If we have accumulated table content, create a merged block if (tableBuffer.length > 0 && tableStartId) { const mergedHTML = tableBuffer.join(""); merged.push({ id: tableStartId, type: "table", data: { text: mergedHTML, }, }); tableBuffer = []; tableStartId = null; isInTable = false; } // Add the non-table block merged.push(block); } } // Handle any remaining table content if (tableBuffer.length > 0 && tableStartId) { const mergedHTML = tableBuffer.join(""); merged.push({ id: tableStartId, type: "table", data: { text: mergedHTML, }, }); } return merged; } function DealersList({ blockId, html }: { blockId: string; html: string }) { const [dealers, setDealers] = useState([]); useEffect(() => { const parsedDealers = parseTableToDealers(html); setDealers(parsedDealers); }, [html]); if (dealers.length === 0) { return null; } return (
{dealers.map((dealer, index) => (
{/* Image Container - Fixed size */}
{/* Content Container */}

{dealer.description}

{dealer.title}

))}
); } export default function OnlineDealersRenderer({ content, }: { content: string | null | undefined; }) { let blocks: EditorJsBlock[] = []; if (content) { try { const parsed = JSON.parse(content); if (Array.isArray(parsed?.blocks)) { blocks = parsed.blocks as EditorJsBlock[]; } } catch (_) {} } if (!blocks.length) { return (

Data Not available

); } // Merge table fragments before rendering const mergedBlocks = mergeTableBlocks(blocks); const renderBlock = (block: EditorJsBlock) => { const { type, data } = block; const html = decodeHtmlEntities(data?.text || ""); switch (type) { case "table": return ( ); case "header": { const level = Math.min(Math.max(Number(data?.level) || 3, 1), 6); return React.createElement(`h${level}`, { key: block.id, className: "text-2xl font-semibold leading-8 tracking-[-0.06px] my-6", dangerouslySetInnerHTML: { __html: html }, }); } case "list": { const style = data?.style || "unordered"; const items = Array.isArray(data?.items) ? data.items : []; const ListTag = style === "ordered" ? "ol" : "ul"; const listClassName = style === "ordered" ? "list-none my-4 space-y-2 text-lg leading-7 tracking-[-0.045px]" : "list-none my-4 space-y-2 text-lg leading-7 tracking-[-0.045px]"; return ( {items.map((item, idx) => (
  • ))} ); } case "paragraph": default: // Check if this paragraph contains table HTML that wasn't merged if (isTableFragment(html)) { return ; } return (

    ); } }; return ( <>