canvas-website/src/components/StarBoardButton.tsx

121 lines
3.7 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import { useAuth } from '../context/AuthContext';
import { useNotifications } from '../context/NotificationContext';
import { starBoard, unstarBoard, isBoardStarred } from '../lib/starredBoards';
interface StarBoardButtonProps {
className?: string;
}
const StarBoardButton: React.FC<StarBoardButtonProps> = ({ className = '' }) => {
const { slug } = useParams<{ slug: string }>();
const { session } = useAuth();
const { addNotification } = useNotifications();
const [isStarred, setIsStarred] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [showPopup, setShowPopup] = useState(false);
const [popupMessage, setPopupMessage] = useState('');
const [popupType, setPopupType] = useState<'success' | 'error' | 'info'>('success');
// Check if board is starred on mount and when session changes
useEffect(() => {
if (session.authed && session.username && slug) {
const starred = isBoardStarred(session.username, slug);
setIsStarred(starred);
} else {
setIsStarred(false);
}
}, [session.authed, session.username, slug]);
const showPopupMessage = (message: string, type: 'success' | 'error' | 'info') => {
setPopupMessage(message);
setPopupType(type);
setShowPopup(true);
// Auto-hide after 2 seconds
setTimeout(() => {
setShowPopup(false);
}, 2000);
};
const handleStarToggle = async () => {
if (!session.authed || !session.username || !slug) {
addNotification('Please log in to star boards', 'warning');
return;
}
setIsLoading(true);
try {
if (isStarred) {
// Unstar the board
const success = unstarBoard(session.username, slug);
if (success) {
setIsStarred(false);
showPopupMessage('Board removed from starred boards', 'success');
} else {
showPopupMessage('Failed to remove board from starred boards', 'error');
}
} else {
// Star the board
const success = starBoard(session.username, slug, slug);
if (success) {
setIsStarred(true);
showPopupMessage('Board added to starred boards', 'success');
} else {
showPopupMessage('Board is already starred', 'info');
}
}
} catch (error) {
console.error('Error toggling star:', error);
showPopupMessage('Failed to update starred boards', 'error');
} finally {
setIsLoading(false);
}
};
// Don't show the button if user is not authenticated
if (!session.authed) {
return null;
}
return (
<div style={{ position: 'relative' }}>
<button
onClick={handleStarToggle}
disabled={isLoading}
className={`star-board-button ${className} ${isStarred ? 'starred' : ''}`}
title={isStarred ? 'Remove from starred boards' : 'Add to starred boards'}
>
{isLoading ? (
<span className="loading-spinner"></span>
) : isStarred ? (
<span className="star-icon starred"></span>
) : (
<span className="star-icon"></span>
)}
</button>
{/* Custom popup notification */}
{showPopup && (
<div
className={`star-popup star-popup-${popupType}`}
style={{
position: 'absolute',
bottom: '40px',
left: '50%',
transform: 'translateX(-50%)',
zIndex: 100001,
whiteSpace: 'nowrap',
pointerEvents: 'none',
}}
>
{popupMessage}
</div>
)}
</div>
);
};
export default StarBoardButton;