import { AnimatePresence, motion } from "framer-motion"; import { useEffect, useState } from "react"; import { api } from "../lib/api"; import type { ShortLink } from "../lib/types"; import { prettyHost, shortUrl } from "../lib/format"; import { isValidUrl, normalizeUrl } from "../lib/shortcode"; import { Modal } from "./ui/Modal"; import { Button } from "./ui/Button"; interface Props { link: ShortLink | null; onClose: () => void; onSaved: (updated: ShortLink, message: string) => void; } export function EditLinkModal({ link, onClose, onSaved }: Props) { const open = Boolean(link); const [draft, setDraft] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); // Reset the form whenever a different link opens the modal. useEffect(() => { setDraft(link?.longUrl ?? ""); setError(null); setBusy(false); }, [link?.id, link?.longUrl]); if (!link) return ; const changed = normalizeUrl(draft) !== link.longUrl; async function save() { if (!link) return; if (!isValidUrl(draft)) { setError("That doesn't look like a valid URL."); return; } setBusy(true); setError(null); try { const updated = await api.updateLink(link.id, { longUrl: normalizeUrl(draft), }); onSaved(updated, "Link updated"); } catch (e) { setError(e instanceof Error ? e.message : "Could not save changes."); setBusy(false); } } return ( {/* Short code is permanent — shown read-only so existing shares keep working. */}

Short link

{shortUrl(link.code)}

permanent
{ setDraft(e.target.value); if (error) setError(null); }} onKeyDown={(e) => e.key === "Enter" && save()} spellCheck={false} className={`h-11 w-full rounded-xl border bg-surface-2 px-3.5 font-mono text-sm text-ink outline-none transition-colors ${ error ? "border-red-400" : "border-line focus:border-[var(--ink)]" }`} />

Currently points to {prettyHost(link.longUrl)}.

{error && ( {error} )}
); }