Files
spsays-training/components/selection-toolbar/share-modal.tsx
T
2026-05-06 00:40:24 +05:30

145 lines
4.8 KiB
TypeScript

"use client";
import { useCopyFeedback } from "./shared";
import { buildHighlightUrl } from "@/lib/text-highlight";
import { createPortal } from "react-dom";
import { X, MessageSquare, ExternalLink } from "lucide-react";
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerTitle,
} from "@/components/ui/drawer";
export function ShareModal({
open,
onClose,
selectedText,
isMobile,
}: {
open: boolean;
onClose: () => void;
selectedText: string;
isMobile: boolean;
}) {
const { copied, copy } = useCopyFeedback();
const shareOptions = [
{
key: "feed",
label: "Share to Feed",
icon: <MessageSquare className="size-4" />,
description: "Post this quote to your feed",
onClick: () => {
// TODO: Implement share to feed
onClose();
},
},
{
key: "link",
label: "Share Link",
icon: <ExternalLink className="size-4" />,
description: "Copy a shareable link",
onClick: () => {
copy(buildHighlightUrl(selectedText));
},
},
];
if (isMobile) {
return (
<Drawer open={open} onOpenChange={(o) => !o && onClose()}>
<DrawerContent className="bg-black dark:bg-[#1a1a1a] border-white/10">
<DrawerHeader className="text-left border-b border-white/10 pb-4">
<DrawerTitle className="text-white">Share</DrawerTitle>
{selectedText && (
<p className="text-sm text-white/50 mt-1 line-clamp-2">
&ldquo;{selectedText.slice(0, 120)}
{selectedText.length > 120 ? "…" : ""}&rdquo;
</p>
)}
</DrawerHeader>
<div className="p-4 space-y-1">
{shareOptions.map((opt) => (
<button
key={opt.key}
onClick={opt.onClick}
className="flex items-center gap-3 w-full px-3 py-3 rounded-lg text-left hover:bg-white/10 transition-colors"
>
<div className="flex items-center justify-center size-9 rounded-lg bg-amber-400/15 text-amber-400">
{opt.icon}
</div>
<div>
<p className="text-sm font-medium text-white/90">
{opt.key === "link" && copied ? "Link Copied!" : opt.label}
</p>
<p className="text-xs text-white/50">{opt.description}</p>
</div>
</button>
))}
</div>
<div className="p-4 pt-0">
<DrawerClose asChild>
<button className="w-full py-2.5 rounded-lg border border-white/15 text-sm font-medium text-white/60 hover:bg-white/10 transition-colors">
Cancel
</button>
</DrawerClose>
</div>
</DrawerContent>
</Drawer>
);
}
// Desktop modal
if (!open) return null;
return createPortal(
<>
<div
className="fixed inset-0 z-100 bg-black/60 animate-in fade-in-0"
onClick={onClose}
/>
<div className="fixed left-1/2 top-1/2 z-101 w-full max-w-sm -translate-x-1/2 -translate-y-1/2 rounded-xl border border-white/10 bg-black shadow-2xl animate-in fade-in-0 zoom-in-95 dark:bg-[#1a1a1a] dark:border-white/15">
<div className="flex items-center justify-between px-5 py-4 border-b border-white/10">
<h2 className="text-lg font-semibold text-white">Share</h2>
<button
onClick={onClose}
className="flex items-center justify-center size-8 rounded-lg text-white/50 hover:bg-white/10 hover:text-white transition-colors"
>
<X className="size-4" />
</button>
</div>
{selectedText && (
<div className="px-5 py-3 border-b border-white/10">
<p className="text-sm text-white/50 line-clamp-2">
&ldquo;{selectedText.slice(0, 120)}
{selectedText.length > 120 ? "…" : ""}&rdquo;
</p>
</div>
)}
<div className="p-3 space-y-1">
{shareOptions.map((opt) => (
<button
key={opt.key}
onClick={opt.onClick}
className="flex items-center gap-3 w-full px-3 py-3 rounded-lg text-left hover:bg-white/10 transition-colors"
>
<div className="flex items-center justify-center size-9 rounded-lg bg-amber-400/15 text-amber-400">
{opt.icon}
</div>
<div>
<p className="text-sm font-medium text-white/90">
{opt.key === "link" && copied ? "Link Copied!" : opt.label}
</p>
<p className="text-xs text-white/50">{opt.description}</p>
</div>
</button>
))}
</div>
</div>
</>,
document.body,
);
}