chore: add seo reusable component
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
interface SeoPreviewData {
|
||||
seo?: {
|
||||
ogImage?: string;
|
||||
ogTitle?: string;
|
||||
seoTitle?: string;
|
||||
ogDescription?: string;
|
||||
metaDescription?: string;
|
||||
slug?: string;
|
||||
};
|
||||
doctorId?: string;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
interface SeoPreviewProps {
|
||||
open: boolean;
|
||||
onOpenChange: (open: boolean) => void;
|
||||
previewData?: SeoPreviewData | null;
|
||||
url?: string;
|
||||
title?: string;
|
||||
}
|
||||
|
||||
export default function SeoPreview({
|
||||
open,
|
||||
onOpenChange,
|
||||
previewData,
|
||||
url,
|
||||
title = "SEO Preview",
|
||||
}: SeoPreviewProps) {
|
||||
const previewUrl = url || "#";
|
||||
const imageUrl =
|
||||
previewData?.seo?.ogImage || "https://placehold.co/1200x630?text=GG+Hospital";
|
||||
const ogTitle =
|
||||
previewData?.seo?.ogTitle || previewData?.seo?.seoTitle || "GG Hospital";
|
||||
const ogDescription =
|
||||
previewData?.seo?.ogDescription || previewData?.seo?.metaDescription ||
|
||||
"No description available";
|
||||
const searchTitle =
|
||||
previewData?.seo?.seoTitle || previewData?.seo?.ogTitle || "SEO title preview";
|
||||
const searchDescription =
|
||||
previewData?.seo?.metaDescription || previewData?.seo?.ogDescription ||
|
||||
"No meta description available";
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="sm:!max-w-4xl overflow-hidden">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-xl">{title}</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
{previewData ? (
|
||||
<div className="space-y-10 py-2">
|
||||
<div>
|
||||
<p className="mb-4 text-sm font-semibold text-muted-foreground">
|
||||
Social Media Preview (WhatsApp / Facebook)
|
||||
</p>
|
||||
|
||||
<a
|
||||
href={previewUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block max-w-[560px] overflow-hidden rounded-xl border bg-white shadow-sm transition hover:shadow-md"
|
||||
>
|
||||
<div className="aspect-[1.91/1] overflow-hidden bg-muted">
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt="OG Preview"
|
||||
className="h-full w-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="border-t bg-[#f0f2f5] px-4 py-3">
|
||||
<p className="truncate text-[11px] uppercase tracking-wide text-[#65676b]">
|
||||
gg-hospital.com
|
||||
</p>
|
||||
|
||||
<h3 className="mt-1 line-clamp-2 text-[18px] font-semibold leading-snug text-[#1c1e21]">
|
||||
{ogTitle}
|
||||
</h3>
|
||||
|
||||
<p className="mt-1 line-clamp-2 text-[14px] text-[#65676b]">
|
||||
{ogDescription}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p className="mb-4 text-sm font-semibold text-muted-foreground">
|
||||
Google Search Preview
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border bg-white p-6">
|
||||
<a
|
||||
href={previewUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="block"
|
||||
>
|
||||
<p className="truncate text-[14px] text-[#202124] hover:underline">
|
||||
{previewUrl}
|
||||
</p>
|
||||
|
||||
<h3 className="mt-1 text-[22px] leading-tight text-[#1a0dab] hover:underline">
|
||||
{searchTitle}
|
||||
</h3>
|
||||
</a>
|
||||
|
||||
<p className="mt-2 line-clamp-3 text-[14px] leading-6 text-[#4d5156]">
|
||||
{searchDescription}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="p-6 text-sm text-muted-foreground">
|
||||
No preview data available.
|
||||
</div>
|
||||
)}
|
||||
|
||||
<DialogFooter className="p-6 border-t bg-background z-10 mt-0">
|
||||
<Button variant="outline" onClick={() => onOpenChange(false)}>
|
||||
Close
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user