1+ "use client" ;
2+ import { useState } from "react" ;
3+ import { Button } from "@/components/ui/button" ;
4+ import {
5+ Dialog ,
6+ DialogContent ,
7+ DialogHeader ,
8+ DialogTitle ,
9+ DialogTrigger ,
10+ DialogFooter ,
11+ DialogClose ,
12+ } from "@/components/ui/dialog" ;
13+ import {
14+ Table ,
15+ TableBody ,
16+ TableCell ,
17+ TableHead ,
18+ TableHeader ,
19+ TableRow ,
20+ } from "@/components/ui/table" ;
21+ import { Badge } from "@/components/ui/badge" ;
22+
23+ type Request = {
24+ id : string ;
25+ studentId : string ;
26+ courseCode : string ;
27+ originalDay : string ;
28+ originalTime : string ;
29+ requestedSlots : { day : string ; time : string } [ ] ;
30+ status : "Pending" | "Approved" | "Rejected" ;
31+ reason : string ;
32+ } ;
33+
34+ const initialMockRequests : Request [ ] = [
35+ {
36+ id : "REQ001" ,
37+ studentId : "S001" ,
38+ courseCode : "CO221" ,
39+ originalDay : "Monday" ,
40+ originalTime : "08:00" ,
41+ requestedSlots : [
42+ { day : "Wednesday" , time : "10:00" } ,
43+ { day : "Friday" , time : "14:00" } ,
44+ ] ,
45+ status : "Pending" ,
46+ reason : "Medical appointment" ,
47+ } ,
48+ {
49+ id : "REQ002" ,
50+ studentId : "S002" ,
51+ courseCode : "CO222" ,
52+ originalDay : "Tuesday" ,
53+ originalTime : "10:00" ,
54+ requestedSlots : [ { day : "Thursday" , time : "13:00" } ] ,
55+ status : "Pending" ,
56+ reason : "Family event" ,
57+ } ,
58+ {
59+ id : "REQ003" ,
60+ studentId : "S001" ,
61+ courseCode : "CO223" ,
62+ originalDay : "Friday" ,
63+ originalTime : "13:00" ,
64+ requestedSlots : [ { day : "Monday" , time : "15:00" } ] ,
65+ status : "Approved" ,
66+ reason : "Approved" ,
67+ } ,
68+ {
69+ id : "REQ004" ,
70+ studentId : "S003" ,
71+ courseCode : "CO224" ,
72+ originalDay : "Wednesday" ,
73+ originalTime : "11:00" ,
74+ requestedSlots : [ { day : "Friday" , time : "09:00" } ] ,
75+ status : "Rejected" ,
76+ reason : "Invalid reason" ,
77+ } ,
78+ ] ;
79+
80+ export function ClashReports ( ) {
81+ const [ requests , setRequests ] = useState < Request [ ] > ( initialMockRequests ) ;
82+ const [ selectedRequest , setSelectedRequest ] = useState < Request | null > ( null ) ;
83+
84+ const handleStatusChange = ( requestId : string , status : "Approved" | "Rejected" ) => {
85+ setRequests ( prevRequests =>
86+ prevRequests . map ( req =>
87+ req . id === requestId ? { ...req , status } : req
88+ )
89+ ) ;
90+ } ;
91+
92+ const newReports = requests . filter ( req => req . status === "Pending" ) ;
93+ const viewedReports = requests . filter ( req => req . status !== "Pending" ) ;
94+
95+ const renderTable = ( title : string , reports : Request [ ] ) => (
96+ < div className = "mt-8" >
97+ < h2 className = "text-2xl font-bold mb-4" > { title } </ h2 >
98+ < Table >
99+ < TableHeader >
100+ < TableRow >
101+ < TableHead > Request ID</ TableHead >
102+ < TableHead > Student ID</ TableHead >
103+ < TableHead > Course Code</ TableHead >
104+ < TableHead > Status</ TableHead >
105+ < TableHead > Action</ TableHead >
106+ </ TableRow >
107+ </ TableHeader >
108+ < TableBody >
109+ { reports . map ( ( request ) => (
110+ < TableRow key = { request . id } >
111+ < TableCell > { request . id } </ TableCell >
112+ < TableCell > { request . studentId } </ TableCell >
113+ < TableCell > { request . courseCode } </ TableCell >
114+ < TableCell >
115+ < Badge
116+ variant = {
117+ request . status === "Approved"
118+ ? "default"
119+ : request . status === "Rejected"
120+ ? "destructive"
121+ : "outline"
122+ }
123+ >
124+ { request . status }
125+ </ Badge >
126+ </ TableCell >
127+ < TableCell >
128+ < Dialog onOpenChange = { ( isOpen ) => ! isOpen && setSelectedRequest ( null ) } >
129+ < DialogTrigger asChild >
130+ < Button
131+ variant = "outline"
132+ onClick = { ( ) => setSelectedRequest ( request ) }
133+ >
134+ View
135+ </ Button >
136+ </ DialogTrigger >
137+ { selectedRequest && selectedRequest . id === request . id && (
138+ < DialogContent >
139+ < DialogHeader >
140+ < DialogTitle > Request Details</ DialogTitle >
141+ </ DialogHeader >
142+ < div >
143+ < p > < strong > Request ID:</ strong > { selectedRequest . id } </ p >
144+ < p > < strong > Student ID:</ strong > { selectedRequest . studentId } </ p >
145+ < p > < strong > Course Code:</ strong > { selectedRequest . courseCode } </ p >
146+ < p > < strong > Original Slot:</ strong > { selectedRequest . originalDay } , { selectedRequest . originalTime } </ p >
147+ < p > < strong > Status:</ strong > { selectedRequest . status } </ p >
148+ < p > < strong > Reason:</ strong > { selectedRequest . reason } </ p >
149+ < h4 className = "font-semibold mt-4" > Requested Slots:</ h4 >
150+ < ul >
151+ { selectedRequest . requestedSlots . map ( ( slot , index ) => (
152+ < li key = { index } >
153+ { slot . day } , { slot . time }
154+ </ li >
155+ ) ) }
156+ </ ul >
157+ </ div >
158+ { selectedRequest . status === 'Pending' && (
159+ < DialogFooter className = "mt-4" >
160+ < DialogClose asChild >
161+ < Button variant = "outline" > Cancel</ Button >
162+ </ DialogClose >
163+ < DialogClose asChild >
164+ < Button onClick = { ( ) => handleStatusChange ( selectedRequest . id , 'Approved' ) } > Approve</ Button >
165+ </ DialogClose >
166+ < DialogClose asChild >
167+ < Button variant = "destructive" onClick = { ( ) => handleStatusChange ( selectedRequest . id , 'Rejected' ) } > Reject</ Button >
168+ </ DialogClose >
169+ </ DialogFooter >
170+ ) }
171+ </ DialogContent >
172+ ) }
173+ </ Dialog >
174+ </ TableCell >
175+ </ TableRow >
176+ ) ) }
177+ </ TableBody >
178+ </ Table >
179+ </ div >
180+ ) ;
181+
182+ return (
183+ < div className = "p-4" >
184+ < h1 className = "text-3xl font-bold mb-6" > Clash Reports</ h1 >
185+ { renderTable ( "New Clash Reports" , newReports ) }
186+ { renderTable ( "Viewed Clash Reports" , viewedReports ) }
187+ </ div >
188+ ) ;
189+ }
0 commit comments