Skip to content

Commit bd22d37

Browse files
Feat/phase 2 core features (#848)
* feat: complete assignment submission system with database integration Assignment Submission Improvements: - Connected submission form to /api/lms/submissions endpoint - Added liveUrl field for deployed demo submissions - Replaced mock data with real database queries (Prisma) - Added server-side authentication and enrollment verification - Display assignment details from database (instructions, due date, max points) - Show required submission types (GitHub repo, live demo) - Enhanced error handling and user feedback Frontend Changes: - Added error state and display for submission failures - Updated form validation to support githubUrl, liveUrl, or file uploads - Dynamic breadcrumbs using actual course data - Improved UI to show assignment type and requirements - Better formatting for instructions and assignment details Backend Integration: - Uses getServerSideProps for server-side rendering - Verifies user authentication before page load - Confirms user enrollment in course before allowing submission - Fetches assignment with course relationship from database Security: - Server-side auth check prevents unauthorized access - Enrollment verification ensures only enrolled students can submit - Proper redirect to login with callback URL Note: File upload to Cloudinary pending - currently stores file metadata only * feat: add submission history view for students Submission History Features: - Created /submissions page to view all assignment submissions - Added GET endpoint to /api/lms/submissions with filtering - Filter submissions by status (all, pending, graded) - Display submission details: GitHub URL, live demo, notes - Show instructor feedback and grades when available - Display submission timestamps and due dates - Calculate and show percentage scores API Enhancements: - Extended /api/lms/submissions to handle GET requests - Support filtering by courseId or assignmentId - Include assignment and course details in response - Order submissions by most recent first UI Components: - Status badges (SUBMITTED, GRADED, RETURNED) - Clickable links to GitHub repos and live demos - Instructor feedback display with timestamp - Score display with percentage calculation - Empty states for no submissions - Filter buttons for quick navigation Dashboard Integration: - Added 'My Submissions' link to Quick Links sidebar - Students can easily access submission history from dashboard Student Benefits: - Track all assignment submissions in one place - View feedback and scores from instructors - Access submitted GitHub repos and live demos - See pending vs graded submissions at a glance * fix: remove unused session variable from submissions page TypeScript error fix - session variable was declared but never used
1 parent 399ce0f commit bd22d37

File tree

4 files changed

+558
-95
lines changed

4 files changed

+558
-95
lines changed

src/pages/api/lms/submissions/index.ts

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ import { requireAuth, AuthenticatedRequest } from '@/lib/rbac';
33
import prisma from '@/lib/prisma';
44

55
/**
6-
* POST /api/lms/submissions
6+
* GET /api/lms/submissions
7+
* Fetch user's submissions (optionally filtered by courseId or assignmentId)
8+
*
9+
* Query params:
10+
* - courseId?: string - Filter by course
11+
* - assignmentId?: string - Filter by specific assignment
712
*
13+
* POST /api/lms/submissions
814
* Submit an assignment. Students can create or update their submissions.
915
* Only one submission per user per assignment (enforced by unique constraint).
1016
*
@@ -16,21 +22,63 @@ import prisma from '@/lib/prisma';
1622
* notes?: string,
1723
* files?: string (JSON array of file URLs)
1824
* }
19-
*
20-
* Response:
21-
* {
22-
* submission: {...},
23-
* message: string
24-
* }
2525
*/
2626
export default requireAuth(async (req: AuthenticatedRequest, res: NextApiResponse) => {
27+
const userId = req.user!.id;
28+
29+
// GET - Fetch user's submissions
30+
if (req.method === 'GET') {
31+
try {
32+
const { courseId, assignmentId } = req.query;
33+
34+
const where: any = { userId };
35+
36+
if (assignmentId) {
37+
where.assignmentId = assignmentId as string;
38+
} else if (courseId) {
39+
where.assignment = {
40+
courseId: courseId as string,
41+
};
42+
}
43+
44+
const submissions = await prisma.submission.findMany({
45+
where,
46+
include: {
47+
assignment: {
48+
select: {
49+
id: true,
50+
title: true,
51+
description: true,
52+
dueDate: true,
53+
maxPoints: true,
54+
course: {
55+
select: {
56+
id: true,
57+
title: true,
58+
},
59+
},
60+
},
61+
},
62+
},
63+
orderBy: {
64+
submittedAt: 'desc',
65+
},
66+
});
67+
68+
return res.status(200).json({ submissions });
69+
} catch (error) {
70+
console.error('Error fetching submissions:', error);
71+
return res.status(500).json({ error: 'Failed to fetch submissions' });
72+
}
73+
}
74+
75+
// POST - Create/update submission
2776
if (req.method !== 'POST') {
2877
return res.status(405).json({ error: 'Method not allowed' });
2978
}
3079

3180
try {
3281
const { assignmentId, githubUrl, liveUrl, notes, files } = req.body;
33-
const userId = req.user!.id;
3482

3583
// Validate required fields
3684
if (!assignmentId) {

0 commit comments

Comments
 (0)