import { Flag, Play, Send, Share, Square, StopCircle, X } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; import { cn } from '../../../lib/classname'; import { useStickyStuck } from '../../../hooks/use-sticky-stuck'; import { StepperAction } from './StepperAction'; import { StepperStepSeparator } from './StepperStepSeparator'; import { MilestoneStep } from './MilestoneStep'; import { httpGet, httpPost } from '../../../lib/http'; import { StartProjectModal } from '../StartProjectModal'; import { getRelativeTimeString } from '../../../lib/date'; import { getUser, isLoggedIn } from '../../../lib/jwt'; import { showLoginPopup } from '../../../lib/popup'; import { SubmitProjectModal } from '../SubmitProjectModal'; import { useCopyText } from '../../../hooks/use-copy-text'; import { CheckIcon } from '../../ReactIcons/CheckIcon'; import { pageProgressMessage } from '../../../stores/page'; type ProjectStatusResponse = { id?: string; startedAt?: Date; submittedAt?: Date; repositoryUrl?: string; upvotes: number; downvotes: number; }; type ProjectStepperProps = { projectId: string; }; export function ProjectStepper(props: ProjectStepperProps) { const { projectId } = props; const stickyElRef = useRef(null); const isSticky = useStickyStuck(stickyElRef, 8); const currentUser = getUser(); const [isStartingProject, setIsStartingProject] = useState(false); const [isSubmittingProject, setIsSubmittingProject] = useState(false); const { copyText, isCopied } = useCopyText(); const [isStoppingProject, setIsStoppingProject] = useState(false); const [error, setError] = useState(null); const [activeStep, setActiveStep] = useState(0); const [isLoadingStatus, setIsLoadingStatus] = useState(true); const [projectStatus, setProjectStatus] = useState({ upvotes: 0, downvotes: 0, }); async function loadProjectStatus() { setIsLoadingStatus(true); const { response, error } = await httpGet( `${import.meta.env.PUBLIC_API_URL}/v1-project-status/${projectId}`, {}, ); if (error || !response) { setError(error?.message || 'Error loading project status'); setIsLoadingStatus(false); return; } const { startedAt, submittedAt, upvotes } = response; if (upvotes >= 10) { setActiveStep(4); } else if (upvotes >= 5) { setActiveStep(3); } else if (submittedAt) { setActiveStep(2); } else if (startedAt) { setActiveStep(1); } setProjectStatus(response); setIsLoadingStatus(false); } const stopProject = async () => { setIsStoppingProject(true); const { response, error } = await httpPost( `${import.meta.env.PUBLIC_API_URL}/v1-stop-project/${projectId}`, {}, ); if (error || !response) { setIsStoppingProject(false); setError(error?.message || 'Error stopping project'); return; } pageProgressMessage.set('Update project status'); setActiveStep(0); loadProjectStatus().finally(() => { pageProgressMessage.set(''); setIsStoppingProject(false); }); }; useEffect(() => { loadProjectStatus().finally(() => {}); }, []); const projectSolutionUrl = `${import.meta.env.DEV ? 'http://localhost:3000' : 'https://roadmap.sh'}/projects/${projectId}/solutions?u=${currentUser?.id}`; return (
{isSubmittingProject && ( setIsSubmittingProject(false)} projectId={projectId} onSubmit={(response) => { const { repositoryUrl, submittedAt } = response; setProjectStatus({ ...projectStatus, repositoryUrl, submittedAt, }); setActiveStep(2); }} repositoryUrl={projectStatus.repositoryUrl} /> )} {isStartingProject && ( { setProjectStatus({ ...projectStatus, startedAt, }); setActiveStep(1); }} startedAt={projectStatus?.startedAt} onClose={() => setIsStartingProject(false)} /> )} {error && (
{error}
)} {isLoadingStatus && (
)}
{activeStep === 0 && ( <> Start building, submit solution and get feedback from the community. )} {activeStep === 1 && ( <> Started working  {getRelativeTimeString(projectStatus.startedAt!)} . Follow   to get most out of it. )} {activeStep >= 2 && ( <> Congrats on submitting your solution.  )} {projectStatus?.startedAt && !projectStatus?.submittedAt && ( )} {activeStep >= 2 && ( )}
0} icon={Play} text={activeStep > 0 ? 'Started Working' : 'Start Working'} number={1} onClick={() => { if (!isLoggedIn()) { showLoginPopup(); return; } setIsStartingProject(true); }} /> 0} />
1} icon={Send} onClick={() => { if (!isLoggedIn()) { showLoginPopup(); return; } setIsSubmittingProject(true); }} text={activeStep > 1 ? 'Submitted' : 'Submit Solution'} number={2} /> {activeStep > 1 && ( <> · )}
1} /> 2} icon={Flag} text={ activeStep == 2 ? `${projectStatus.upvotes} / 5 upvotes` : `5 upvotes` } /> 2} /> 3} icon={Flag} text={ activeStep == 3 ? `${projectStatus.upvotes} / 10 upvotes` : activeStep > 3 ? `${projectStatus.upvotes} upvotes` : `10 upvotes` } />
); }