Spaces:
Runtime error
Runtime error
| import React from 'react' | |
| import { Sliders } from 'lucide-react' | |
| export default function SidebarPanel({ | |
| totalQuestions, | |
| currentQuestionIndex, | |
| answers, | |
| markedForReview, | |
| onGoToQuestion, | |
| answeredCount, | |
| markedCount, | |
| contrast, | |
| onContrastChange | |
| }) { | |
| const getQuestionStatus = (idx) => { | |
| if (markedForReview.has(idx)) return 'marked' | |
| if (answers.hasOwnProperty(idx)) return 'answered' | |
| return 'not-answered' | |
| } | |
| const unansweredCount = totalQuestions - answeredCount | |
| return ( | |
| <div className="sidebar-panel"> | |
| {/* Summary Stats */} | |
| <div className="mb-6"> | |
| <h3 className="text-sm font-semibold text-gray-700 mb-3 uppercase">Exam Status</h3> | |
| <div className="space-y-2 text-sm"> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-600">Answered:</span> | |
| <span className="font-semibold text-green-600">{answeredCount}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-600">Not Answered:</span> | |
| <span className="font-semibold text-red-600">{unansweredCount}</span> | |
| </div> | |
| <div className="flex justify-between"> | |
| <span className="text-gray-600">Marked:</span> | |
| <span className="font-semibold text-amber-600">{markedCount}</span> | |
| </div> | |
| </div> | |
| <div className="mt-3 pt-3 border-t border-gray-200"> | |
| <div className="w-full bg-gray-200 rounded-full h-2"> | |
| <div | |
| className="bg-green-500 h-2 rounded-full transition-all" | |
| style={{ width: `${(answeredCount / totalQuestions) * 100}%` }} | |
| /> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Image Settings */} | |
| <div className="settings-panel"> | |
| <h3 className="settings-title flex items-center gap-2"> | |
| <Sliders className="w-4 h-4" /> | |
| Image Contrast | |
| </h3> | |
| <div className="setting-item"> | |
| <div className="setting-label">Adjust image clarity</div> | |
| <input | |
| type="range" | |
| min="50" | |
| max="150" | |
| value={contrast} | |
| onChange={(e) => onContrastChange(Number(e.target.value))} | |
| className="contrast-slider w-full" | |
| /> | |
| <div className="text-xs text-gray-500 mt-1">{contrast}%</div> | |
| </div> | |
| </div> | |
| {/* Question Review */} | |
| <div className="mt-4"> | |
| <h3 className="settings-title">Question Review</h3> | |
| <div className="question-review"> | |
| {Array.from({ length: totalQuestions }).map((_, idx) => { | |
| const status = getQuestionStatus(idx) | |
| return ( | |
| <button | |
| key={idx} | |
| onClick={() => onGoToQuestion(idx)} | |
| className={`review-item w-full text-left ${ | |
| idx === currentQuestionIndex ? 'bg-blue-50 font-semibold' : '' | |
| }`} | |
| > | |
| <span | |
| className={`status-indicator ${ | |
| status === 'answered' | |
| ? 'answered' | |
| : status === 'marked' | |
| ? 'marked' | |
| : 'not-answered' | |
| }`} | |
| /> | |
| Q{idx + 1} | |
| <span className="text-xs ml-1"> | |
| {status === 'answered' && '✓'} | |
| {status === 'marked' && '⚑'} | |
| </span> | |
| </button> | |
| ) | |
| })} | |
| </div> | |
| </div> | |
| {/* Help Text */} | |
| <div className="mt-6 pt-4 border-t border-gray-200 text-xs text-gray-600"> | |
| <p className="mb-2"> | |
| <span className="inline-block w-3 h-3 rounded-full bg-green-500 mr-2"></span> | |
| Answered | |
| </p> | |
| <p className="mb-2"> | |
| <span className="inline-block w-3 h-3 rounded-full bg-red-500 mr-2"></span> | |
| Not Answered | |
| </p> | |
| <p> | |
| <span className="inline-block w-3 h-3 rounded-full bg-amber-500 mr-2"></span> | |
| Marked | |
| </p> | |
| </div> | |
| </div> | |
| ) | |
| } | |