[dyad] Added headline extraction and display - wrote 4 file(s)
This commit is contained in:
@@ -7,6 +7,12 @@ interface FaqItem {
|
|||||||
answer: string;
|
answer: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface HeadlineItem {
|
||||||
|
tag: string;
|
||||||
|
text: string;
|
||||||
|
length: number;
|
||||||
|
}
|
||||||
|
|
||||||
export async function extractMetaData(url: string) {
|
export async function extractMetaData(url: string) {
|
||||||
if (!url) {
|
if (!url) {
|
||||||
return { error: "URL is required." };
|
return { error: "URL is required." };
|
||||||
@@ -73,12 +79,26 @@ export async function extractMetaData(url: string) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const headlines: HeadlineItem[] = [];
|
||||||
|
$("h1, h2, h3, h4, h5, h6").each((i, el) => {
|
||||||
|
const tag = $(el).prop("tagName").toLowerCase();
|
||||||
|
const text = $(el).text().trim();
|
||||||
|
if (text) {
|
||||||
|
headlines.push({
|
||||||
|
tag,
|
||||||
|
text,
|
||||||
|
length: text.length,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
image,
|
image,
|
||||||
faq: faqData.length > 0 ? faqData : null,
|
faq: faqData.length > 0 ? faqData : null,
|
||||||
|
headlines: headlines.length > 0 ? headlines : null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
51
src/components/headlines-display.tsx
Normal file
51
src/components/headlines-display.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Table,
|
||||||
|
TableBody,
|
||||||
|
TableCell,
|
||||||
|
TableHead,
|
||||||
|
TableHeader,
|
||||||
|
TableRow,
|
||||||
|
} from "@/components/ui/table";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
|
||||||
|
interface HeadlinesDisplayProps {
|
||||||
|
headlines: {
|
||||||
|
tag: string;
|
||||||
|
text: string;
|
||||||
|
length: number;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HeadlinesDisplay({ headlines }: HeadlinesDisplayProps) {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h3 className="font-semibold text-card-foreground mb-2">Headlines</h3>
|
||||||
|
<div className="border rounded-lg max-h-80 overflow-y-auto relative">
|
||||||
|
<Table>
|
||||||
|
<TableHeader className="sticky top-0 bg-muted/95 backdrop-blur-sm">
|
||||||
|
<TableRow>
|
||||||
|
<TableHead className="w-[80px]">Tag</TableHead>
|
||||||
|
<TableHead>Text</TableHead>
|
||||||
|
<TableHead className="text-right w-[100px]">Length</TableHead>
|
||||||
|
</TableRow>
|
||||||
|
</TableHeader>
|
||||||
|
<TableBody>
|
||||||
|
{headlines.map((headline, index) => (
|
||||||
|
<TableRow key={index}>
|
||||||
|
<TableCell>
|
||||||
|
<Badge variant="secondary" className="uppercase">
|
||||||
|
{headline.tag}
|
||||||
|
</Badge>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell className="font-medium">{headline.text}</TableCell>
|
||||||
|
<TableCell className="text-right">{headline.length}</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
))}
|
||||||
|
</TableBody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -12,12 +12,14 @@ import { CopyButton } from "./copy-button";
|
|||||||
import { SerpPreview } from "./serp-preview";
|
import { SerpPreview } from "./serp-preview";
|
||||||
import { ResultsSkeleton } from "./results-skeleton";
|
import { ResultsSkeleton } from "./results-skeleton";
|
||||||
import { FaqDisplay } from "./faq-display";
|
import { FaqDisplay } from "./faq-display";
|
||||||
|
import { HeadlinesDisplay } from "./headlines-display";
|
||||||
|
|
||||||
interface MetaData {
|
interface MetaData {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
image?: string | null;
|
image?: string | null;
|
||||||
faq?: { question: string; answer: string }[] | null;
|
faq?: { question: string; answer: string }[] | null;
|
||||||
|
headlines?: { tag: string; text: string; length: number }[] | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function MetaForm() {
|
export function MetaForm() {
|
||||||
@@ -271,6 +273,9 @@ export function MetaForm() {
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{metaData.headlines && metaData.headlines.length > 0 && (
|
||||||
|
<HeadlinesDisplay headlines={metaData.headlines} />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@@ -63,6 +63,15 @@ export function ResultsSkeleton() {
|
|||||||
<Skeleton className="h-4 w-full mb-2" />
|
<Skeleton className="h-4 w-full mb-2" />
|
||||||
<Skeleton className="h-24 w-full" />
|
<Skeleton className="h-24 w-full" />
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<Skeleton className="h-5 w-24 mb-2" />
|
||||||
|
<div className="border rounded-lg p-2 space-y-2">
|
||||||
|
<Skeleton className="h-8 w-full" />
|
||||||
|
<Skeleton className="h-8 w-full" />
|
||||||
|
<Skeleton className="h-8 w-full" />
|
||||||
|
<Skeleton className="h-8 w-full" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
Reference in New Issue
Block a user