diff --git a/app/educator/dashboard/page.tsx b/app/educator/dashboard/page.tsx index 721cfa0..c0f8eb0 100644 --- a/app/educator/dashboard/page.tsx +++ b/app/educator/dashboard/page.tsx @@ -9,28 +9,79 @@ import { usePathname } from "next/navigation"; export default function InstructorDashboard() { const pathname = usePathname(); + return (
- + {/* Header */} +
+
+ {/* Logo and User Info Row (mobile) / Logo (desktop) */} +
+ Logo + + {/* Mobile: Show avatar and bell in header row */} +
+ + + + IN + +
+
+ + {/* Search Bar */} +
+ + +
+ + {/* Desktop: Avatar and Bell */} +
+ + + + IN + +
+
+
{/* Main */} -
+
{/* Greeting Card */} - - + + IN -

Hello Mr. Burns!

+

+ Hello Mr. Burns! +

{/* Tabs */} -
+
+
); -} +} \ No newline at end of file diff --git a/app/educator/students/StudentDetailsDialog.tsx b/app/educator/students/StudentDetailsDialog.tsx index 2ee5fb0..50bde80 100644 --- a/app/educator/students/StudentDetailsDialog.tsx +++ b/app/educator/students/StudentDetailsDialog.tsx @@ -35,11 +35,14 @@ interface StudentDetails { correct: number; wrong: number; completed_at: string | null; - performance_by_subject: Record; - }>; + performance_by_subject: Record< + string, + { + correct: number; + total: number; + topics: Record; + } + >; } | null; } @@ -137,87 +140,119 @@ export default function StudentDetailsDialog({ return ( - {student ? `${student.first_name} ${student.last_name}` : "Student Details"} + + {student + ? `${student.first_name} ${student.last_name}` + : "Student Details"} + + {/* Header */} -
+
-

+

{student ? `${student.first_name} ${student.last_name}` : ""}

{details && ( -

- Last Active: {details.lastActive || "No recent activity"} | Total - Lessons: {details.totalLessons} +

+ + Last Active: {details.lastActive || "No recent activity"} + + | + + Total Lessons: {details.totalLessons} +

)}
-
+
{loading ? ( -
+
Loading student details…
) : details ? ( <> {/* Diagnostic Results */} {details.diagnosticResults && ( - -

+ +

Diagnostic Results

-
-
+
+
-
Score
-
+
+ Score +
+
{details.diagnosticResults.score}%
-
Correct
-
+
+ Correct +
+
{details.diagnosticResults.correct}
-
Wrong
-
+
+ Wrong +
+
{details.diagnosticResults.wrong}
-
- Total Questions: {details.diagnosticResults.total_questions} +
+ + Total Questions:{" "} + {details.diagnosticResults.total_questions} + {details.diagnosticResults.completed_at && ( - - Completed: {new Date(details.diagnosticResults.completed_at).toLocaleDateString()} + + Completed:{" "} + {new Date( + details.diagnosticResults.completed_at + ).toLocaleDateString()} )}
{/* Performance by Subject */} - {Object.keys(details.diagnosticResults.performance_by_subject || {}).length > 0 && ( -
-

+ {Object.keys( + details.diagnosticResults.performance_by_subject || {} + ).length > 0 && ( +
+

Performance by Subject

-
- {Object.entries(details.diagnosticResults.performance_by_subject).map(([subject, data]: [string, any]) => { - const accuracy = data.total > 0 ? Math.round((data.correct / data.total) * 100) : 0; +
+ {Object.entries( + details.diagnosticResults.performance_by_subject + ).map(([subject, data]: [string, any]) => { + const accuracy = + data.total > 0 + ? Math.round((data.correct / data.total) * 100) + : 0; return ( -
+
{subject} {data.correct}/{data.total} ({accuracy}%) @@ -233,27 +268,29 @@ export default function StudentDetailsDialog({ )} {/* Strengths & Weaknesses */} -
+
{/* Strengths */} - -

+ +

Top Strengths

{details.strengths.length === 0 ? ( -

+

No strengths recorded

) : ( -
+
{details.strengths.map((s, i) => (
-
{s.skill}
-
+
+ {s.skill} +
+
{s.description}
{i < details.strengths.length - 1 && ( -
+
)}
))} @@ -262,25 +299,27 @@ export default function StudentDetailsDialog({ {/* Weaknesses */} - -

+ +

Top Weaknesses

{details.weaknesses.length === 0 ? ( -

+

No weaknesses recorded

) : ( -
+
{details.weaknesses.map((w, i) => (
-
{w.skill}
-
+
+ {w.skill} +
+
{w.description}
{i < details.weaknesses.length - 1 && ( -
+
)}
))} @@ -291,32 +330,97 @@ export default function StudentDetailsDialog({ {/* Lesson Tracker */} - -

+ +

Lesson Tracker

-
- {resultsLoading ? ( -
Loading results…
+ {/* Filters */} +
+ + + +
+ + {/* Mobile: Card-based layout */} +
+ {details.lessonHistory.length === 0 ? ( +

+ No lessons yet +

) : ( - - + details.lessonHistory.map((lesson, index) => ( +
+
+ + {lesson.assignment} + + + {lesson.lastAttempt} + +
+

+ {lesson.feedback} +

+
+ )) + )} + + + {/* Desktop: Table layout */} +
+
+ + + + Assignment + + + Last Attempt + + + Feedback + + + + + {details.lessonHistory.length === 0 ? ( - Quiz - Questions - Completed - Feedback + + No lessons yet + - - - {quizResults.length === 0 ? ( - - - No quiz results yet + ) : ( + details.lessonHistory.map((lesson, index) => ( + + + {lesson.assignment} + + + {lesson.lastAttempt} + + + {lesson.feedback} ) : ( diff --git a/app/educator/students/page.tsx b/app/educator/students/page.tsx index 1f4f014..9924bf5 100644 --- a/app/educator/students/page.tsx +++ b/app/educator/students/page.tsx @@ -174,18 +174,49 @@ export default function StudentRoster() { }); if (loading) { + // Displays Loading... state while waiting for data return
Loading...
; } return (
- + {/* Header */} +
+
+

+ +

+ +
+ + +
+ +
+
+ + + + +
+
+
+
-
+ {/* Main content area */} +
+ {/* Tabs */}
- - - My Students + {/* Students table */} + + + My Students -
-
+ {/* Filter buttons */} +
+
- +
- + Student - + Progress - + Engagement - + Status @@ -300,32 +333,33 @@ export default function StudentRoster() { className="cursor-pointer hover:bg-gray-100 transition-colors" > -
- +
+ - + {student.first_name?.[0] || ""}{student.last_name?.[0] || ""} - + {student.first_name} {student.last_name}
-
+
- + {student.progress}%
- + {/* Engagement - hidden on mobile */} + {student.progress >= 80 ? "more than 10 hours" : student.progress >= 60 @@ -337,7 +371,7 @@ export default function StudentRoster() { -
-

- Showing {filteredStudents.length} of {students.length}{" "} + {/* Pagination */} +

+

+ Showing {filteredStudents.length} of {filteredStudents.length}{" "} students

diff --git a/app/loadingSpinner.tsx b/app/loadingSpinner.tsx new file mode 100644 index 0000000..9394a09 --- /dev/null +++ b/app/loadingSpinner.tsx @@ -0,0 +1,12 @@ +interface LoadingSpinnerProps { + message?: string; +} + +export default function LoadingSpinner({ message = "Loading..." }: LoadingSpinnerProps) { + return ( +
+
+

{message}

+
+ ); +} \ No newline at end of file diff --git a/app/student/diagnostic/page.tsx b/app/student/diagnostic/page.tsx index c298a94..12ed299 100644 --- a/app/student/diagnostic/page.tsx +++ b/app/student/diagnostic/page.tsx @@ -301,11 +301,11 @@ export default function QuizzesPage() { if (!passage) return null; return ( -
-

+

+

Reading Passage:

-

{passage}

+

{passage}

); }; @@ -318,7 +318,7 @@ export default function QuizzesPage() { const details = currentQuestion.question_details; return ( -
+
{/* Reading Passage */} {renderPassage( (details as FreeResponseDetails | MCQDetails | DragDropDetails) @@ -326,27 +326,27 @@ export default function QuizzesPage() { )} {/* Question Box */} -
+
-

+

{currentQuestion.subject} - {currentQuestion.topic}

{currentQuestion.question_type === "free_response" && ( <> -

+

{(details as FreeResponseDetails).question}

)} {currentQuestion.question_type === "mcq" && ( <> -

+

{(details as MCQDetails).question}

)} {currentQuestion.question_type === "drag_drop" && ( -

+

Match each item with the correct answer from the dropdowns.

)} @@ -354,23 +354,23 @@ export default function QuizzesPage() {
{/* Answer Options */} -
+
{currentQuestion.question_type === "free_response" && (