"use client"; import React from "react"; import { Badge } from "@/components/ui/badge"; import { Link as LinkIcon, Type, Image as ImageIcon, User, Building, Calendar, HelpCircle, Hash, Text, } from "lucide-react"; const keyMappings: { [key: string]: string } = { "@type": "Type", "@context": "Context", "@id": "ID", name: "Name", headline: "Headline", description: "Description", author: "Author", publisher: "Publisher", mainEntityOfPage: "Main Page", image: "Image", datePublished: "Date Published", dateModified: "Date Modified", acceptedAnswer: "Answer", mainEntity: "Main Content", url: "URL", text: "Text", question: "Question", answer: "Answer", logo: "Logo", telephone: "Telephone", email: "Email", }; const keyIcons: { [key: string]: React.ElementType } = { "@type": Type, "@id": Hash, url: LinkIcon, image: ImageIcon, logo: ImageIcon, author: User, publisher: Building, datePublished: Calendar, dateModified: Calendar, question: HelpCircle, text: Text, }; const renderValue = (value: any, level: number): React.ReactNode => { if (typeof value === "string") { if (value.startsWith("http://") || value.startsWith("https://")) { try { const url = new URL(value); return ( {url.hostname} {url.pathname.length > 1 ? "/..." : ""} ); } catch (e) { return {value}; } } return {value}; } if (typeof value === "object" && value !== null) { if (Array.isArray(value)) { return (
{value.map((item, index) => ( {renderValue(item, level + 1)} ))}
); } return ( ); } return {String(value)}; }; const FaqQuestion = ({ item }: { item: any }) => { if ( item["@type"] === "Question" && item.name && item.acceptedAnswer?.text ) { return (
Question:

{item.name}

Answer:

{item.acceptedAnswer.text}

); } // Fallback for non-standard Q&A items return ; }; const SchemaObjectRenderer = ({ data, isNested = false, level = 0, }: { data: any; isNested?: boolean; level?: number; }) => { const gridClasses = level > 0 ? "md:grid-cols-[10rem_1fr]" : "md:grid-cols-[12rem_1fr]"; const paddingClasses = level > 1 ? "p-1.5" : "p-2"; const content = (
{Object.entries(data).map(([key, value]) => { if (key === "@context") return null; // Custom rendering for FAQPage questions if ( key === "mainEntity" && data["@type"] === "FAQPage" && Array.isArray(value) ) { return (
Questions
{value.map((item, index) => ( ))}
); } const label = keyMappings[key] || key.charAt(0).toUpperCase() + key.slice(1); const Icon = keyIcons[key]; return (
{Icon && } {label}
{key === "@type" ? ( {value as string} ) : ( renderValue(value, level) )}
); })}
); if (isNested) { return (
{content}
); } return content; }; export function PrettySchemaDisplay({ schema }: { schema: any }) { return ; }