diff --git a/src/app/actions.ts b/src/app/actions.ts index b67897e..cfbe202 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -35,12 +35,15 @@ export async function extractMetaData(url: string) { $('meta[property="og:description"]').attr("content") || $('meta[name="description"]').attr("content") || "No description found"; + const image = $('meta[property="og:image"]').attr("content") || null; - return { data: { title, description } }; + return { data: { title, description, image } }; } catch (error) { console.error(error); - if (error instanceof Error && error.message.includes('Invalid URL')) { - return { error: "The provided URL is not valid. Please check and try again." }; + if (error instanceof Error && error.message.includes("Invalid URL")) { + return { + error: "The provided URL is not valid. Please check and try again.", + }; } return { error: "An unexpected error occurred while fetching the URL." }; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9be16a0..909a613 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,7 @@ import type { Metadata } from "next"; import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "@/components/theme-provider"; +import { Toaster } from "@/components/ui/sonner"; const geistSans = Geist({ variable: "--font-geist-sans", @@ -35,6 +36,7 @@ export default function RootLayout({ disableTransitionOnChange > {children} + diff --git a/src/components/copy-button.tsx b/src/components/copy-button.tsx new file mode 100644 index 0000000..7f32332 --- /dev/null +++ b/src/components/copy-button.tsx @@ -0,0 +1,41 @@ +"use client"; + +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Check, Copy } from "lucide-react"; +import { toast } from "sonner"; + +interface CopyButtonProps { + textToCopy: string; +} + +export function CopyButton({ textToCopy }: CopyButtonProps) { + const [isCopied, setIsCopied] = useState(false); + + const handleCopy = () => { + if (!textToCopy || textToCopy === "Not found") return; + navigator.clipboard.writeText(textToCopy).then(() => { + setIsCopied(true); + toast.success("Copied to clipboard!"); + setTimeout(() => { + setIsCopied(false); + }, 2000); + }); + }; + + return ( + + ); +} \ No newline at end of file diff --git a/src/components/meta-form.tsx b/src/components/meta-form.tsx index e9df71c..bbd19fb 100644 --- a/src/components/meta-form.tsx +++ b/src/components/meta-form.tsx @@ -7,10 +7,12 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Globe } from "lucide-react"; import { extractMetaData } from "@/app/actions"; import { LengthIndicator } from "./length-indicator"; +import { CopyButton } from "./copy-button"; interface MetaData { title: string; description: string; + image?: string | null; } export function MetaForm() { @@ -40,7 +42,10 @@ export function MetaForm() { return (
-
+
-
@@ -67,28 +76,54 @@ export function MetaForm() { {metaData && ( - Extraction Results + + Extraction Results + - + + {metaData.image && ( +
+

+ Preview Image +

+
+ Meta preview image +
+
+ )}
-
-

Meta Title

- +
+
+

+ Meta Title +

+ +
+

{metaData.title || "Not found"}

-
-

Meta Description

- +
+
+

+ Meta Description +

+ +
+

{metaData.description || "Not found"}