-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add expert view and temporary auxilaries
Adds the expert view and auxiliary data and an auxiliary button to access the expert view temporarily in testing
- Loading branch information
1 parent
114a20c
commit b9db380
Showing
6 changed files
with
317 additions
and
0 deletions.
There are no files selected for viewing
75 changes: 75 additions & 0 deletions
75
playground/src/components/expert_evaluation/expert_view/likert_scale.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import React, { useState } from 'react'; | ||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; | ||
import {faCircleInfo} from "@fortawesome/free-solid-svg-icons/faCircleInfo"; | ||
|
||
interface SingleChoiceLikertScaleProps { | ||
title: string; | ||
summary: string; | ||
description: string; | ||
} | ||
|
||
const SingleChoiceLikertScale: React.FC<SingleChoiceLikertScaleProps> = ({ | ||
title, | ||
summary, | ||
description, | ||
}) => { | ||
const [selectedValue, setSelectedValue] = useState<number | null>(null); // No default value | ||
|
||
const handleInfoClick = () => { | ||
alert(description); | ||
}; | ||
|
||
const handleChange = (value: number) => { | ||
setSelectedValue(value); | ||
}; | ||
|
||
// Define background colors matching the slider colors | ||
const scaleColors = [ | ||
'bg-red-600', // First section | ||
'bg-orange-500', // Second section | ||
'bg-yellow-400', // Third section | ||
'bg-green-400', // Fourth section | ||
'bg-green-700', // Fifth section | ||
]; | ||
|
||
return ( | ||
<> | ||
{/* Title and Info Section */} | ||
<div className="flex items-center"> | ||
<h3 className="text-xl font-semibold mr-2">{title}</h3> | ||
<span | ||
onClick={handleInfoClick} | ||
className="text-gray-500 cursor-pointer hover:text-gray-700" | ||
role="img" | ||
aria-label="info" | ||
> | ||
<FontAwesomeIcon icon={faCircleInfo} /> | ||
</span> | ||
</div> | ||
|
||
{/* Question Section */} | ||
<p className="text-gray-800">{summary}</p> | ||
|
||
{/* Single Choice Likert Scale */} | ||
<div className="flex items-center w-full"> | ||
{[1, 2, 3, 4, 5].map((value, index) => ( | ||
<label | ||
key={value} | ||
className={`flex-1 flex items-center justify-center cursor-pointer py-0.5 ${scaleColors[index]} ${index === 0 ? 'rounded-l-full' : ''} ${index === 4 ? 'rounded-r-full' : ''}`} | ||
> | ||
<input | ||
type="radio" | ||
name="likert" | ||
value={value} | ||
checked={selectedValue === value} | ||
onChange={() => handleChange(value)} | ||
className={`w-4 h-4 ${selectedValue === value ? 'border-white bg-black border-4' : 'border-gray-400 bg-transparent border-2'} rounded-full appearance-none`} | ||
/> | ||
</label> | ||
))} | ||
</div> | ||
</> | ||
); | ||
}; | ||
|
||
export default SingleChoiceLikertScale; |
150 changes: 150 additions & 0 deletions
150
playground/src/components/expert_evaluation/expert_view/likert_scale_form.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import React from 'react'; | ||
import SingleChoiceLikertScale from "@/components/expert_evaluation/expert_view/likert_scale"; | ||
import TextSubmissionDetail from "@/components/details/submission_detail/text"; | ||
import type { TextSubmission } from "@/model/submission"; | ||
import {TextFeedback} from "@/model/feedback"; | ||
|
||
// Define the metric data | ||
const metrics = [ | ||
{ | ||
title: '✅ Correctness', | ||
summary: 'Is the feedback free of content errors?', | ||
description: ` | ||
**Good**: The feedback accurately reflects the submission, solution, and criteria, with no errors. | ||
**Mid**: The feedback is mostly accurate but includes minor errors that don’t impact the overall evaluation. | ||
**Bad**: The feedback contains major errors that misrepresent the submission or solution, likely causing confusion. | ||
`, | ||
}, | ||
{ | ||
title: '🎯 Actionability', | ||
summary: 'Can students realistically act on this feedback?', | ||
description: ` | ||
**Good**: The feedback provides specific steps for improvement or reinforces correct approaches. | ||
**Mid**: The feedback notes correctness or errors but lacks detailed improvement guidance. | ||
**Bad**: The feedback identifies errors without solutions or offers no additional insights for correct work. | ||
`, | ||
}, | ||
{ | ||
title: '💬 Tone', | ||
summary: 'Is the feedback respectful and constructive?', | ||
description: ` | ||
**Good**: The feedback is respectful and constructive, recognizing both strengths and areas for improvement. | ||
**Mid**: The feedback is professional but mainly corrective, with little positive reinforcement. | ||
**Bad**: The feedback is overly critical or dismissive, using unprofessional or disrespectful language. | ||
`, | ||
}, | ||
{ | ||
title: '🔍 Completeness', | ||
summary: 'Does the feedback cover all relevant aspects without unnecessary information?', | ||
description: ` | ||
**Good**: The feedback addresses all key aspects and avoids irrelevant details. | ||
**Mid**: The feedback covers most important points but may miss minor details or include some irrelevant information. | ||
**Bad**: The feedback misses important aspects or includes too much irrelevant content. | ||
`, | ||
}, | ||
]; | ||
|
||
// Define the submission and feedbacks data | ||
const submission: TextSubmission = { | ||
exercise_id: 0, | ||
meta: {}, | ||
type: "text", | ||
id: 1, | ||
text: 'Groups are a loosely coupled amount of people whereas teams are people who work for the same goal together.' | ||
}; | ||
|
||
// Define the Feedbacks type | ||
type Feedbacks = { | ||
Tutor: TextFeedback[]; | ||
LLM: TextFeedback[]; | ||
Coffee: TextFeedback[]; | ||
}; | ||
|
||
const feedbacks: Feedbacks = { | ||
Tutor: [ | ||
{ | ||
id: 37715264, | ||
title: undefined, | ||
description: "Instead of stating what comprises a team and a group, please provide differences between the two, and explain these differences by means of two examples", | ||
credits: 0.0, | ||
type: "text", | ||
exercise_id: 0, | ||
submission_id: 1, | ||
meta: {} | ||
}, | ||
{ | ||
id: 37715265, | ||
title: undefined, | ||
description: "Your answer is quite short, please elaborate more in the future, also use examples to illustrate your point", | ||
credits: 0.0, | ||
type: "text", | ||
exercise_id: 0, | ||
submission_id: 1, | ||
meta: {} | ||
} | ||
], | ||
LLM: [ | ||
{ | ||
id: 1722786968303000, | ||
title: undefined, | ||
description: "Good explanation of a difference between groups and teams. You clearly stated that groups are loosely coupled, while teams work towards the same goal.", | ||
credits: 1.0, | ||
type: "text", | ||
exercise_id: 0, | ||
submission_id: 1, | ||
meta: {} | ||
}, | ||
{ | ||
id: 1722786968303001, | ||
title: undefined, | ||
description: "You did not provide any examples to illustrate the differences between groups and teams. Including examples would strengthen your explanation.", | ||
credits: 0.0, | ||
type: "text", | ||
exercise_id: 0, | ||
submission_id: 1, | ||
meta: {} | ||
} | ||
], | ||
Coffee: [ | ||
// Add Coffee feedbacks here if available | ||
] | ||
}; | ||
|
||
const LikertScaleForm: React.FC = () => { | ||
return ( | ||
<div className="overflow-x-auto"> | ||
<div className="flex min-w-[480px] space-x-6"> | ||
{Object.entries(feedbacks).map(([feedbackType, feedbackList]) => ( | ||
<div key={feedbackType} className="flex-1 min-w-[480px] flex flex-col"> | ||
{/* Render TextSubmissionDetail */} | ||
<div className="flex-grow flex flex-col mb-6"> | ||
<TextSubmissionDetail | ||
identifier={`id-${submission.id}`} | ||
key={submission.id} | ||
submission={submission} | ||
feedbacks={feedbackList} | ||
onFeedbacksChange={undefined} | ||
hideFeedbackDetails={true} | ||
/> | ||
</div> | ||
|
||
{/* Render SingleChoiceLikertScale components */} | ||
<div className="flex flex-col mt-auto"> | ||
{metrics.map((metric, index) => ( | ||
<div key={index} className="mb-4"> | ||
<SingleChoiceLikertScale | ||
title={metric.title} | ||
summary={metric.summary} | ||
description={metric.description} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default LikertScaleForm; |
52 changes: 52 additions & 0 deletions
52
playground/src/components/expert_evaluation/expert_view/side_by_side_header.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React from 'react'; | ||
|
||
function SideBySideHeader() { | ||
return ( | ||
<div className={"mb-12"}> | ||
{/* Title and Submission Info Section */} | ||
<div className="flex flex-col md:flex-row items-start md:items-center justify-between mb-4 space-y-2 md:space-y-0"> | ||
<h1 className="text-3xl font-semibold text-gray-900">Side by Side Evaluation</h1> | ||
<span className="text-lg text-gray-700"> | ||
Submission <strong>15</strong> / 105 | ||
</span> | ||
</div> | ||
|
||
{/* Subtitle and Details Buttons Section */} | ||
<div className="flex flex-col md:flex-row justify-between items-end gap-4"> | ||
<div className="flex flex-col gap-2 w-full md:w-auto"> | ||
<span className="text-lg text-gray-800"> | ||
Exercise L13E02 Strategy vs. Bridge (id=642) | ||
</span> | ||
<div className="flex flex-col md:flex-row gap-2 w-full"> | ||
<button className="w-full md:w-auto px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 transition"> | ||
📄 Exercise Details | ||
</button> | ||
<button className="w-full md:w-auto px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 transition"> | ||
📊 Metric Details | ||
</button> | ||
<button className="w-full md:w-auto px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 transition"> | ||
📚 Evaluation Tutorial | ||
</button> | ||
</div> | ||
</div> | ||
|
||
{/* Navigation Buttons Section */} | ||
<div className="flex flex-col items-end gap-2 mt-4 md:mt-0 w-full md:w-[250px]"> | ||
<button className="px-4 py-2 bg-gray-300 text-gray-700 rounded-md hover:bg-gray-400 transition w-full"> | ||
😴 Continue Later | ||
</button> | ||
<div className="flex gap-2 w-full"> | ||
<button className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition min-w-[120px] md:w-auto"> | ||
⬅️ Previous | ||
</button> | ||
<button className="px-4 py-2 bg-blue-500 text-white rounded-md hover:bg-blue-600 transition min-w-[120px] md:w-auto"> | ||
Next ➡️ | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
export default SideBySideHeader; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import React from 'react'; | ||
import { useRouter } from 'next/router'; | ||
|
||
function ExpertEvaluation() { | ||
const router = useRouter(); | ||
|
||
const handleGoToExpertView = () => { | ||
router.push('/expert_view'); | ||
}; | ||
|
||
return ( | ||
<div className="bg-white rounded-md p-4 mb-8 space-y-2"> | ||
<h3 className="text-2xl font-bold">Define Experiment</h3> | ||
<button | ||
onClick={handleGoToExpertView} | ||
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition" | ||
> | ||
Go to expert view | ||
</button> | ||
</div> | ||
); | ||
} | ||
|
||
export default ExpertEvaluation; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import SideBySideHeader from '@/components/expert_evaluation/expert_view/side_by_side_header'; | ||
import React from 'react'; | ||
import LikertScaleForm from "@/components/expert_evaluation/expert_view/likert_scale_form"; | ||
|
||
function SideBySideExpertView() { | ||
return ( | ||
<div className={"bg-white p-6"}> | ||
<SideBySideHeader /> | ||
<LikertScaleForm /> | ||
</div> | ||
); | ||
} | ||
|
||
export default SideBySideExpertView; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters