From 9c807386683242e0b504e25f5ecb883a88b40f7f Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Mon, 26 Aug 2024 11:41:50 +0530 Subject: [PATCH 01/11] working sort and search array made Signed-off-by: ayushka11 --- .../checkQuiz/api/generateLeaderboard.tsx | 14 ++- src/modules/checkQuiz/api/getDashboard.ts | 13 ++- src/modules/checkQuiz/api/useDashboard.ts | 7 +- src/modules/checkQuiz/components/Filters.tsx | 106 ++++++++++++------ .../checkQuiz/components/Leaderboard.tsx | 2 +- .../checkQuiz/components/TabViewDashboard.tsx | 2 +- 6 files changed, 97 insertions(+), 47 deletions(-) diff --git a/src/modules/checkQuiz/api/generateLeaderboard.tsx b/src/modules/checkQuiz/api/generateLeaderboard.tsx index 63d5e16..c50f1be 100644 --- a/src/modules/checkQuiz/api/generateLeaderboard.tsx +++ b/src/modules/checkQuiz/api/generateLeaderboard.tsx @@ -4,19 +4,29 @@ import axiosInstance from './axiosInstance' export const GenerateLeaderboard = async ({ quizId, sectionIndex = null, + searchQuery = null, }: { quizId: string sectionIndex: number | null + searchQuery: string | null }) => { try { - if (sectionIndex === null) { + if (sectionIndex === null && searchQuery === null) { const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}`) return res.data - } else { + } else if (sectionIndex !== null && searchQuery === null) { const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}`, ) return res.data + } else if (sectionIndex === null && searchQuery !== null) { + const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}?search=${searchQuery}`) + return res.data + } else { + const res = await axiosInstance.patch( + `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}?search=${searchQuery}`, + ) + return res.data } } catch (e: any) { if (axios.isAxiosError(e)) { diff --git a/src/modules/checkQuiz/api/getDashboard.ts b/src/modules/checkQuiz/api/getDashboard.ts index f651deb..743f3a8 100644 --- a/src/modules/checkQuiz/api/getDashboard.ts +++ b/src/modules/checkQuiz/api/getDashboard.ts @@ -1,14 +1,21 @@ import axios from 'axios' import axiosInstance from './axiosInstance' -export const getDashboard = async (quizId: string, sectionIndex: number | null = null) => { +export const getDashboard = async (quizId: string, sectionIndex: number | null = null, searchQuery: string | null = null) => { try { - if (sectionIndex === null) { + console.log('getDashboard', quizId, sectionIndex, searchQuery) + if (sectionIndex === null && searchQuery === null) { const res = await axiosInstance.get(`/checkQuiz/dashboard/${quizId}`) return res.data - } else { + } else if (sectionIndex !== null && searchQuery === null) { const res = await axiosInstance.get(`/checkQuiz/sectionLeaderboard/${quizId}/${sectionIndex}`) return res.data + } else if (sectionIndex === null && searchQuery !== null) { + const res = await axiosInstance.get(`/checkQuiz/dashboard/${quizId}?search=${searchQuery}`) + return res.data + } else { + const res = await axiosInstance.get(`/checkQuiz/sectionLeaderboard/${quizId}/${sectionIndex}?search=${searchQuery}`) + return res.data } } catch (e: unknown) { if (axios.isAxiosError(e)) { diff --git a/src/modules/checkQuiz/api/useDashboard.ts b/src/modules/checkQuiz/api/useDashboard.ts index d242fd2..b14856e 100644 --- a/src/modules/checkQuiz/api/useDashboard.ts +++ b/src/modules/checkQuiz/api/useDashboard.ts @@ -2,10 +2,11 @@ import { useQuery, useMutation } from '@tanstack/react-query' import axiosInstance from './axiosInstance' import { getDashboard } from './getDashboard' -export const useFetchDashboard = (quizId: string, sectionIndex: number | null = null) => { +export const useFetchDashboard = (quizId: string, sectionIndex: number | null = null, searchQuery: string | null = null) => { + console.log('useFetchDashboard', quizId, sectionIndex, searchQuery) const query = useQuery({ - queryKey: ['fetchDashboard', quizId, sectionIndex], - queryFn: () => getDashboard(quizId, sectionIndex), + queryKey: ['fetchDashboard', quizId, sectionIndex, searchQuery], + queryFn: () => getDashboard(quizId, sectionIndex, searchQuery), }) return query } diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 5f6eedf..2e1ca2f 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -1,12 +1,13 @@ import React, { useEffect, useState } from 'react' import { Select } from 'chakra-react-select' -import { Button, HStack, Input, Select as SelectChakra, Text } from '@chakra-ui/react' +import { Button, HStack, Input, IconButton, Select as SelectChakra, Text } from '@chakra-ui/react' import { useLeaderboard } from '@checkQuiz/api/useLeaderboard' import AutocheckModal from './Modals/Autocheck' import useCheckQuizStore from '@checkQuiz/store/checkQuizStore' import { Section } from '@checkQuiz/types' import { useFetchDashboard } from '@checkQuiz/api/useDashboard' import { getDashboard } from '@checkQuiz/api/getDashboard' +import { AddIcon } from '@chakra-ui/icons'; interface FiltersProps { question?: boolean @@ -28,8 +29,14 @@ const Filters: React.FC = ({ state.leaderboard, state.setLeaderboard, ]) + const [searchQuery, setSearchQuery] = useState('') - const { data, isFetched, refetch } = useFetchDashboard(quizId, sectionIndex) + const handleSearchChange = (e: React.ChangeEvent) => { + setSearchQuery(e.target.value.toLocaleLowerCase()) + console.log('Search query:', searchQuery) + } + + const { data, isFetched, refetch } = useFetchDashboard(quizId, sectionIndex, searchQuery) useEffect(() => { if (isFetched && data) { @@ -66,14 +73,14 @@ const Filters: React.FC = ({ data: sectionData, isFetched: sectionDataIsFetched, refetch: sectionDataRefetch, - } = useFetchDashboard(quizId, sectionIndex) + } = useFetchDashboard(quizId, sectionIndex, searchQuery) const handleLeaderboard = (sectionIndex: number | null) => { generateLeaderboard( - { quizId, sectionIndex }, + { quizId, sectionIndex, searchQuery }, { onSuccess: () => { - window.location.reload() + console.log('Leaderboard generated successfully') }, }, ) @@ -101,6 +108,10 @@ const Filters: React.FC = ({ } } + const handleAddClick = () => { + console.log('Add button clicked'); + }; + useEffect(() => { sectionDataRefetch() }, [sectionIndex]) @@ -111,42 +122,62 @@ const Filters: React.FC = ({ {question && ( <> - - Assigned to: - - + } + onClick={handleAddClick} + size="sm" + bgColor="brand" + color="white" + borderRadius="0.25rem" + /> + )} {participants && ( <> - - + + + Sort by + + + {sections.map((section, index) => ( + + ))} + + )} {participants && ( @@ -191,3 +222,4 @@ const Filters: React.FC = ({ } export default Filters + diff --git a/src/modules/checkQuiz/components/Leaderboard.tsx b/src/modules/checkQuiz/components/Leaderboard.tsx index fc7cc33..fd63f18 100644 --- a/src/modules/checkQuiz/components/Leaderboard.tsx +++ b/src/modules/checkQuiz/components/Leaderboard.tsx @@ -95,4 +95,4 @@ const Leaderboard = () => { ) } -export default Leaderboard +export default Leaderboard \ No newline at end of file diff --git a/src/modules/checkQuiz/components/TabViewDashboard.tsx b/src/modules/checkQuiz/components/TabViewDashboard.tsx index f60b27d..5702be8 100644 --- a/src/modules/checkQuiz/components/TabViewDashboard.tsx +++ b/src/modules/checkQuiz/components/TabViewDashboard.tsx @@ -40,4 +40,4 @@ const TabViewDashboard = () => { ) } -export default TabViewDashboard +export default TabViewDashboard \ No newline at end of file From 23aafc44cbe0db5f59c1c6a42af6d85d18924ecd Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Wed, 28 Aug 2024 19:21:07 +0530 Subject: [PATCH 02/11] array of strings for answer and leaderboard search debouncing Signed-off-by: ayushka11 --- .../checkQuiz/api/generateLeaderboard.tsx | 6 ++ src/modules/checkQuiz/components/Filters.tsx | 25 ++++--- .../createQuiz/forms/QuestionDetails.tsx | 33 ++++++--- .../giveQuiz/components/QuestionView.tsx | 68 ++++++++++--------- .../giveQuiz/utils/handleSaveButton.ts | 8 ++- 5 files changed, 87 insertions(+), 53 deletions(-) diff --git a/src/modules/checkQuiz/api/generateLeaderboard.tsx b/src/modules/checkQuiz/api/generateLeaderboard.tsx index c50f1be..cbd96aa 100644 --- a/src/modules/checkQuiz/api/generateLeaderboard.tsx +++ b/src/modules/checkQuiz/api/generateLeaderboard.tsx @@ -12,17 +12,23 @@ export const GenerateLeaderboard = async ({ }) => { try { if (sectionIndex === null && searchQuery === null) { + console.log(1) const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}`) return res.data } else if (sectionIndex !== null && searchQuery === null) { + console.log(2) const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}`, ) return res.data } else if (sectionIndex === null && searchQuery !== null) { + console.log(3) + console.log(searchQuery) const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}?search=${searchQuery}`) + console.log(res) return res.data } else { + console.log(4) const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}?search=${searchQuery}`, ) diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 2e1ca2f..a3e602a 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -1,12 +1,10 @@ import React, { useEffect, useState } from 'react' -import { Select } from 'chakra-react-select' import { Button, HStack, Input, IconButton, Select as SelectChakra, Text } from '@chakra-ui/react' import { useLeaderboard } from '@checkQuiz/api/useLeaderboard' import AutocheckModal from './Modals/Autocheck' import useCheckQuizStore from '@checkQuiz/store/checkQuizStore' import { Section } from '@checkQuiz/types' import { useFetchDashboard } from '@checkQuiz/api/useDashboard' -import { getDashboard } from '@checkQuiz/api/getDashboard' import { AddIcon } from '@chakra-ui/icons'; interface FiltersProps { @@ -30,13 +28,23 @@ const Filters: React.FC = ({ state.setLeaderboard, ]) const [searchQuery, setSearchQuery] = useState('') + const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery) const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value.toLocaleLowerCase()) - console.log('Search query:', searchQuery) } - const { data, isFetched, refetch } = useFetchDashboard(quizId, sectionIndex, searchQuery) + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedSearchQuery(searchQuery); + }, 300); + + return () => { + clearTimeout(handler); + }; + }, [searchQuery]); + + const { data, isFetched, refetch } = useFetchDashboard(quizId, sectionIndex, debouncedSearchQuery) useEffect(() => { if (isFetched && data) { @@ -54,6 +62,7 @@ const Filters: React.FC = ({ } }, [sectionIndex, isFetched, data]) + useEffect(() => { if (sections) { let totalAutocheckQuestionsCount = 0 @@ -66,18 +75,18 @@ const Filters: React.FC = ({ }) setTotalAutocheckQuestions(totalAutocheckQuestionsCount) } - }, [sections]) + }, [sections, searchQuery]) const { mutate: generateLeaderboard } = useLeaderboard() const { data: sectionData, isFetched: sectionDataIsFetched, refetch: sectionDataRefetch, - } = useFetchDashboard(quizId, sectionIndex, searchQuery) + } = useFetchDashboard(quizId, sectionIndex, debouncedSearchQuery) const handleLeaderboard = (sectionIndex: number | null) => { generateLeaderboard( - { quizId, sectionIndex, searchQuery }, + { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, // Correct property name { onSuccess: () => { console.log('Leaderboard generated successfully') @@ -85,6 +94,7 @@ const Filters: React.FC = ({ }, ) } + // TODO: fetch assignees from athena const [availableAssignees] = useState([ @@ -222,4 +232,3 @@ const Filters: React.FC = ({ } export default Filters - diff --git a/src/modules/createQuiz/forms/QuestionDetails.tsx b/src/modules/createQuiz/forms/QuestionDetails.tsx index 5de9fcc..b8c0580 100644 --- a/src/modules/createQuiz/forms/QuestionDetails.tsx +++ b/src/modules/createQuiz/forms/QuestionDetails.tsx @@ -19,6 +19,7 @@ import { Text, VStack, } from '@chakra-ui/react' +import select from 'react-select' import { useEffect, useState } from 'react' import CustomRichTextEditor from '@common/components/CustomRichTextEditor' import { QuestionType, Option } from '../../types' @@ -36,7 +37,7 @@ const QuestionDetails = () => { const [marks, setMarks] = useState(0) const [autoCheck, setAutoCheck] = useState(false) const [options, setOptions] = useState([]) - const [answer, setAnswer] = useState('') + const [answer, setAnswer] = useState([]); const { sections, currentSectionIdx, currentQuestionIdx } = useSectionStore((state) => state) const activeSection = sections[currentSectionIdx ?? 0] @@ -61,7 +62,7 @@ const QuestionDetails = () => { setMarks(data?.question.maxMarks ?? 0) setAutoCheck(data?.question?.autoCheck ?? false) setOptions(data?.question?.options ?? []) - setAnswer(data?.question?.correctAnswer ?? '') + setAnswer(Array.isArray(data.question?.correctAnswer) ? data.question.correctAnswer : [data.question?.correctAnswer ?? '']); } const handleEdit = (id: string, newLabel: string) => { setOptions((prevOptions) => @@ -98,10 +99,14 @@ const QuestionDetails = () => { setAutoCheck(data.question?.autoCheck) setOptions(data.question?.options) setNotes(data.question?.checkerNotes) - setAnswer(data.question?.correctAnswer) + setAnswer(Array.isArray(data.question?.correctAnswer) ? data.question.correctAnswer : [data.question?.correctAnswer ?? '']); } }, [isFetched, isLoading, data]) + // useEffect(() => { + // console.log(answer); + // },[answer]) + const renderChoiceBuilder = () => { if (type === QuestionType.SUB) return null @@ -210,13 +215,21 @@ const QuestionDetails = () => { Answer: - + )} diff --git a/src/modules/giveQuiz/components/QuestionView.tsx b/src/modules/giveQuiz/components/QuestionView.tsx index 76fd4b8..14dd784 100644 --- a/src/modules/giveQuiz/components/QuestionView.tsx +++ b/src/modules/giveQuiz/components/QuestionView.tsx @@ -1,4 +1,4 @@ -import { Flex, Button, Text, Box, RadioGroup, Radio } from '@chakra-ui/react' +import { Flex, Button, Text, Box, CheckboxGroup, Checkbox, Stack } from '@chakra-ui/react' import CustomRichTextEditor, { renderPreview } from '@common/components/CustomRichTextEditor' import { useState, useEffect } from 'react' import useQuizStore from '../store/QuizStore' @@ -22,7 +22,7 @@ const QuestionView = () => { const [questionNumber, setQuestionNumber] = useState(1) const [question, setQuestion] = useState('') const [options, setOptions] = useState([]) - const [answer, setAnswer] = useState('') + const [answer, setAnswer] = useState(''); const [mark, setMark] = useState(4) const [isLastQuestion, setIsLastQuestion] = useState(false) const { mutate: deleteResponse } = useDeleteResponse() @@ -63,7 +63,7 @@ const QuestionView = () => { } = useGetResponse(quizId, currentQuestion) const handleClearResponse = () => { - setAnswer('') + setAnswer(questionType === 'mcq' ? [] : ''); deleteResponse( { quizId, @@ -81,24 +81,25 @@ const QuestionView = () => { } async function handleSave() { - handleSaveButton( - answer, - isCurrentQuestionMarked, - currentQuestion, - quizId, - mutate, - deleteResponse, - questionType, - nextQuestion, - setAnsweredQuestions, - setMarkedQuestions, - setMarkedAnsweredQuestions, - markedAnsweredQuestions, - answeredQuestions, - markedQuestions, - queryClient - ) - } + const answerValue = Array.isArray(answer) ? answer.join(',') : answer; // Convert array to string if needed + handleSaveButton( + answerValue, + isCurrentQuestionMarked, + currentQuestion, + quizId, + mutate, + deleteResponse, + questionType, + nextQuestion, + setAnsweredQuestions, + setMarkedQuestions, + setMarkedAnsweredQuestions, + markedAnsweredQuestions, + answeredQuestions, + markedQuestions, + queryClient + ); +} useEffect(() => { setIsLastQuestion( @@ -125,7 +126,7 @@ const QuestionView = () => { setIsCurrentQuestionMarked(false) } } else { - setAnswer('') + setAnswer(questionType === 'mcq' ? [] : '') setIsCurrentQuestionMarked(false) } } @@ -178,19 +179,19 @@ const QuestionView = () => { {questionType === 'mcq' ? ( - setAnswer(event)} + setAnswer(selectedValues)} // Ensure selectedValues is string[] > + {options.map((option) => ( - + {option.label} - + ))} - + + + diff --git a/src/modules/giveQuiz/utils/handleSaveButton.ts b/src/modules/giveQuiz/utils/handleSaveButton.ts index 999ce32..7fadc37 100644 --- a/src/modules/giveQuiz/utils/handleSaveButton.ts +++ b/src/modules/giveQuiz/utils/handleSaveButton.ts @@ -26,9 +26,9 @@ export const handleSaveButton = async ( ) => { let status: ResponseStatus = ResponseStatus.unanswered if (!answer && !isCurrentQuestionMarked) { - console.log('answer', answer) - console.log('isCurrentQuestionMarked', isCurrentQuestionMarked) - displayErrorToast('This question is unanswered and not marked for review', { + console.log('answer', answer) // answer did not come //TODO: remove this line + console.log('isCurrentQuestionMarked', isCurrentQuestionMarked) // came false + displayErrorToast('This question is unanswered and not marked for review', { type: 'info', autoClose: 2000, }) @@ -57,6 +57,7 @@ export const handleSaveButton = async ( }, { onError: (error: any) => { + console.log('error', error) //TODO: remove this line displayErrorToast('Failed to clear response. Please try again.') }, }, From 7b82097462e71fc28fcb498a205234b3a9554594 Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Thu, 29 Aug 2024 16:58:29 +0530 Subject: [PATCH 04/11] selectOptionId string problem fixed Signed-off-by: ayushka11 --- src/modules/giveQuiz/components/QuestionView.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/giveQuiz/components/QuestionView.tsx b/src/modules/giveQuiz/components/QuestionView.tsx index 490d9d9..5b05914 100644 --- a/src/modules/giveQuiz/components/QuestionView.tsx +++ b/src/modules/giveQuiz/components/QuestionView.tsx @@ -82,7 +82,7 @@ const QuestionView = () => { async function handleSave() { console.log('raw answer', answer) //TODO: remove this line - const answerValue = Array.isArray(answer) ? answer.join(',') : answer; // Convert array to string if needed + const answerValue = answer; console.log('answerValue', answerValue) //TODO: remove this line handleSaveButton( answerValue, From eb41311c4da9e671fa8ea433603cd24f24cf4045 Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Fri, 30 Aug 2024 18:56:39 +0530 Subject: [PATCH 05/11] removed logs Signed-off-by: ayushka11 --- .../checkQuiz/api/generateLeaderboard.tsx | 6 ------ src/modules/checkQuiz/api/getDashboard.ts | 1 - src/modules/checkQuiz/api/useDashboard.ts | 1 - src/modules/checkQuiz/components/Filters.tsx | 16 ++++++++-------- src/modules/createQuiz/forms/QuestionDetails.tsx | 4 ---- src/modules/giveQuiz/components/QuestionView.tsx | 15 +++------------ src/modules/giveQuiz/utils/handleSaveButton.ts | 3 --- 7 files changed, 11 insertions(+), 35 deletions(-) diff --git a/src/modules/checkQuiz/api/generateLeaderboard.tsx b/src/modules/checkQuiz/api/generateLeaderboard.tsx index cbd96aa..c50f1be 100644 --- a/src/modules/checkQuiz/api/generateLeaderboard.tsx +++ b/src/modules/checkQuiz/api/generateLeaderboard.tsx @@ -12,23 +12,17 @@ export const GenerateLeaderboard = async ({ }) => { try { if (sectionIndex === null && searchQuery === null) { - console.log(1) const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}`) return res.data } else if (sectionIndex !== null && searchQuery === null) { - console.log(2) const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}`, ) return res.data } else if (sectionIndex === null && searchQuery !== null) { - console.log(3) - console.log(searchQuery) const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}?search=${searchQuery}`) - console.log(res) return res.data } else { - console.log(4) const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}?search=${searchQuery}`, ) diff --git a/src/modules/checkQuiz/api/getDashboard.ts b/src/modules/checkQuiz/api/getDashboard.ts index 743f3a8..215b064 100644 --- a/src/modules/checkQuiz/api/getDashboard.ts +++ b/src/modules/checkQuiz/api/getDashboard.ts @@ -3,7 +3,6 @@ import axiosInstance from './axiosInstance' export const getDashboard = async (quizId: string, sectionIndex: number | null = null, searchQuery: string | null = null) => { try { - console.log('getDashboard', quizId, sectionIndex, searchQuery) if (sectionIndex === null && searchQuery === null) { const res = await axiosInstance.get(`/checkQuiz/dashboard/${quizId}`) return res.data diff --git a/src/modules/checkQuiz/api/useDashboard.ts b/src/modules/checkQuiz/api/useDashboard.ts index b14856e..b2255c9 100644 --- a/src/modules/checkQuiz/api/useDashboard.ts +++ b/src/modules/checkQuiz/api/useDashboard.ts @@ -3,7 +3,6 @@ import axiosInstance from './axiosInstance' import { getDashboard } from './getDashboard' export const useFetchDashboard = (quizId: string, sectionIndex: number | null = null, searchQuery: string | null = null) => { - console.log('useFetchDashboard', quizId, sectionIndex, searchQuery) const query = useQuery({ queryKey: ['fetchDashboard', quizId, sectionIndex, searchQuery], queryFn: () => getDashboard(quizId, sectionIndex, searchQuery), diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index f10243e..254589b 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -136,14 +136,14 @@ const Filters: React.FC = ({ maxWidth='20rem' placeholder='Search or add assignee' variant='outline' - borderColor='#939393' + borderColor='grey' borderRadius='0.25rem' fontSize='0.875rem' fontWeight='600' - color='#939393' + color='grey' value={searchQuery} onChange={handleSearchChange} - _placeholder={{ color: '#939393' }} + _placeholder={{ color: 'grey' }} /> = ({ maxWidth='20rem' placeholder='Search' variant='outline' - borderColor='#939393' + borderColor='grey' borderRadius='0.25rem' fontSize='0.875rem' fontWeight='600' - color='#939393' + color='grey' value={searchQuery} onChange={handleSearchChange} - _placeholder={{ color: '#939393' }} + _placeholder={{ color: 'grey' }} /> - + Sort by {sections.map((section, index) => ( diff --git a/src/modules/createQuiz/forms/QuestionDetails.tsx b/src/modules/createQuiz/forms/QuestionDetails.tsx index b8c0580..f92232c 100644 --- a/src/modules/createQuiz/forms/QuestionDetails.tsx +++ b/src/modules/createQuiz/forms/QuestionDetails.tsx @@ -103,10 +103,6 @@ const QuestionDetails = () => { } }, [isFetched, isLoading, data]) - // useEffect(() => { - // console.log(answer); - // },[answer]) - const renderChoiceBuilder = () => { if (type === QuestionType.SUB) return null diff --git a/src/modules/giveQuiz/components/QuestionView.tsx b/src/modules/giveQuiz/components/QuestionView.tsx index 5b05914..f5b8c7f 100644 --- a/src/modules/giveQuiz/components/QuestionView.tsx +++ b/src/modules/giveQuiz/components/QuestionView.tsx @@ -81,9 +81,7 @@ const QuestionView = () => { } async function handleSave() { - console.log('raw answer', answer) //TODO: remove this line const answerValue = answer; - console.log('answerValue', answerValue) //TODO: remove this line handleSaveButton( answerValue, isCurrentQuestionMarked, @@ -147,10 +145,6 @@ const QuestionView = () => { setQuestionType(questionData.question.type) } }, [currentQuestionIndex, questionData]) - - useEffect(() => { - console.log('Current Answer State:', answer); - }, [answer]); if (isQuestionDataLoading || isGetResponseLoading) { @@ -189,8 +183,7 @@ const QuestionView = () => { { - console.log('selectedValues', selectedValues); // Check if this logs correctly - setAnswer(selectedValues); // Set selected values as the answer + setAnswer(selectedValues); }} > @@ -215,11 +208,10 @@ const QuestionView = () => { ) : ( { - console.log('value', value) //TODO: remove this line setAnswer(value ?? '') - }} // Handle the case where value is not a string + }} /> )} @@ -238,7 +230,6 @@ const QuestionView = () => { bgColor='brand' alignSelf='flex-end' onClick={() => { - console.log('Answer before save:', answer); //TODO: remove this line handleSave(); }} > diff --git a/src/modules/giveQuiz/utils/handleSaveButton.ts b/src/modules/giveQuiz/utils/handleSaveButton.ts index 7fadc37..5f6c178 100644 --- a/src/modules/giveQuiz/utils/handleSaveButton.ts +++ b/src/modules/giveQuiz/utils/handleSaveButton.ts @@ -26,8 +26,6 @@ export const handleSaveButton = async ( ) => { let status: ResponseStatus = ResponseStatus.unanswered if (!answer && !isCurrentQuestionMarked) { - console.log('answer', answer) // answer did not come //TODO: remove this line - console.log('isCurrentQuestionMarked', isCurrentQuestionMarked) // came false displayErrorToast('This question is unanswered and not marked for review', { type: 'info', autoClose: 2000, @@ -57,7 +55,6 @@ export const handleSaveButton = async ( }, { onError: (error: any) => { - console.log('error', error) //TODO: remove this line displayErrorToast('Failed to clear response. Please try again.') }, }, From e569d56334cf1fb846f9f63a52747b3a44d5e083 Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Sat, 14 Sep 2024 19:12:10 +0530 Subject: [PATCH 06/11] minor fixes Signed-off-by: ayushka11 --- src/modules/checkQuiz/components/Filters.tsx | 15 +++------------ .../checkQuiz/hooks/useDebouncedValue.ts | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 src/modules/checkQuiz/hooks/useDebouncedValue.ts diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 254589b..defa243 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -6,6 +6,7 @@ import useCheckQuizStore from '@checkQuiz/store/checkQuizStore' import { Section } from '@checkQuiz/types' import { useFetchDashboard } from '@checkQuiz/api/useDashboard' import { AddIcon } from '@chakra-ui/icons'; +import useDebouncedValue from '@checkQuiz/hooks/useDebouncedValue' interface FiltersProps { question?: boolean @@ -28,22 +29,12 @@ const Filters: React.FC = ({ state.setLeaderboard, ]) const [searchQuery, setSearchQuery] = useState('') - const [debouncedSearchQuery, setDebouncedSearchQuery] = useState(searchQuery) + const debouncedSearchQuery = useDebouncedValue(searchQuery, 300) const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value.toLocaleLowerCase()) } - useEffect(() => { - const handler = setTimeout(() => { - setDebouncedSearchQuery(searchQuery); - }, 300); - - return () => { - clearTimeout(handler); - }; - }, [searchQuery]); - const { data, isFetched, refetch } = useFetchDashboard(quizId, sectionIndex, debouncedSearchQuery) useEffect(() => { @@ -86,7 +77,7 @@ const Filters: React.FC = ({ const handleLeaderboard = (sectionIndex: number | null) => { generateLeaderboard( - { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, // Correct property name + { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, { onSuccess: () => { console.log('Leaderboard generated successfully') diff --git a/src/modules/checkQuiz/hooks/useDebouncedValue.ts b/src/modules/checkQuiz/hooks/useDebouncedValue.ts new file mode 100644 index 0000000..cf768ad --- /dev/null +++ b/src/modules/checkQuiz/hooks/useDebouncedValue.ts @@ -0,0 +1,19 @@ +import {useState, useEffect} from 'react' + +const useDebouncedValue = (value: T, delay: number): T => { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value) + }, delay) + + return () => { + clearTimeout(handler) + } + }, [value, delay]) + + return debouncedValue +} + +export default useDebouncedValue \ No newline at end of file From dbc59ff81f049f8b14f04b74220c26f33adafbe0 Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Wed, 18 Sep 2024 16:00:29 +0530 Subject: [PATCH 07/11] sort and search intersection working and prefix search Signed-off-by: ayushka11 --- src/modules/checkQuiz/api/useLeaderboard.tsx | 1 - src/modules/checkQuiz/components/Filters.tsx | 44 +++++++------------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/modules/checkQuiz/api/useLeaderboard.tsx b/src/modules/checkQuiz/api/useLeaderboard.tsx index dcad105..9d23d2a 100644 --- a/src/modules/checkQuiz/api/useLeaderboard.tsx +++ b/src/modules/checkQuiz/api/useLeaderboard.tsx @@ -1,5 +1,4 @@ import { useMutation } from '@tanstack/react-query' -import axiosInstance from './axiosInstance' import { GenerateLeaderboard } from './generateLeaderboard' export const useLeaderboard = () => { diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index defa243..82a53ff 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -7,6 +7,7 @@ import { Section } from '@checkQuiz/types' import { useFetchDashboard } from '@checkQuiz/api/useDashboard' import { AddIcon } from '@chakra-ui/icons'; import useDebouncedValue from '@checkQuiz/hooks/useDebouncedValue' +import { useNavigate, useLocation } from 'react-router-dom'; // For URL handling interface FiltersProps { question?: boolean @@ -30,6 +31,9 @@ const Filters: React.FC = ({ ]) const [searchQuery, setSearchQuery] = useState('') const debouncedSearchQuery = useDebouncedValue(searchQuery, 300) + + const navigate = useNavigate(); // For navigating without reloading + const location = useLocation(); // For getting current URL const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value.toLocaleLowerCase()) @@ -69,43 +73,30 @@ const Filters: React.FC = ({ }, [sections, searchQuery]) const { mutate: generateLeaderboard } = useLeaderboard() - const { - data: sectionData, - isFetched: sectionDataIsFetched, - refetch: sectionDataRefetch, - } = useFetchDashboard(quizId, sectionIndex, debouncedSearchQuery) const handleLeaderboard = (sectionIndex: number | null) => { + console.log('handleLeaderboard - sectionIndex:', sectionIndex); + console.log('handleLeaderboard - searchQuery:', debouncedSearchQuery); generateLeaderboard( { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, { onSuccess: () => { + refetch() // Refetch the data without reloading console.log('Leaderboard generated successfully') }, }, ) } - - - // TODO: fetch assignees from athena - const [availableAssignees] = useState([ - { value: '1', label: 'A' }, - { value: '2', label: 'B' }, - { value: '3', label: 'C' }, - { value: '4', label: 'D' }, - { value: '5', label: 'E' }, - ]) - - const handleAssigneesChange = (selectedOptions: any) => { - const selectedAssignees = Array.isArray(selectedOptions) ? selectedOptions : [selectedOptions] - setAssignees(selectedAssignees) - } + // Modify sectionIndex handling to update the URL without causing a page reload const handleSectionChange = (e: React.ChangeEvent) => { - if (e.target.value != '') { - setSectionIndex(parseInt(e.target.value)) + const value = e.target.value; + console.log('value', value); + if (value !== '') { + const newSectionIndex = parseInt(value, 10); + setSectionIndex(newSectionIndex); } else { - setSectionIndex(null) + setSectionIndex(null); } } @@ -113,10 +104,6 @@ const Filters: React.FC = ({ console.log('Add button clicked'); }; - useEffect(() => { - sectionDataRefetch() - }, [sectionIndex]) - return ( <> @@ -191,7 +178,6 @@ const Filters: React.FC = ({ fontWeight='400' onClick={() => { handleLeaderboard(sectionIndex) - window.location.reload() }} > Generate Leaderboard @@ -223,4 +209,4 @@ const Filters: React.FC = ({ ) } -export default Filters +export default Filters; From fbc2f458600b89555541735fadc387eee912083d Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Wed, 18 Sep 2024 19:36:09 +0530 Subject: [PATCH 08/11] multi correct ui fix Signed-off-by: ayushka11 --- .../createQuiz/forms/QuestionDetails.tsx | 114 +++++++++++------- 1 file changed, 69 insertions(+), 45 deletions(-) diff --git a/src/modules/createQuiz/forms/QuestionDetails.tsx b/src/modules/createQuiz/forms/QuestionDetails.tsx index f92232c..44b5d00 100644 --- a/src/modules/createQuiz/forms/QuestionDetails.tsx +++ b/src/modules/createQuiz/forms/QuestionDetails.tsx @@ -18,6 +18,11 @@ import { Switch, Text, VStack, + Menu, + MenuButton, + MenuList, + MenuItem, + Checkbox, } from '@chakra-ui/react' import select from 'react-select' import { useEffect, useState } from 'react' @@ -103,6 +108,43 @@ const QuestionDetails = () => { } }, [isFetched, isLoading, data]) + const renderCorrectAnswerMenu = () => { + if (type === QuestionType.SUB) return null; + + return ( + + + Answer: + + + + + {answer.length > 0 ? `${answer.length} selected` : 'Select correct answers'} + + + {options.map((option) => ( + + { + if (e.target.checked) { + setAnswer((prev) => [...prev, option.id]); + } else { + setAnswer((prev) => prev.filter((id) => id !== option.id)); + } + }} + > + {option.label} + + + ))} + + + + + ); + }; + const renderChoiceBuilder = () => { if (type === QuestionType.SUB) return null @@ -184,52 +226,34 @@ const QuestionDetails = () => { - - - Marks: - - setMarks(parseInt(e.target.value, 10))} - /> - - {type === QuestionType.MCQ && ( - <> - - - Autocheck: - - setAutoCheck(e.target.checked)} - /> - - - - Answer: - - - - - )} + + + Marks: + + setMarks(parseInt(e.target.value, 10))} + /> + + {type === QuestionType.MCQ && ( + <> + + + Autocheck: + + setAutoCheck(e.target.checked)} + /> + {renderCorrectAnswerMenu()} + + )} + + {type === QuestionType.SUB && ( From 4dac85fa6a53e91b8c793ca6d55ea46f0133fd91 Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Wed, 18 Sep 2024 21:48:41 +0530 Subject: [PATCH 09/11] consoles removed Signed-off-by: ayushka11 --- src/modules/checkQuiz/components/Filters.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 82a53ff..58bd8ae 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -75,14 +75,11 @@ const Filters: React.FC = ({ const { mutate: generateLeaderboard } = useLeaderboard() const handleLeaderboard = (sectionIndex: number | null) => { - console.log('handleLeaderboard - sectionIndex:', sectionIndex); - console.log('handleLeaderboard - searchQuery:', debouncedSearchQuery); generateLeaderboard( { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, { onSuccess: () => { refetch() // Refetch the data without reloading - console.log('Leaderboard generated successfully') }, }, ) @@ -91,7 +88,6 @@ const Filters: React.FC = ({ // Modify sectionIndex handling to update the URL without causing a page reload const handleSectionChange = (e: React.ChangeEvent) => { const value = e.target.value; - console.log('value', value); if (value !== '') { const newSectionIndex = parseInt(value, 10); setSectionIndex(newSectionIndex); From a6ab84e399d1c76a20b2ea352597a58ea8414fdb Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Thu, 19 Sep 2024 22:27:13 +0530 Subject: [PATCH 10/11] color changes and sort temporary state change Signed-off-by: ayushka11 --- src/modules/checkQuiz/components/Filters.tsx | 33 ++++++++----------- .../checkQuiz/components/Leaderboard.tsx | 4 +-- .../createQuiz/forms/QuestionDetails.tsx | 7 +++- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 58bd8ae..6236e57 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -23,7 +23,8 @@ const Filters: React.FC = ({ const [assignees, setAssignees] = useState([]) const [isAutocheckModalOpen, setIsAutocheckModalOpen] = useState(false) const [totalAutocheckQuestions, setTotalAutocheckQuestions] = useState(0) - const [sectionIndex, setSectionIndex] = useState(null) + const [sectionIndex, setSectionIndex] = useState(null) // Actual sectionIndex state + const [tempSectionIndex, setTempSectionIndex] = useState(null) // Temporary sectionIndex state const [quizId] = useCheckQuizStore((state) => [state.quizId]) const [leaderboard, setLeaderboard] = useCheckQuizStore((state) => [ state.leaderboard, @@ -31,9 +32,9 @@ const Filters: React.FC = ({ ]) const [searchQuery, setSearchQuery] = useState('') const debouncedSearchQuery = useDebouncedValue(searchQuery, 300) - - const navigate = useNavigate(); // For navigating without reloading - const location = useLocation(); // For getting current URL + + const navigate = useNavigate(); + const location = useLocation(); const handleSearchChange = (e: React.ChangeEvent) => { setSearchQuery(e.target.value.toLocaleLowerCase()) @@ -52,12 +53,9 @@ const Filters: React.FC = ({ setLeaderboard(data?.sectionLeaderboard[0].participants || []) } } - } else { - refetch() } - }, [sectionIndex, isFetched, data]) + }, [sectionIndex, isFetched, data, setLeaderboard]) - useEffect(() => { if (sections) { let totalAutocheckQuestionsCount = 0 @@ -74,25 +72,24 @@ const Filters: React.FC = ({ const { mutate: generateLeaderboard } = useLeaderboard() - const handleLeaderboard = (sectionIndex: number | null) => { + const handleLeaderboard = () => { + setSectionIndex(tempSectionIndex); generateLeaderboard( - { quizId, sectionIndex, searchQuery: debouncedSearchQuery }, + { quizId, sectionIndex: tempSectionIndex, searchQuery: debouncedSearchQuery }, { onSuccess: () => { - refetch() // Refetch the data without reloading + refetch() }, }, ) } - // Modify sectionIndex handling to update the URL without causing a page reload const handleSectionChange = (e: React.ChangeEvent) => { const value = e.target.value; if (value !== '') { - const newSectionIndex = parseInt(value, 10); - setSectionIndex(newSectionIndex); + setTempSectionIndex(parseInt(value, 10)); } else { - setSectionIndex(null); + setTempSectionIndex(null); } } @@ -153,7 +150,7 @@ const Filters: React.FC = ({ width='12rem' placeholder='None' color='grey' - onChange={handleSectionChange} + onChange={handleSectionChange} > {sections.map((section, index) => ( - + {answer.length > 0 ? `${answer.length} selected` : 'Select correct answers'} From 28696a0d3654ee29cc77fb5d34c75bb7446b91da Mon Sep 17 00:00:00 2001 From: ayushka11 Date: Fri, 20 Sep 2024 23:12:49 +0530 Subject: [PATCH 11/11] leaderboard change done Signed-off-by: ayushka11 --- .../checkQuiz/api/generateLeaderboard.tsx | 16 ++++---------- src/modules/checkQuiz/components/Filters.tsx | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/modules/checkQuiz/api/generateLeaderboard.tsx b/src/modules/checkQuiz/api/generateLeaderboard.tsx index c50f1be..1f998bc 100644 --- a/src/modules/checkQuiz/api/generateLeaderboard.tsx +++ b/src/modules/checkQuiz/api/generateLeaderboard.tsx @@ -11,23 +11,15 @@ export const GenerateLeaderboard = async ({ searchQuery: string | null }) => { try { - if (sectionIndex === null && searchQuery === null) { - const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}`) + if (searchQuery === null) { + const res = await axiosInstance.patch(`/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}`,) return res.data - } else if (sectionIndex !== null && searchQuery === null) { - const res = await axiosInstance.patch( - `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}`, - ) - return res.data - } else if (sectionIndex === null && searchQuery !== null) { - const res = await axiosInstance.patch(`/checkQuiz/leaderboard/${quizId}?search=${searchQuery}`) - return res.data - } else { + } else{ const res = await axiosInstance.patch( `/checkQuiz/generateSectionLeaderboard/${quizId}/${sectionIndex}?search=${searchQuery}`, ) return res.data - } + } } catch (e: any) { if (axios.isAxiosError(e)) { return e.response?.data || e.message diff --git a/src/modules/checkQuiz/components/Filters.tsx b/src/modules/checkQuiz/components/Filters.tsx index 6236e57..638926c 100644 --- a/src/modules/checkQuiz/components/Filters.tsx +++ b/src/modules/checkQuiz/components/Filters.tsx @@ -74,16 +74,21 @@ const Filters: React.FC = ({ const handleLeaderboard = () => { setSectionIndex(tempSectionIndex); - generateLeaderboard( - { quizId, sectionIndex: tempSectionIndex, searchQuery: debouncedSearchQuery }, - { - onSuccess: () => { - refetch() - }, - }, - ) } + useEffect(() => { + if (quizId !== null) { + generateLeaderboard( + { quizId, sectionIndex: sectionIndex, searchQuery: debouncedSearchQuery }, + { + onSuccess: () => { + refetch(); + }, + } + ); + } + }, [sectionIndex, quizId, debouncedSearchQuery, generateLeaderboard, refetch]); + const handleSectionChange = (e: React.ChangeEvent) => { const value = e.target.value; if (value !== '') {