source: frontend/web3-eDnevnik_Frontend/src/pages/KlasenRakovoditel_Pages/Klasen_ViewOcenkiZaUcenik/Klasen_ViewOcenkiZaUcenik.jsx

Last change on this file was 81cdf2d, checked in by Nikola Janev <nikolajanev57@…>, 10 days ago

initial commit

  • Property mode set to 100644
File size: 7.7 KB
Line 
1import React, { useState, useEffect } from "react";
2import axios from "axios";
3import { useParams, useNavigate } from "react-router-dom";
4import styles from "./Klasen_ViewOcenkiZaUcenikStyles.module.css";
5import NavbarKlasen from "../../../components/navbarKlasen/NavbarKlasen.jsx";
6
7const Klasen_ViewOcenkiZaUcenik = () => {
8 const { studentId } = useParams();
9 const navigate = useNavigate();
10 const [data, setData] = useState(null);
11 const [loading, setLoading] = useState(true);
12 const [teachersMap, setTeachersMap] = useState({});
13
14 useEffect(() => {
15 const fetchFullData = async () => {
16 try {
17 setLoading(true);
18 const response = await axios.get(
19 `http://localhost:8080/api/users/ucenici/${studentId}/ocenki`,
20 { withCredentials: true }
21 );
22
23 const gradesData = response.data;
24
25 if (!gradesData || !gradesData.predmeti) {
26 setData(gradesData);
27 setLoading(false);
28 return;
29 }
30
31 setData(gradesData);
32
33 const teacherIds = new Set();
34
35 gradesData.predmeti.forEach((predmet) => {
36 (predmet.usniOcenki || []).forEach((o) =>
37 teacherIds.add(o.vnesena_Od)
38 );
39 (predmet.pismeniOcenki || []).forEach((o) =>
40 teacherIds.add(o.vnesena_Od)
41 );
42 (predmet.krajniOcenki || []).forEach((o) =>
43 teacherIds.add(o.vnesena_Od)
44 );
45 });
46
47 const teacherMap = {};
48 await Promise.all(
49 Array.from(teacherIds).map(async (tId) => {
50 if (!tId) return;
51 try {
52 const tRes = await axios.get(
53 `http://localhost:8080/api/users/nastavnici/${tId}`,
54 { withCredentials: true }
55 );
56 teacherMap[tId] = `${tRes.data.ime} ${tRes.data.prezime}`;
57 } catch (e) {
58 console.warn(`Наставникот со ID ${tId} не е најден.`);
59 teacherMap[tId] = "Непознат наставник";
60 }
61 })
62 );
63
64 setTeachersMap(teacherMap);
65 } catch (err) {
66 console.error("Грешка при вчитување на податоците:", err);
67 } finally {
68 setLoading(false);
69 }
70 };
71
72 if (studentId) fetchFullData();
73 }, [studentId]);
74
75 if (loading) return <div className={styles.loader}>Вчитување...</div>;
76 if (!data)
77 return <div className={styles.error}>Нема податоци за овој ученик.</div>;
78
79 const handleVnesiUsnaOcenka = () => {
80 navigate("insertUsnaOcenka");
81 };
82
83 return (
84 <div className={styles.pageWrapper}>
85 <NavbarKlasen />
86
87 <div className={styles.mainContainer}>
88 <div className={styles.contentHeader}>
89 <h1>
90 Оценки за {data.ime} {data.prezime}
91 </h1>
92 </div>
93
94 {data.predmeti.map((predmet) => (
95 <div key={predmet.predmetId} className={styles.subjectSection}>
96 <h2 className={styles.subjectTitle}>
97 Предмет: {predmet.predmetIme}
98 </h2>
99
100 <div className={styles.gradeBox}>
101 <h3 className={styles.boxTitle}>Усни оценки</h3>
102 <table className={styles.gradeTable}>
103 <thead>
104 <tr>
105 <th>Оценка</th>
106 <th>датум</th>
107 <th>Забелешка</th>
108 <th>Тема</th>
109 <th>Освоени поени/Мах поени</th>
110 <th>вид</th>
111 <th>Внесена од</th>
112 </tr>
113 </thead>
114 <tbody>
115 {predmet.usniOcenki.length > 0 ? (
116 predmet.usniOcenki.map((o) => (
117 <tr key={o.id}>
118 <td className={styles.gradeNum}>{o.ocenka}</td>
119 <td>{o.datum}</td>
120 <td>{o.zabeleska}</td>
121 <td>{o.tema}</td>
122 <td>
123 {o.osvoeni_poeni}/{o.max_poeni}
124 </td>
125 <td>{o.vid_isprasuvanje}</td>
126 <td className={styles.teacherName}>
127 {teachersMap[o.vnesena_Od]}
128 </td>
129 </tr>
130 ))
131 ) : (
132 <tr>
133 <td colSpan="7" className={styles.noGrades}>
134 Нема усни оценки
135 </td>
136 </tr>
137 )}
138 </tbody>
139 </table>
140 </div>
141
142 <div className={styles.gradeBox}>
143 <h3 className={styles.boxTitle}>Писмени оценки</h3>
144 <table className={styles.gradeTable}>
145 <thead>
146 <tr>
147 <th>Оценка</th>
148 <th>датум</th>
149 <th>Забелешка</th>
150 <th>Тема</th>
151 <th>Освоени поени/Мах поени</th>
152 <th>вид</th>
153 <th>Внесена од</th>
154 </tr>
155 </thead>
156 <tbody>
157 {predmet.pismeniOcenki.length > 0 ? (
158 predmet.pismeniOcenki.map((o) => (
159 <tr key={o.id}>
160 <td className={styles.gradeNum}>{o.ocenka}</td>
161 <td>{o.datum}</td>
162 <td>{o.zabeleska}</td>
163 <td>{o.tema}</td>
164 <td>
165 {o.osvoeni_poeni}/{o.max_poeni}
166 </td>
167 <td>{o.vid}</td>
168 <td className={styles.teacherName}>
169 {teachersMap[o.vnesena_Od]}
170 </td>
171 </tr>
172 ))
173 ) : (
174 <tr>
175 <td colSpan="7" className={styles.noGrades}>
176 Нема писмени оценки
177 </td>
178 </tr>
179 )}
180 </tbody>
181 </table>
182 </div>
183
184 <div className={styles.gradeBox}>
185 <h3 className={styles.boxTitle}>Крајни Оценки</h3>
186 <table className={styles.gradeTable}>
187 <thead>
188 <tr>
189 <th>Оценка</th>
190 <th>датум</th>
191 <th>Забелешка</th>
192 <th>вид</th>
193 <th>Внесена од</th>
194 </tr>
195 </thead>
196 <tbody>
197 {predmet.krajniOcenki.length > 0 ? (
198 predmet.krajniOcenki.map((o) => (
199 <tr key={o.id}>
200 <td className={styles.gradeNumBold}>{o.ocenka}</td>
201 <td>{o.datum}</td>
202 <td>{o.zabeleska}</td>
203 <td>{o.tip}</td>
204 <td className={styles.teacherName}>
205 {teachersMap[o.vnesena_Od]}
206 </td>
207 </tr>
208 ))
209 ) : (
210 <tr>
211 <td colSpan="5" className={styles.noGrades}>
212 Нема крајни оценки
213 </td>
214 </tr>
215 )}
216 </tbody>
217 </table>
218 </div>
219 </div>
220 ))}
221 </div>
222 </div>
223 );
224};
225
226export default Klasen_ViewOcenkiZaUcenik;
Note: See TracBrowser for help on using the repository browser.