diff --git a/src/components/Projects/EmptySolutions.tsx b/src/components/Projects/EmptySolutions.tsx index dcaf5b591..28f1cce72 100644 --- a/src/components/Projects/EmptySolutions.tsx +++ b/src/components/Projects/EmptySolutions.tsx @@ -8,7 +8,7 @@ export function EmptySolutions(props: EmptySolutionsProps) { const { projectId } = props; return ( -
+

No solutions submitted yet diff --git a/src/components/Projects/LeavingRoadmapWarningModal.tsx b/src/components/Projects/LeavingRoadmapWarningModal.tsx index 5576f1f52..c47d5fcf7 100644 --- a/src/components/Projects/LeavingRoadmapWarningModal.tsx +++ b/src/components/Projects/LeavingRoadmapWarningModal.tsx @@ -4,13 +4,13 @@ import { SubmissionRequirement } from './SubmissionRequirement.tsx'; type LeavingRoadmapWarningModalProps = { onClose: () => void; - onContinue: () => void; + repositoryUrl: string; }; export function LeavingRoadmapWarningModal( props: LeavingRoadmapWarningModalProps, ) { - const { onClose, onContinue } = props; + const { onClose, repositoryUrl } = props; return ( @@ -45,13 +45,14 @@ export function LeavingRoadmapWarningModal(

- + +
+ + + ); + })} + + + {(solutions?.totalPages || 0) > 1 && ( +
+ { + setPageState({ + ...pageState, + currentPage: page, + }); + }} + />
- ); - })} - - - {(solutions?.totalPages || 0) > 1 && ( -
- { - setPageState({ - ...pageState, - currentPage: page, - }); - }} - /> -
+ )} + )} - + ); } diff --git a/src/components/Projects/SelectLanguages.tsx b/src/components/Projects/SelectLanguages.tsx new file mode 100644 index 000000000..bde1db0f2 --- /dev/null +++ b/src/components/Projects/SelectLanguages.tsx @@ -0,0 +1,88 @@ +import { useEffect, useRef, useState } from 'react'; +import { useOutsideClick } from '../../hooks/use-outside-click'; +import { httpGet } from '../../lib/http'; +import { useToast } from '../../hooks/use-toast'; +import { ChevronDown, X } from 'lucide-react'; + +type SelectLanguagesProps = { + projectId: string; + selectedLanguage: string; + onSelectLanguage: (language: string) => void; +}; + +export function SelectLanguages(props: SelectLanguagesProps) { + const { projectId, onSelectLanguage, selectedLanguage } = props; + + const dropdownRef = useRef(null); + const toast = useToast(); + + const [distinctLanguages, setDistinctLanguages] = useState([]); + const [isOpen, setIsOpen] = useState(false); + + const loadDistinctLanguages = async () => { + const { response, error } = await httpGet( + `${import.meta.env.PUBLIC_API_URL}/v1-list-project-languages/${projectId}`, + ); + + if (error || !response) { + toast.error(error?.message || 'Failed to load project languages'); + return; + } + + setDistinctLanguages(response); + }; + + useOutsideClick(dropdownRef, () => { + setIsOpen(false); + }); + + useEffect(() => { + loadDistinctLanguages().finally(() => {}); + }, []); + + return ( +
+ + {selectedLanguage && ( + + )} + + {isOpen && ( +
+ {distinctLanguages.map((language) => { + const isSelected = selectedLanguage === language; + + return ( + + ); + })} +
+ )} +
+ ); +} diff --git a/src/components/Projects/SubmitProjectModal.tsx b/src/components/Projects/SubmitProjectModal.tsx index ac8b84e4c..cc9e34780 100644 --- a/src/components/Projects/SubmitProjectModal.tsx +++ b/src/components/Projects/SubmitProjectModal.tsx @@ -170,10 +170,19 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) { projectUrlExists: 'success', }); + const languagesUrl = `${mainApiUrl}/languages`; + const languagesResponse = await fetch(languagesUrl); + let languages: string[] = []; + if (languagesResponse.ok) { + const languagesData = await languagesResponse.json(); + languages = Object.keys(languagesData || {})?.slice(0, 4); + } + const submitProjectUrl = `${import.meta.env.PUBLIC_API_URL}/v1-submit-project/${projectId}`; const { response: submitResponse, error } = await httpPost(submitProjectUrl, { repositoryUrl: repoUrl, + languages, }); if (error || !submitResponse) { @@ -272,7 +281,7 @@ export function SubmitProjectModal(props: SubmitProjectModalProps) {