import { ClockCircleOutlined, DeleteOutlined, DownloadOutlined, EditOutlined, MoreOutlined, PlayCircleOutlined, SlackOutlined, UserOutlined, } from '@ant-design/icons'; import { Button, Checkbox, Dropdown, Tooltip } from 'antd'; import copy from 'copy-to-clipboard'; import { Link2 } from 'lucide-react'; import React, { useState } from 'react'; import { useHistory, useParams } from 'react-router-dom'; import { toast } from 'react-toastify'; import { Spot } from 'App/mstore/types/spot'; import { spot as spotUrl, withSiteId } from 'App/routes'; import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG'; import EditItemModal from './EditItemModal'; const backgroundUrl = '/assets/img/spotThumbBg.svg'; interface ISpotListItem { spot: Spot; onRename: (id: string, title: string) => void; onDelete: () => void; onVideo: (id: string) => Promise<{ url: string }>; onSelect: (selected: boolean) => void; isSelected: boolean; } function SpotListItem({ spot, onRename, onDelete, onVideo, onSelect, isSelected, }: ISpotListItem) { const [isEdit, setIsEdit] = useState(false); const [loading, setLoading] = useState(true); const [tooltipText, setTooltipText] = useState('Copy link to clipboard'); const history = useHistory(); const { siteId } = useParams<{ siteId: string }>(); const menuItems = [ { key: 'rename', icon: , label: 'Rename', }, { key: 'download', label: 'Download Video', icon: , }, { key: 'delete', icon: , label: 'Delete', }, ]; React.useEffect(() => { menuItems.splice(1, 0, { key: 'slack', icon: , label: 'Share via Slack', }); }, []); const onMenuClick = async ({ key }: any) => { switch (key) { case 'rename': return setIsEdit(true); case 'download': const { url } = await onVideo(spot.spotId); await downloadFile(url, `${spot.title}.webm`); return; case 'copy': copy( `${window.location.origin}${withSiteId( spotUrl(spot.spotId.toString()), siteId )}` ); return toast.success('Spot URL copied to clipboard'); case 'delete': return onDelete(); case 'slack': break; default: break; } }; const onSpotClick = (e: any) => { if (e.shiftKey || e.ctrlKey || e.metaKey) { const spotLink = withSiteId(spotUrl(spot.spotId.toString()), siteId); const fullLink = `${window.location.origin}${spotLink}`; window.open(fullLink, '_blank'); } else { history.push(withSiteId(spotUrl(spot.spotId.toString()), siteId)); } }; const copyToClipboard = () => { const spotLink = withSiteId(spotUrl(spot.spotId.toString()), siteId); const fullLink = `${window.location.origin}${spotLink}`; navigator.clipboard .writeText(fullLink) .then(() => { setTooltipText('Link copied to clipboard!'); setTimeout(() => setTooltipText('Copy link to clipboard'), 2000); // Reset tooltip text after 2 seconds }) .catch(() => { setTooltipText('Failed to copy URL'); setTimeout(() => setTooltipText('Copy link to clipboard'), 2000); // Reset tooltip text after 2 seconds }); }; const onSave = (newName: string) => { onRename(spot.spotId, newName); setIsEdit(false); }; return (
{isEdit ? ( setIsEdit(false)} itemName={spot.title} /> ) : null}
{loading && (
)}
{spot.title} setLoading(false)} onError={() => setLoading(false)} style={{ display: loading ? 'none' : 'block' }} />
{spot.duration}
onSelect(checked)} className={`flex cursor-pointer w-full hover:text-teal ${isSelected ? 'text-teal' : ''}`} > {spot.title}
{spot.user}
{spot.createdAt}
); } async function downloadFile(url: string, fileName: string) { try { const response = await fetch(url); if (!response.ok) { throw new Error('Network response was not ok'); } const blob = await response.blob(); const blobUrl = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = blobUrl; a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(blobUrl); } catch (error) { console.error('Error downloading file:', error); } } export default SpotListItem;