76 lines
3.2 KiB
TypeScript
76 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import Image from 'next/image';
|
|
import Link from 'next/link';
|
|
|
|
interface VisualLinkPreviewProps {
|
|
url: string;
|
|
title: string;
|
|
summary: string;
|
|
image: string;
|
|
}
|
|
|
|
export default function VisualLinkPreview({ url, title, summary, image }: VisualLinkPreviewProps) {
|
|
const hostname = (() => {
|
|
try {
|
|
return new URL(url).hostname;
|
|
} catch {
|
|
return url;
|
|
}
|
|
})();
|
|
|
|
return (
|
|
<Link href={url} target="_blank" rel="noopener noreferrer" className="block my-12 no-underline group">
|
|
<div className="flex flex-col md:flex-row border border-neutral-200 rounded-2xl overflow-hidden bg-white transition-all duration-500 hover:shadow-2xl hover:border-primary/20 hover:-translate-y-1 group">
|
|
<div className="relative w-full md:w-64 h-48 md:h-auto flex-shrink-0 bg-neutral-50 overflow-hidden">
|
|
{image ? (
|
|
<Image
|
|
src={image}
|
|
alt={title}
|
|
fill
|
|
unoptimized
|
|
className="object-cover transition-transform duration-700 group-hover:scale-110"
|
|
/>
|
|
) : (
|
|
<div className="w-full h-full flex items-center justify-center bg-primary/5">
|
|
<svg className="w-12 h-12 text-primary/20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" />
|
|
</svg>
|
|
</div>
|
|
)}
|
|
{/* Industrial overlay */}
|
|
<div className="absolute inset-0 bg-primary/10 opacity-0 group-hover:opacity-100 transition-opacity duration-500 pointer-events-none" />
|
|
</div>
|
|
|
|
<div className="p-8 flex flex-col justify-center relative">
|
|
{/* Industrial accent corner */}
|
|
<div className="absolute top-0 right-0 w-12 h-12 bg-primary/5 -mr-6 -mt-6 rotate-45 transition-transform group-hover:scale-110" />
|
|
|
|
<div className="flex items-center gap-2 mb-3">
|
|
<span className="text-[10px] font-bold uppercase tracking-[0.2em] text-primary/60 bg-primary/5 px-2 py-0.5 rounded">
|
|
External Link
|
|
</span>
|
|
<span className="text-[10px] font-bold uppercase tracking-[0.2em] text-text-secondary/40">
|
|
{hostname}
|
|
</span>
|
|
</div>
|
|
|
|
<h3 className="text-xl font-bold text-text-primary mb-3 group-hover:text-primary transition-colors line-clamp-2 leading-tight">
|
|
{title}
|
|
</h3>
|
|
|
|
<p className="text-text-secondary text-base line-clamp-2 leading-relaxed mb-4">
|
|
{summary}
|
|
</p>
|
|
|
|
<div className="flex items-center gap-2 text-primary font-bold text-xs uppercase tracking-widest">
|
|
<span>Read more</span>
|
|
<svg className="w-4 h-4 transition-transform group-hover:translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 8l4 4m0 0l-4 4m4-4H3" />
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
);
|
|
}
|