diff --git a/package-lock.json b/package-lock.json index 3ef4561e..ec5213eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,7 @@ "@types/react-router-dom": "^5.3.3", "axios": "^1.4.0", "bootstrap": "^5.3.3", - "chart.js": "^3.7.0", + "chart.js": "^4.1.1", "formik": "^2.2.9", "jquery": "^3.7.1", "jwt-decode": "^3.1.2", @@ -38,7 +38,7 @@ "react-redux": "^8.0.5", "react-router-dom": "^6.11.1", "react-scripts": "^5.0.1", - "recharts": "^2.12.3", + "recharts": "^2.0.0", "redux-persist": "^6.0.0", "sass": "^1.62.1", "save": "^2.9.0", @@ -3045,6 +3045,12 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", @@ -5760,9 +5766,16 @@ } }, "node_modules/chart.js": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.7.0.tgz", - "integrity": "sha512-31gVuqqKp3lDIFmzpKIrBeum4OpZsQjSIAqlOpgjosHDJZlULtvwLEZKtEhIAZc7JMPaHlYMys40Qy9Mf+1AAg==" + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.8.tgz", + "integrity": "sha512-IkGZlVpXP+83QpMm4uxEiGqSI7jFizwVtF3+n5Pc3k7sMO+tkd0qxh2OzLhenM0K80xtmAONWGBn082EiBQSDA==", + "license": "MIT", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } }, "node_modules/check-types": { "version": "11.2.3", @@ -16603,6 +16616,28 @@ "node": ">= 0.8" } }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, "node_modules/void-elements": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", diff --git a/src/App.test.tsx b/src/App.test.tsx index 2a68616d..a2973e6a 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,5 +1,8 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import { render, screen, fireEvent, waitFor } from "@testing-library/react"; +import { MemoryRouter, Route, Routes } from "react-router-dom"; +import ReviewTable from 'components/HeatGrid/ReviewTable'; + import App from './App'; test('renders learn react link', () => { @@ -7,3 +10,64 @@ test('renders learn react link', () => { const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); }); + + +describe("ReviewTable page", () => { + const setup = () => + render( + + + } /> + + + ); + + test("renders summary report and team info", async () => { + setup(); + expect(screen.getByText(/Summary Report: Program 2/i)).toBeInTheDocument(); + expect(screen.getByText(/Team:/i)).toBeInTheDocument(); + }); + + test("renders submission links", async () => { + setup(); + expect( + screen.getByText("https://github.ncsu.edu/Program-2-Ruby-on-Rails/WolfEvents") + ).toBeInTheDocument(); + expect(screen.getByText("README.md")).toBeInTheDocument(); + }); + + test("renders round selector", () => { + setup(); + expect(screen.getByText(/Round/i)).toBeInTheDocument(); + }); + + test("renders word count checkboxes", () => { + setup(); + expect(screen.getByLabelText(/> 10 Word Comments/i)).toBeInTheDocument(); + expect(screen.getByLabelText(/> 20 Word Comments/i)).toBeInTheDocument(); + }); + + test("shows Word Count column when checkbox is selected", async () => { + setup(); + + // Before clicking: Word Count column should not be visible + expect(screen.queryByText(/Word Count/i)).not.toBeInTheDocument(); + + // Click the checkbox to show word count + const checkbox10 = screen.getByLabelText(/> 10 Word Comments/i); + fireEvent.click(checkbox10); + + // Wait for DOM update + await waitFor(() => { + expect(screen.getAllByText(/Word Count/i).length).toBeGreaterThan(0); + }); + }); + + test("toggle sort by total score", () => { + setup(); + const button = screen.getByText(/Sort by Total Review Score/i); + fireEvent.click(button); + expect(button.textContent).toMatch(/desc|asc/i); + }); +}); + diff --git a/src/App.tsx b/src/App.tsx index 27736ba3..1b2d5029 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -30,7 +30,7 @@ import { loadCourseInstructorDataAndInstitutions } from "pages/Courses/CourseUti import TA from "pages/TA/TA"; import TAEditor from "pages/TA/TAEditor"; import { loadTAs } from "pages/TA/TAUtil"; -import ReviewTable from "./pages/ViewTeamGrades/ReviewTable"; +import ReviewTable from "./components/HeatGrid/ReviewTable"; import EditProfile from "pages/Profile/Edit"; import Reviews from "pages/Reviews/reviews"; import Email_the_author from "./pages/Email_the_author/email_the_author"; diff --git a/src/pages/ViewTeamGrades/App.tsx b/src/components/HeatGrid/App.tsx similarity index 100% rename from src/pages/ViewTeamGrades/App.tsx rename to src/components/HeatGrid/App.tsx diff --git a/src/pages/ViewTeamGrades/BarGraph.tsx b/src/components/HeatGrid/BarGraph.tsx similarity index 100% rename from src/pages/ViewTeamGrades/BarGraph.tsx rename to src/components/HeatGrid/BarGraph.tsx diff --git a/src/pages/ViewTeamGrades/CircularProgress.tsx b/src/components/HeatGrid/CircularProgress.tsx similarity index 100% rename from src/pages/ViewTeamGrades/CircularProgress.tsx rename to src/components/HeatGrid/CircularProgress.tsx diff --git a/src/pages/ViewTeamGrades/Filters.tsx b/src/components/HeatGrid/Filters.tsx similarity index 100% rename from src/pages/ViewTeamGrades/Filters.tsx rename to src/components/HeatGrid/Filters.tsx diff --git a/src/components/HeatGrid/ReviewTable.tsx b/src/components/HeatGrid/ReviewTable.tsx new file mode 100644 index 00000000..7c7cb2f7 --- /dev/null +++ b/src/components/HeatGrid/ReviewTable.tsx @@ -0,0 +1,167 @@ +import React, { useEffect, useState } from "react"; +import RoundSelector from "./RoundSelector"; +import dummyDataRounds from "../../pages/ViewTeamGrades/Data/heatMapData.json"; +import dummyData from "../../pages/ViewTeamGrades/Data/dummyData.json"; +import "../../pages/ViewTeamGrades/grades.scss"; +import { Link } from "react-router-dom"; +import Statistics from "./Statistics"; +import Filters from "./Filters"; +import ShowReviews from "./ShowReviews"; +import dummyauthorfeedback from "../../pages/ViewTeamGrades/Data/authorFeedback.json"; +import ReviewTableContent from "./ReviewTableContent"; + +interface ReviewTableProps { + currentUser?: { id: string }; + project?: { student: { id: string } }; +} + +const ReviewTable: React.FC = ({ currentUser, project }) => { + const [currentRound, setCurrentRound] = useState(-1); + const [sortOrderRow, setSortOrderRow] = useState<"asc" | "desc" | "none">("none"); + const [sortByTotalScore, setSortByTotalScore] = useState<"asc" | "desc" | "none">("none"); + const [showToggleQuestion, setShowToggleQuestion] = useState(false); + const [teamMembers, setTeamMembers] = useState([]); + const [showReviews, setShowReviews] = useState(false); + const [ShowAuthorFeedback, setShowAuthorFeedback] = useState(false); + const [roundSelected, setRoundSelected] = useState(-1); + + useEffect(() => { + setTeamMembers(dummyData.members); + }, []); + + const toggleSortOrderRow = () => { + setSortOrderRow((prev) => + prev === "asc" ? "desc" : prev === "desc" ? "none" : "asc" + ); + }; + + const toggleSortByTotalScore = () => { + setSortByTotalScore((prev) => + prev === "asc" ? "desc" : prev === "desc" ? "none" : "asc" + ); + }; + + const toggleShowReviews = () => setShowReviews((prev) => !prev); + const toggleAuthorFeedback = () => setShowAuthorFeedback((prev) => !prev); + const selectRound = (r: number) => setRoundSelected(r); + const toggleShowQuestion = () => setShowToggleQuestion(!showToggleQuestion); + const handleRoundChange = (roundIndex: number) => setCurrentRound(roundIndex); + + return ( +
+

Summary Report: Program 2

+
Team: {dummyData.team}
+ + Team members:{" "} + {teamMembers.map((member, index) => ( + + {member} + {index !== teamMembers.length - 1 && ", "} + + ))} + + +
+
Submission Links
+ +
+ + +
+ + + + + {/* Render Round(s) */} + {currentRound === -1 + ? dummyDataRounds.map((roundData, index) => ( + + )) + : ( + + )} + + + + {showReviews && ( +
+

Reviews

+ +
+ )} + + {ShowAuthorFeedback && ( +
+

Author Feedback

+ +
+ )} + +
+

Grade and comment for submission

+ Grade: {dummyData.grade} +
+ Comment: {dummyData.comment} +
+ Late Penalty: {dummyData.late_penalty} +
+
+ + Back +
+ ); +}; + +export default ReviewTable; \ No newline at end of file diff --git a/src/components/HeatGrid/ReviewTableContent.tsx b/src/components/HeatGrid/ReviewTableContent.tsx new file mode 100644 index 00000000..fd7ff1ed --- /dev/null +++ b/src/components/HeatGrid/ReviewTableContent.tsx @@ -0,0 +1,181 @@ +import React, { useState } from "react"; +import ReviewTableRow from "./ReviewTableRow"; +import { Button } from "react-bootstrap"; +import ToolTip from "components/ToolTip"; +import { calculateAverages } from "../../pages/ViewTeamGrades/utils"; +import { Review } from "./types"; + +interface RoundData { + questionNumber: string; + questionText: string; + reviews: Review[]; + RowAvg: number; + maxScore: number; +} + +interface ReviewTableContentProps { + roundData: RoundData[]; + roundIndex: number; + currentUser?: { id: string }; + project?: { student: { id: string } }; + sortOrderRow: "asc" | "desc" | "none"; + toggleSortOrderRow: () => void; + sortByTotalScore: "asc" | "desc" | "none"; + toggleSortByTotalScore: () => void; + toggleShowQuestion: () => void; + showToggleQuestion: boolean; +} + +const ReviewTableContent: React.FC = ({ + roundData, + roundIndex, + currentUser, + project, + sortOrderRow, + toggleSortOrderRow, + sortByTotalScore, + toggleSortByTotalScore, + showToggleQuestion, + toggleShowQuestion +}) => { + const { averagePeerReviewScore, columnAverages, sortedData } = calculateAverages( + roundData, + sortOrderRow + ); + const [showWordComments, setshowWordComments] = useState(0); + + let displayData = [...sortedData]; + if (sortByTotalScore !== "none") { + displayData.sort((a, b) => { + const totalA = a.reviews.reduce((sum, r) => sum + r.score, 0); + const totalB = b.reviews.reduce((sum, r) => sum + r.score, 0); + return sortByTotalScore === "asc" ? totalA - totalB : totalB - totalA; + }); + } + + return ( +
+
+

Review (Round: {roundIndex + 1})

+
+ + +
+
{/* USE gap-4 for EVEN Spacing */} + + {showToggleQuestion ? "toggle question list" : "toggle question list"} + + + + hide tags + + + + color legend + + + + interaction legend + +
+ +
+ + + + + + {showToggleQuestion && ( + + )} + {roundData[0]?.reviews?.map((review, index) => ( + + ))} + {showWordComments != 0 && ( + + )} + + + + + {displayData.map((row, index) => ( + + ))} + + + {showToggleQuestion && } + {columnAverages.map((avg, index) => ( + + ))} + + +
Question No.Question + {currentUser?.id === project?.student?.id + ? `Review ${index + 1}` + : review.name} + + Word Count + + Average + {sortOrderRow === "none" && ▲▼} + {sortOrderRow === "asc" && } + {sortOrderRow === "desc" && } +
Avg + {avg.toFixed(2)} +
+
+ + Teamates: + {["Raj Patel", "Aditya Pai", "Parth Kulkarni"].map((teammate, index) => ( + + {teammate} + + ))} + +
+
+
+ Average peer review score:{" "} + {averagePeerReviewScore} +
+
+
+ ); +}; + +export default ReviewTableContent; diff --git a/src/pages/ViewTeamGrades/ReviewTableRow.tsx b/src/components/HeatGrid/ReviewTableRow.tsx similarity index 56% rename from src/pages/ViewTeamGrades/ReviewTableRow.tsx rename to src/components/HeatGrid/ReviewTableRow.tsx index ffa4e5b6..39225b4f 100644 --- a/src/pages/ViewTeamGrades/ReviewTableRow.tsx +++ b/src/components/HeatGrid/ReviewTableRow.tsx @@ -1,15 +1,40 @@ -import React, { useState, useEffect } from "react"; -import { getColorClass } from "./utils"; // Importing utility functions +import React from "react"; +import { getColorClass } from "../../pages/ViewTeamGrades/utils"; // Importing utility functions import { ReviewData } from "./App"; // Importing the ReviewData interface from App // Props interface for ReviewTableRow component interface ReviewTableRowProps { - row: ReviewData; // Data for the row - showToggleQuestion: boolean; // Flag to toggle the question column + row: ReviewData; + showToggleQuestion: boolean; + showWordCount: number; // NEW } +// Helper function to calculate word count +const calculateWordCount = (comment?: string) => { + return comment ? comment.split(/\s+/).filter((word) => word).length : 0; +}; + +// Helper function to count short and long comments +const countShortAndLongComments = (reviews: { comment?: string }[]) => { + let shortCount = 0; + let longCount = 0; + + reviews.forEach((review) => { + const wordCount = calculateWordCount(review.comment); + if (wordCount > 20) { + longCount++; + } else if (wordCount <= 10) { + shortCount++; + } + }); + + return { shortCount, longCount }; +}; + // Functional component ReviewTableRow -const ReviewTableRow: React.FC = ({ row, showToggleQuestion }) => { +const ReviewTableRow: React.FC = ({ row, showToggleQuestion , showWordCount }) => { + const { shortCount, longCount } = countShortAndLongComments(row.reviews); + return ( {/* Question Number */} @@ -23,6 +48,7 @@ const ReviewTableRow: React.FC = ({ row, showToggleQuestion       {row.questionNumber} + {/* Toggle Question */} {showToggleQuestion && {row.questionText}} @@ -41,10 +67,19 @@ const ReviewTableRow: React.FC = ({ row, showToggleQuestion ))} + {showWordCount !=0 && ( + + {showWordCount >= 20 && `${longCount}`} + {showWordCount <= 10 && `${shortCount}`} + + )} + + + {/* Row Average */} {row.RowAvg.toFixed(2)} ); }; -export default ReviewTableRow; // Exporting the ReviewTableRow component as default +export default ReviewTableRow; // Exporting the ReviewTableRow component as default \ No newline at end of file diff --git a/src/pages/ViewTeamGrades/RoundSelector.tsx b/src/components/HeatGrid/RoundSelector.tsx similarity index 87% rename from src/pages/ViewTeamGrades/RoundSelector.tsx rename to src/components/HeatGrid/RoundSelector.tsx index 103362d1..025b8893 100644 --- a/src/pages/ViewTeamGrades/RoundSelector.tsx +++ b/src/components/HeatGrid/RoundSelector.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from "react"; -import dummyDataRounds from "./Data/heatMapData.json"; -import teamData from "./Data/dummyData.json"; +import dummyDataRounds from "../../pages/ViewTeamGrades/Data/heatMapData.json"; +import teamData from "../../pages/ViewTeamGrades/Data/dummyData.json"; interface RoundSelectorProps { currentRound: number; diff --git a/src/pages/ViewTeamGrades/ShowReviews.tsx b/src/components/HeatGrid/ShowReviews.tsx similarity index 97% rename from src/pages/ViewTeamGrades/ShowReviews.tsx rename to src/components/HeatGrid/ShowReviews.tsx index 570a412e..a3786e44 100644 --- a/src/pages/ViewTeamGrades/ShowReviews.tsx +++ b/src/components/HeatGrid/ShowReviews.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { getColorClass } from "./utils"; +import { getColorClass } from "../../pages/ViewTeamGrades/utils"; import { RootState } from "../../store/store"; import { useDispatch, useSelector } from "react-redux"; diff --git a/src/pages/ViewTeamGrades/Statistics.tsx b/src/components/HeatGrid/Statistics.tsx similarity index 90% rename from src/pages/ViewTeamGrades/Statistics.tsx rename to src/components/HeatGrid/Statistics.tsx index e26d175a..34be5b0f 100644 --- a/src/pages/ViewTeamGrades/Statistics.tsx +++ b/src/components/HeatGrid/Statistics.tsx @@ -1,10 +1,10 @@ // Statistics.tsx import React, { useState, useEffect } from "react"; -import { calculateAverages } from "./utils"; -import "./grades.scss"; -import dummyDataRounds from "./Data/heatMapData.json"; // Importing dummy data for rounds -import dummyauthorfeedback from "./Data/authorFeedback.json"; // Importing dummy data for author feedback -import teammateData from "./Data/teammateData.json"; +import { calculateAverages } from "../../pages/ViewTeamGrades/utils"; +import "../../pages/ViewTeamGrades/grades.scss"; +import dummyDataRounds from "../../pages/ViewTeamGrades/Data/heatMapData.json"; // Importing dummy data for rounds +import dummyauthorfeedback from "../../pages/ViewTeamGrades/Data/authorFeedback.json"; // Importing dummy data for author feedback +import teammateData from "../../pages/ViewTeamGrades/Data/teammateData.json"; //props for statistics component interface StatisticsProps {} diff --git a/src/pages/ViewTeamGrades/teamMarks.tsx b/src/components/HeatGrid/teamMarks.tsx similarity index 100% rename from src/pages/ViewTeamGrades/teamMarks.tsx rename to src/components/HeatGrid/teamMarks.tsx diff --git a/src/components/HeatGrid/types.ts b/src/components/HeatGrid/types.ts new file mode 100644 index 00000000..5069631e --- /dev/null +++ b/src/components/HeatGrid/types.ts @@ -0,0 +1,5 @@ +export interface Review { + name: string; + score: number; + comment?: string; + } \ No newline at end of file diff --git a/src/hooks/useAPI.ts b/src/hooks/useAPI.ts index 47ba7ee5..416995c3 100644 --- a/src/hooks/useAPI.ts +++ b/src/hooks/useAPI.ts @@ -6,7 +6,7 @@ import { getAuthToken } from "../utils/auth"; * @author Ankur Mundra on April, 2023 */ -axios.defaults.baseURL = "http://localhost:3002/api/v1"; +axios.defaults.baseURL = "http://152.7.178.127:3002/api/v1"; axios.defaults.headers.common["Accept"] = "application/json"; axios.defaults.headers.post["Content-Type"] = "application/json"; axios.defaults.headers.put["Content-Type"] = "application/json"; diff --git a/src/pages/Authentication/Login.tsx b/src/pages/Authentication/Login.tsx index 2051b297..e52d953d 100644 --- a/src/pages/Authentication/Login.tsx +++ b/src/pages/Authentication/Login.tsx @@ -30,7 +30,7 @@ const Login: React.FC = () => { const onSubmit = (values: ILoginFormValues, submitProps: FormikHelpers) => { axios - .post("http://localhost:3002/login", values) + .post("http://152.7.178.127:3002/login", values) .then((response) => { const payload = setAuthToken(response.data.token); diff --git a/src/pages/ViewTeamGrades/ReviewTable.tsx b/src/pages/ViewTeamGrades/ReviewTable.tsx deleted file mode 100644 index 5aa18db7..00000000 --- a/src/pages/ViewTeamGrades/ReviewTable.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import React, { useEffect, useState } from "react"; -import ReviewTableRow from "./ReviewTableRow"; -import RoundSelector from "./RoundSelector"; -import dummyDataRounds from "./Data/heatMapData.json"; -import dummyData from "./Data/dummyData.json"; -import { calculateAverages, getColorClass } from "./utils"; -import "./grades.scss"; -import { Link } from "react-router-dom"; -import Statistics from "./Statistics"; -import Filters from "./Filters"; -import ShowReviews from "./ShowReviews"; //importing show reviews component -import dummyauthorfeedback from "./Data/authorFeedback.json"; // Importing dummy data for author feedback - -const ReviewTable: React.FC = () => { - const [currentRound, setCurrentRound] = useState(-1); - const [sortOrderRow, setSortOrderRow] = useState<"asc" | "desc" | "none">("none"); - const [showToggleQuestion, setShowToggleQuestion] = useState(false); - const [open, setOpen] = useState(false); - const [teamMembers, setTeamMembers] = useState([]); - const [showReviews, setShowReviews] = useState(false); - const [ShowAuthorFeedback, setShowAuthorFeedback] = useState(false); - const [roundSelected, setRoundSelected] = useState(-1); - - useEffect(() => { - setTeamMembers(dummyData.members); - }, []); - - const toggleSortOrderRow = () => { - setSortOrderRow((prevSortOrder) => { - if (prevSortOrder === "asc") return "desc"; - if (prevSortOrder === "desc") return "none"; - return "asc"; - }); - }; - - const toggleShowReviews = () => { - setShowReviews((prev) => !prev); - }; - - const selectRound = (r: number) => { - setRoundSelected((prev) => r); - }; - - // Function to toggle the visibility of ShowAuthorFeedback component - const toggleAuthorFeedback = () => { - setShowAuthorFeedback((prev) => !prev); - }; - - const handleRoundChange = (roundIndex: number) => { - setCurrentRound(roundIndex); - }; - - const toggleShowQuestion = () => { - setShowToggleQuestion(!showToggleQuestion); - }; - - const renderTable = (roundData: any, roundIndex: number) => { - const { averagePeerReviewScore, columnAverages, sortedData } = calculateAverages( - roundData, - sortOrderRow - ); - - return ( -
-

- Review (Round: {roundIndex + 1} of {dummyDataRounds.length}) -

- - - - - {showToggleQuestion && ( - - )} - {Array.from({ length: roundData[0].reviews.length }, (_, i) => ( - - ))} - - - - - {sortedData.map((row, index) => ( - - ))} - - - {showToggleQuestion && } - {columnAverages.map((avg, index) => ( - - ))} - - -
- Question No. - - Question - {`Review ${ - i + 1 - }`} - Average - {sortOrderRow === "none" && ▲▼} - {sortOrderRow === "asc" && } - {sortOrderRow === "desc" && } -
- Avg - - {avg.toFixed(2)} -
-
-
- Average peer review score:{" "} - {averagePeerReviewScore} -
-
-
- ); - }; - - return ( -
-

Summary Report: Program 2

-
Team: {dummyData.team}
- - Team members:{" "} - {teamMembers.map((member, index) => ( - - {member} - {index !== teamMembers.length - 1 && ", "} - - ))} - - - - - -
- - - -
- - -
- - {/* Conditionally render tables based on currentRound */} - {currentRound === -1 - ? dummyDataRounds.map((roundData, index) => renderTable(roundData, index)) // Render a table for each round if "All Rounds" is selected - : renderTable(dummyDataRounds[currentRound], currentRound)} - -
- -
- -
- {showReviews && ( -
-

Reviews

- -
- )} - {ShowAuthorFeedback && ( -
-

Author Feedback

- -
- )} -
- -

-

Grade and comment for submission

- Grade: {dummyData.grade} -
- Comment: {dummyData.comment} -
- Late Penalty: {dummyData.late_penalty} -
-

- - Back -
- ); -}; - -export default ReviewTable; diff --git a/src/pages/ViewTeamGrades/utils.ts b/src/pages/ViewTeamGrades/utils.ts index 8cf8d2a2..ada25a47 100644 --- a/src/pages/ViewTeamGrades/utils.ts +++ b/src/pages/ViewTeamGrades/utils.ts @@ -1,4 +1,4 @@ -import { ReviewData } from './App'; +import { ReviewData } from '../../components/HeatGrid/App'; // Function to get color class based on score and maxScore export const getColorClass = (score: number, maxScore: number) => { diff --git a/src/utils/axios_client.ts b/src/utils/axios_client.ts index b5fe47d7..77c9d2cd 100644 --- a/src/utils/axios_client.ts +++ b/src/utils/axios_client.ts @@ -6,7 +6,7 @@ import { getAuthToken } from "./auth"; */ const axiosClient = axios.create({ - baseURL: "http://localhost:3002/api/v1", + baseURL: "http://152.7.178.127:3002/api/v1", timeout: 1000, headers: { "Content-Type": "application/json",