"use client" import { useState, useEffect } from "react" import { cn } from "@lib/utils" import { Button } from "@ui/components/button" import { dmSansClassName } from "@/lib/fonts" import { useHotkeys } from "react-hotkeys-hook" import { Image as ImageIcon, Loader2 } from "lucide-react" import { toast } from "sonner" export interface LinkData { url: string title: string description: string image?: string } interface LinkContentProps { onSubmit?: (data: LinkData) => void onDataChange?: (data: LinkData) => void isSubmitting?: boolean isOpen?: boolean } export function LinkContent({ onSubmit, onDataChange, isSubmitting, isOpen, }: LinkContentProps) { const [url, setUrl] = useState("") const [title, setTitle] = useState("") const [description, setDescription] = useState("") const [image, setImage] = useState(undefined) const [isPreviewLoading, setIsPreviewLoading] = useState(false) const canSubmit = url.trim().length > 0 && !isSubmitting const handleSubmit = () => { if (canSubmit && onSubmit) { let normalizedUrl = url.trim() if ( !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") ) { normalizedUrl = `https://${normalizedUrl}` } onSubmit({ url: normalizedUrl, title, description }) } } const updateData = ( newUrl: string, newTitle: string, newDescription: string, newImage?: string, ) => { onDataChange?.({ url: newUrl, title: newTitle, description: newDescription, ...(newImage && { image: newImage }), }) } const handleUrlChange = (newUrl: string) => { setUrl(newUrl) updateData(newUrl, title, description, image) } const handleTitleChange = (newTitle: string) => { setTitle(newTitle) updateData(url, newTitle, description) } const handleDescriptionChange = (newDescription: string) => { setDescription(newDescription) updateData(url, title, newDescription, image) } const handlePreviewLink = async () => { if (!url.trim()) { toast.error("Please enter a URL first") return } let normalizedUrl = url.trim() if ( !normalizedUrl.startsWith("http://") && !normalizedUrl.startsWith("https://") ) { normalizedUrl = `https://${normalizedUrl}` setUrl(normalizedUrl) updateData(normalizedUrl, title, description, image) } setIsPreviewLoading(true) try { const response = await fetch( `/api/og?url=${encodeURIComponent(normalizedUrl)}`, ) if (!response.ok) { const errorData = await response.json().catch(() => ({})) throw new Error(errorData.error || "Failed to fetch preview") } const data = await response.json() const newTitle = data.title || "" const newDescription = data.description || "" const newImage = data.image || undefined setTitle(newTitle) setDescription(newDescription) setImage(newImage) updateData(url, newTitle, newDescription, newImage) if (!newTitle && !newDescription && !newImage) { toast.info("No Open Graph data found for this URL") } else { toast.success("Preview loaded successfully") } } catch (error) { console.error("Preview error:", error) toast.error( error instanceof Error ? error.message : "Failed to load preview", ) } finally { setIsPreviewLoading(false) } } useHotkeys("mod+enter", handleSubmit, { enabled: isOpen && canSubmit, enableOnFormTags: ["INPUT", "TEXTAREA"], }) // Reset content when modal closes useEffect(() => { if (!isOpen) { setUrl("") setTitle("") setDescription("") setImage(undefined) onDataChange?.({ url: "", title: "", description: "" }) } }, [isOpen, onDataChange]) return (

Paste a link to turn it into a memory

handleUrlChange(e.target.value)} placeholder="https://example.com" disabled={isSubmitting} className="w-full p-4 rounded-xl bg-[#14161A] shadow-inside-out disabled:opacity-50 outline-1 outline-transparent focus:outline-[#525D6EB2]" />

Link title

handleTitleChange(e.target.value)} placeholder="Mahesh Sanikommu - Portfolio" disabled className="w-full px-4 py-3 bg-[#0F1217] rounded-xl disabled:opacity-50 outline-1 outline-transparent focus:outline-[#525D6EB2]" />

Link description