project-standalo-sonic-cloud/components/ShareButton.tsx

75 lines
2.2 KiB
TypeScript

'use client';
import { useState } from 'react';
import { ShareModal } from './ShareModal';
import type { ShareType, CreateShareResponse } from '@/types/api-types';
interface ShareButtonProps {
type: ShareType;
targetId: string;
title: string;
className?: string;
}
export function ShareButton({ type, targetId, title, className = '' }: ShareButtonProps) {
const [isModalOpen, setIsModalOpen] = useState(false);
const [shareUrl, setShareUrl] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleShare = async () => {
if (shareUrl) {
setIsModalOpen(true);
return;
}
setIsLoading(true);
try {
const endpoint = type === 'SONG'
? `/api/share/song/${targetId}`
: type === 'PLAYLIST'
? `/api/share/playlist/${targetId}`
: `/api/share/album/${targetId}`;
const res = await fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
});
if (!res.ok) throw new Error('Failed to create share link');
const data: CreateShareResponse = await res.json();
setShareUrl(data.shareUrl);
setIsModalOpen(true);
} catch (err) {
console.error('Share error:', err);
} finally {
setIsLoading(false);
}
};
return (
<>
<button
onClick={handleShare}
disabled={isLoading}
className={`flex items-center gap-2 text-zinc-400 hover:text-white transition-colors disabled:opacity-50 ${className}`}
aria-label="Share"
>
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M8.684 13.342C8.886 12.938 9 12.482 9 12c0-.482-.114-.938-.316-1.342m0 2.684a3 3 0 110-2.684m0 2.684l6.632 3.316m-6.632-6l6.632-3.316m0 0a3 3 0 105.367-2.684 3 3 0 00-5.367 2.684zm0 9.316a3 3 0 105.368 2.684 3 3 0 00-5.368-2.684z" />
</svg>
{isLoading ? 'Loading...' : 'Share'}
</button>
<ShareModal
isOpen={isModalOpen}
onClose={() => setIsModalOpen(false)}
shareUrl={shareUrl}
title={title}
type={type}
/>
</>
);
}