import { useState, useEffect } from 'react'; import { shareApi } from '../../api/share'; import type { DocumentShareWithUser, ShareLink } from '../../types/share'; import PixelIcon from '../PixelIcon/PixelIcon'; import './ShareModal.css'; interface ShareModalProps { documentId: string; documentType?: 'editor' | 'kanban'; onClose: () => void; currentPermission?: string; currentRole?: string; } function ShareModal({ documentId, documentType = 'editor', onClose, currentPermission, currentRole, }: ShareModalProps) { const [activeTab, setActiveTab] = useState<'users' | 'link'>('users'); const [shares, setShares] = useState([]); const [shareLink, setShareLink] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [success, setSuccess] = useState(null); // Form state for user sharing const [userEmail, setUserEmail] = useState(''); const [permission, setPermission] = useState<'view' | 'edit'>('view'); // Form state for link sharing const [linkPermission, setLinkPermission] = useState<'view' | 'edit'>('edit'); const [copied, setCopied] = useState(false); // Load shares on mount useEffect(() => { loadShares(); loadShareLink(); }, [documentId]); const loadShares = async () => { try { const data = await shareApi.listShares(documentId); setShares(data); } catch (err) { console.error('Failed to load shares:', err); } }; const loadShareLink = async () => { try { const link = await shareApi.getShareLink(documentId); setShareLink(link); if (link) { setLinkPermission(link.permission); } } catch (err) { console.error('Failed to load share link:', err); } }; const handleAddUser = async (e: React.FormEvent) => { e.preventDefault(); if (!userEmail.trim()) { setError('Please enter an email address'); return; } setLoading(true); setError(null); setSuccess(null); try { await shareApi.createShare(documentId, { user_email: userEmail, permission, }); setSuccess('User added successfully'); setUserEmail(''); await loadShares(); } catch (err) { setError('Failed to add user. Make sure the email is registered.'); } finally { setLoading(false); } }; const handleRemoveUser = async (userId: string) => { if (!confirm('Remove access for this user?')) { return; } setLoading(true); setError(null); try { await shareApi.deleteShare(documentId, userId); setSuccess('User removed successfully'); await loadShares(); } catch (err) { setError('Failed to remove user'); } finally { setLoading(false); } }; const handleGenerateLink = async () => { setLoading(true); setError(null); try { const link = await shareApi.createShareLink(documentId, linkPermission); setShareLink(link); setSuccess('Share link created'); } catch (err) { setError('Failed to create share link'); } finally { setLoading(false); } }; const handleRevokeLink = async () => { if (!confirm('Revoke this share link? Anyone with the link will lose access.')) { return; } setLoading(true); setError(null); try { await shareApi.revokeShareLink(documentId); setShareLink(null); setSuccess('Share link revoked'); } catch (err) { setError('Failed to revoke share link'); } finally { setLoading(false); } }; const handleCopyLink = () => { if (!shareLink) return; const url = `${window.location.origin}/${documentType}/${documentId}?share=${shareLink.token}`; navigator.clipboard.writeText(url); setCopied(true); setTimeout(() => setCopied(false), 2000); }; return (
e.stopPropagation()}>

Share Document

{currentRole && (
{currentRole === 'owner' ? '👑' : currentPermission === 'edit' ? '✏️' : '👁️'} {currentRole === 'owner' && 'You are the owner'} {currentRole === 'editor' && 'You have edit access'} {currentRole === 'viewer' && 'You have view-only access'}
)}
{error &&
{error}
} {success &&
{success}
} {activeTab === 'users' && (
setUserEmail(e.target.value)} className="share-input" disabled={loading} />

People with access

{shares.length === 0 ? (

No users have been given access yet.

) : ( shares.map((share) => (
{share.user.avatar_url && ( {share.user.name} )}
{share.user.name}
{share.user.email}
{share.permission}
)) )}
)} {activeTab === 'link' && (
{!shareLink ? (

Create a public link that anyone can use to access this document.

) : (

Anyone with this link can {shareLink.permission} this document.

{shareLink.permission} Created {new Date(shareLink.created_at).toLocaleDateString()}
)}
)}
); } export default ShareModal;