import { useState, useEffect } from 'react' import { X, Copy, Check, Link2, Users, Lock, Globe } from 'lucide-react' import type { TreeListItem, TreeShare, TreeVisibility } from '@/types' import { treesApi } from '@/api/trees' import { cn } from '@/lib/utils' import { toast } from '@/lib/toast' interface ShareTreeModalProps { tree: TreeListItem isOpen: boolean onClose: () => void } export function ShareTreeModal({ tree, isOpen, onClose }: ShareTreeModalProps) { const [isGenerating, setIsGenerating] = useState(false) const [shares, setShares] = useState([]) const [activeShare, setActiveShare] = useState(null) const [copied, setCopied] = useState(false) const [allowForking, setAllowForking] = useState(true) const [visibility, setVisibility] = useState('private') useEffect(() => { if (isOpen) { loadShares() // Reset state setCopied(false) setAllowForking(true) } }, [isOpen, tree.id]) const loadShares = async () => { try { const sharesData = await treesApi.listShares(tree.id) setShares(sharesData) // Set active share to most recent if (sharesData.length > 0) { setActiveShare(sharesData[0]) } } catch (err) { console.error('Failed to load shares:', err) } } const handleGenerateLink = async () => { setIsGenerating(true) try { const newShare = await treesApi.createShare(tree.id, { allow_forking: allowForking, }) setShares([newShare, ...shares]) setActiveShare(newShare) toast.success('Share link generated') } catch (err) { console.error('Failed to generate share link:', err) toast.error('Failed to generate share link') } finally { setIsGenerating(false) } } const handleCopyLink = async () => { if (!activeShare) return try { await navigator.clipboard.writeText(activeShare.share_url) setCopied(true) toast.success('Link copied to clipboard') setTimeout(() => setCopied(false), 2000) } catch (err) { console.error('Failed to copy link:', err) toast.error('Failed to copy link') } } const handleVisibilityChange = async (newVisibility: TreeVisibility) => { try { await treesApi.updateVisibility(tree.id, { visibility: newVisibility }) setVisibility(newVisibility) toast.success('Visibility updated') } catch (err) { console.error('Failed to update visibility:', err) toast.error('Failed to update visibility') } } const getVisibilityIcon = (level: TreeVisibility) => { switch (level) { case 'private': return case 'team': return case 'link': return case 'public': return } } const getVisibilityDescription = (level: TreeVisibility) => { switch (level) { case 'private': return 'Only you can access' case 'team': return 'Team members can access' case 'link': return 'Anyone with the link' case 'public': return 'Discoverable by everyone' } } if (!isOpen) return null return (
{/* Backdrop */}
{/* Modal */}
{/* Header */}

Share Tree

{/* Body */}
{/* Tree Info */}

{tree.name}

{tree.description && (

{tree.description}

)}
{/* Visibility Settings */}
{(['private', 'team', 'link', 'public'] as TreeVisibility[]).map((level) => ( ))}
{/* Share Link Generation */} {visibility !== 'private' && (
{/* Allow Forking Checkbox */}
setAllowForking(e.target.checked)} className="h-4 w-4 rounded border-border bg-card text-foreground focus:ring-2 focus:ring-primary/20 focus:ring-offset-2 focus:ring-offset-black" />
{/* Generate Button */} {!activeShare && ( )} {/* Active Share Link */} {activeShare && (

{activeShare.allow_forking ? 'Recipients can fork this tree' : 'Forking disabled for this share'}

{shares.length > 1 && (

{shares.length} active share links

)}
)}
)}
{/* Footer */}
) }