source: frontend/web3-eDnevnik_Frontend/src/pages/RoditelPages/Roditel_ViewOcenki/Roditel_ViewOcenki.jsx

Last change on this file was 81cdf2d, checked in by Nikola Janev <nikolajanev57@…>, 9 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 "./Roditel_ViewOcenkiStyles.module.css";
5import NavbarRoditel from "../../../components/NavbarRoditel/NavbarRoditel.jsx";
6
7const Roditel_ViewOcenki = () => {
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 <NavbarRoditel />
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
101 <div className={styles.gradeBox}>
102 <h3 className={styles.boxTitle}>Усни оценки</h3>
103 <table className={styles.gradeTable}>
104 <thead>
105 <tr>
106 <th>Оценка</th>
107 <th>датум</th>
108 <th>Забелешка</th>
109 <th>Тема</th>
110 <th>Освоени поени/Мах поени</th>
111 <th>вид</th>
112 <th>Внесена од</th>
113 </tr>
114 </thead>
115 <tbody>
116 {predmet.usniOcenki.length > 0 ? (
117 predmet.usniOcenki.map((o) => (
118 <tr key={o.id}>
119 <td className={styles.gradeNum}>{o.ocenka}</td>
120 <td>{o.datum}</td>
121 <td>{o.zabeleska}</td>
122 <td>{o.tema}</td>
123 <td>
124 {o.osvoeni_poeni}/{o.max_poeni}
125 </td>
126 <td>{o.vid_isprasuvanje}</td>
127 <td className={styles.teacherName}>
128 {teachersMap[o.vnesena_Od]}
129 </td>
130 </tr>
131 ))
132 ) : (
133 <tr>
134 <td colSpan="7" className={styles.noGrades}>
135 Нема усни оценки
136 </td>
137 </tr>
138 )}
139 </tbody>
140 </table>
141 </div>
142
143 <div className={styles.gradeBox}>
144 <h3 className={styles.boxTitle}>Писмени оценки</h3>
145 <table className={styles.gradeTable}>
146 <thead>
147 <tr>
148 <th>Оценка</th>
149 <th>датум</th>
150 <th>Забелешка</th>
151 <th>Тема</th>
152 <th>Освоени поени/Мах поени</th>
153 <th>вид</th>
154 <th>Внесена од</th>
155 </tr>
156 </thead>
157 <tbody>
158 {predmet.pismeniOcenki.length > 0 ? (
159 predmet.pismeniOcenki.map((o) => (
160 <tr key={o.id}>
161 <td className={styles.gradeNum}>{o.ocenka}</td>
162 <td>{o.datum}</td>
163 <td>{o.zabeleska}</td>
164 <td>{o.tema}</td>
165 <td>
166 {o.osvoeni_poeni}/{o.max_poeni}
167 </td>
168 <td>{o.vid}</td>
169 <td className={styles.teacherName}>
170 {teachersMap[o.vnesena_Od]}
171 </td>
172 </tr>
173 ))
174 ) : (
175 <tr>
176 <td colSpan="7" className={styles.noGrades}>
177 Нема писмени оценки
178 </td>
179 </tr>
180 )}
181 </tbody>
182 </table>
183 </div>
184
185 <div className={styles.gradeBox}>
186 <h3 className={styles.boxTitle}>Крајни Оценки</h3>
187 <table className={styles.gradeTable}>
188 <thead>
189 <tr>
190 <th>Оценка</th>
191 <th>датум</th>
192 <th>Забелешка</th>
193 <th>вид</th>
194 <th>Внесена од</th>
195 </tr>
196 </thead>
197 <tbody>
198 {predmet.krajniOcenki.length > 0 ? (
199 predmet.krajniOcenki.map((o) => (
200 <tr key={o.id}>
201 <td className={styles.gradeNumBold}>{o.ocenka}</td>
202 <td>{o.datum}</td>
203 <td>{o.zabeleska}</td>
204 <td>{o.tip}</td>
205 <td className={styles.teacherName}>
206 {teachersMap[o.vnesena_Od]}
207 </td>
208 </tr>
209 ))
210 ) : (
211 <tr>
212 <td colSpan="5" className={styles.noGrades}>
213 Нема крајни оценки
214 </td>
215 </tr>
216 )}
217 </tbody>
218 </table>
219 </div>
220 </div>
221 ))}
222 </div>
223 </div>
224 );
225};
226
227export default Roditel_ViewOcenki;
Note: See TracBrowser for help on using the repository browser.