[dyad] Grouped schemas into collapsible sections - wrote 1 file(s)

This commit is contained in:
[dyad]
2026-01-20 15:03:08 +01:00
parent 596c2643d4
commit 80a88e20f2

View File

@@ -8,49 +8,95 @@ import {
} from "@/components/ui/accordion"; } from "@/components/ui/accordion";
import { CopyButton } from "./copy-button"; import { CopyButton } from "./copy-button";
import { PrettySchemaDisplay } from "./pretty-schema-display"; import { PrettySchemaDisplay } from "./pretty-schema-display";
import { Badge } from "@/components/ui/badge";
interface SchemaDisplayProps { interface SchemaDisplayProps {
schemas: any[]; schemas: any[];
} }
export function SchemaDisplay({ schemas }: SchemaDisplayProps) { export function SchemaDisplay({ schemas }: SchemaDisplayProps) {
const groupedSchemas = schemas.reduce((acc, schema) => {
const type = Array.isArray(schema["@type"])
? schema["@type"].join(", ")
: schema["@type"] || "Untyped";
if (!acc[type]) {
acc[type] = [];
}
acc[type].push(schema);
return acc;
}, {} as Record<string, any[]>);
const SchemaContent = ({ schema }: { schema: any }) => {
const schemaJson = JSON.stringify(schema, null, 2);
return (
<>
<div className="border-t pt-4 mb-4">
<div className="flex justify-end items-center gap-2">
<span className="text-sm text-muted-foreground">
Copy Raw JSON
</span>
<CopyButton textToCopy={schemaJson} />
</div>
</div>
<PrettySchemaDisplay schema={schema} />
</>
);
};
return ( return (
<div className="space-y-4"> <div className="space-y-4">
<div className="flex justify-between items-center p-4 bg-muted/50 rounded-lg"> <div className="flex justify-between items-center p-4 bg-muted/50 rounded-lg">
<p className="text-sm font-medium"> <p className="text-sm font-medium">
Found {schemas.length} schema block{schemas.length > 1 ? "s" : ""} on Found {schemas.length} schema block{schemas.length > 1 ? "s" : ""} in{" "}
this page. {Object.keys(groupedSchemas).length} type
{Object.keys(groupedSchemas).length > 1 ? "s" : ""}.
</p> </p>
<p className="text-sm text-muted-foreground">Expand to see details.</p> <p className="text-sm text-muted-foreground">Expand to see details.</p>
</div> </div>
<Accordion type="single" collapsible className="w-full space-y-4"> <Accordion type="multiple" className="w-full space-y-4">
{schemas.map((schema, index) => { {Object.entries(groupedSchemas).map(
const schemaType = schema["@type"] || `Schema Block ${index + 1}`; ([type, schemaGroup], groupIndex) => (
const schemaJson = JSON.stringify(schema, null, 2);
return (
<AccordionItem <AccordionItem
value={`item-${index}`} value={`group-${type}-${groupIndex}`}
key={index} key={groupIndex}
className="border rounded-lg bg-background shadow-sm" className="border rounded-lg bg-background shadow-sm"
> >
<AccordionTrigger className="px-6 hover:no-underline text-left"> <AccordionTrigger className="px-6 hover:no-underline text-left">
<span className="font-semibold">{schemaType}</span> <div className="flex items-center gap-3">
</AccordionTrigger> <span className="font-semibold">{type}</span>
<AccordionContent className="px-6 pt-0"> <Badge variant="secondary">{schemaGroup.length}</Badge>
<div className="border-t pt-4 mb-4">
<div className="flex justify-end items-center gap-2">
<span className="text-sm text-muted-foreground">
Copy Raw JSON
</span>
<CopyButton textToCopy={schemaJson} />
</div>
</div> </div>
<PrettySchemaDisplay schema={schema} /> </AccordionTrigger>
<AccordionContent className="px-6 pb-6 pt-0">
{schemaGroup.length > 1 ? (
<div className="border-t pt-4">
<Accordion
type="multiple"
className="w-full space-y-2"
>
{schemaGroup.map((schema, schemaIndex) => (
<AccordionItem
value={`schema-${groupIndex}-${schemaIndex}`}
key={schemaIndex}
className="border rounded-lg bg-muted/50"
>
<AccordionTrigger className="px-4 py-3 hover:no-underline text-sm font-medium">
{type} #{schemaIndex + 1}
</AccordionTrigger>
<AccordionContent className="p-4 bg-background rounded-b-lg">
<SchemaContent schema={schema} />
</AccordionContent>
</AccordionItem>
))}
</Accordion>
</div>
) : (
<SchemaContent schema={schemaGroup[0]} />
)}
</AccordionContent> </AccordionContent>
</AccordionItem> </AccordionItem>
); )
})} )}
</Accordion> </Accordion>
</div> </div>
); );