import { useEffect, useMemo, useRef, useState } from 'preact/hooks'; import { useOutsideClick } from '../../hooks/use-outside-click'; import CheckIcon from '../../icons/check.svg'; import DownIcon from '../../icons/down.svg'; import ProgressIcon from '../../icons/progress.svg'; import ResetIcon from '../../icons/reset.svg'; import SpinnerIcon from '../../icons/spinner.svg'; import { isLoggedIn } from '../../lib/jwt'; import { ResourceProgressType, ResourceType, getTopicStatus, renderTopicProgress, updateResourceProgress, } from '../../lib/resource-progress'; type TopicProgressButtonProps = { topicId: string; resourceId: string; resourceType: ResourceType; onClose: () => void; }; const statusColors: Record = { done: 'bg-green-500', learning: 'bg-yellow-500', pending: 'bg-gray-300', skipped: 'bg-black', }; export function TopicProgressButton(props: TopicProgressButtonProps) { const { topicId, resourceId, resourceType, onClose } = props; const [isUpdatingProgress, setIsUpdatingProgress] = useState(true); const [progress, setProgress] = useState('pending'); const [showChangeStatus, setShowChangeStatus] = useState(false); const changeStatusRef = useRef(null); useOutsideClick(changeStatusRef, () => { setShowChangeStatus(false); }); const isGuest = useMemo(() => !isLoggedIn(), []); useEffect(() => { if (!topicId || !resourceId || !resourceType) { return; } setIsUpdatingProgress(true); getTopicStatus({ topicId, resourceId, resourceType }) .then((status) => { setIsUpdatingProgress(false); setProgress(status); }) .catch(console.error); }, [topicId, resourceId, resourceType]); const handleUpdateResourceProgress = (progress: ResourceProgressType) => { setIsUpdatingProgress(true); updateResourceProgress( { topicId, resourceId, resourceType, }, progress ) .then(() => { setProgress(progress); onClose(); renderTopicProgress(topicId, progress); }) .catch((err) => { alert(err.message); console.error(err); }) .finally(() => { setIsUpdatingProgress(false); }); }; const allowMarkingSkipped = ['pending', 'learning', 'done'].includes(progress); const allowMarkingDone = ['skipped', 'pending', 'learning'].includes(progress); const allowMarkingLearning = ['done', 'skipped', 'pending'].includes(progress); const allowMarkingPending = ['skipped', 'done', 'learning'].includes(progress); if (isUpdatingProgress) { return ( ); } return (
{progress === 'learning' ? 'In Progress' : progress} {showChangeStatus && (
{allowMarkingDone && ( )} {allowMarkingPending && ( )} {allowMarkingLearning && ( )} {allowMarkingSkipped && ( )}
)}
); if (isGuest) { return (
); } return (
{allowMarkingDone && ( )} {allowMarkingLearning && ( )} {allowMarkingPending && ( )}
); }