source: frontend/web3-eDnevnik_Frontend/src/pages/PredmetenNastavnikPages/PredmetenNastavnik_CreateUsnaOcenka/PredmetenNastavnik_CreateUsnaOcenka.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: 12.6 KB
Line 
1import { useState, useEffect } from "react";
2import { useParams, Link, useNavigate } from "react-router-dom";
3import NavbarKlasen from "../../../components/navbarKlasen/NavbarKlasen";
4
5import axios from "axios";
6
7const PredmetenNastavnik_CreateUsnaOcenka = () => {
8 const navigate = useNavigate();
9 const { studentId } = useParams();
10 const [error, setError] = useState("");
11 const [loading, setLoading] = useState(true);
12 const [teacherId, setTeacherId] = useState("");
13 const { classId } = useParams();
14 const [studentInfo, setStudentInfo] = useState("");
15 const [predmeti, setPredmeti] = useState([]);
16 const [aktivnosti, setAktivnosti] = useState([]);
17 const [selectedAktivnostId, setSelectedAktivnostId] = useState("");
18 const [nedelenPlan, setNedelenPlan] = useState([]);
19 const [formData, setFormData] = useState({
20 ocenka: "",
21 datum: "",
22 zabeleska: "",
23 vnesena_Od: teacherId,
24 dobienaZaUcenikot_Id: studentId,
25 eZaPredmetot_Id: predmeti.id,
26 zaAktivnosta_id: "",
27 tema: "",
28 osvoeni_poeni: "",
29 max_poeni: "",
30 vidUsnoIsprasuvanje: "",
31 });
32
33 useEffect(() => {
34 const fetchInitialData = async () => {
35 try {
36 setLoading(true);
37
38 const [resMe, resStudent] = await Promise.all([
39 axios.get("http://localhost:8080/api/auth/me", {
40 withCredentials: true,
41 }),
42 axios.get(`http://localhost:8080/api/users/ucenici/${studentId}`, {
43 withCredentials: true,
44 }),
45 ]);
46
47 const tId = resMe.data.id;
48
49 setTeacherId(tId);
50 setStudentInfo(resStudent.data);
51 setFormData((prev) => ({
52 ...prev,
53 vnesena_Od: tId,
54 }));
55
56 const resPredmeti = await axios.get(
57 `http://localhost:8080/api/klas/${classId}/predmeti`,
58 { withCredentials: true }
59 );
60
61 setPredmeti(resPredmeti.data);
62 const resNedelenPlan = await axios.get(
63 `http://localhost:8080/api/klas/${classId}/nedelenPlan`,
64 { withCredentials: true }
65 );
66
67 setNedelenPlan(resNedelenPlan.data);
68 setAktivnosti(
69 Object.entries(resNedelenPlan.data.timetable).flatMap(
70 ([den, aktivnosti]) =>
71 aktivnosti.map((a) => ({
72 ...a,
73 den,
74 }))
75 )
76 );
77 console.log(resNedelenPlan.data);
78 } catch (err) {
79 console.error("Грешка при вчитување на податоците:", err);
80 setError(
81 "Неуспешно вчитување на податоците за наставникот кој е логиран."
82 );
83 } finally {
84 setLoading(false);
85 }
86 };
87 fetchInitialData();
88 }, []);
89
90 const handleSubmit = async (e) => {
91 e.preventDefault();
92 setError("");
93
94 try {
95 const response = await axios.post(
96 `http://localhost:8080/api/users/ucenici/${studentId}/enterUsnaOcenka`,
97 formData,
98 {
99 withCredentials: true,
100 headers: { "Content-Type": "application/json" },
101 }
102 );
103
104 if (response.status === 200 || response.status === 201) {
105 alert("Успешно е креирана усна оценка за ученикот ");
106 navigate(
107 `/predmetenNastavnikDashboard/klas/${classId}/student/${studentId}/grades`
108 );
109 }
110 } catch (err) {
111 console.error("Грешка при POST:", err.response?.data);
112 const serverMsg = err.response?.data?.message || "Полињата се грешка";
113 setError(serverMsg);
114 }
115 };
116
117 if (loading)
118 return (
119 <div style={{ padding: "50px", textAlign: "center" }}>
120 <NavbarKlasen />
121 <h2>Вчитување на податоците...</h2>
122 </div>
123 );
124 const handleChange = (e) => {
125 const { name, value } = e.target;
126
127 if (name === "predmetId") {
128 setFormData((prev) => ({
129 ...prev,
130 eZaPredmetot_Id: value,
131 }));
132 return;
133 }
134
135 if (name === "zaAktivnosta_id") {
136 const selectedAktivnost = aktivnosti.find((a) => a.id === value);
137 setSelectedAktivnostId(value);
138 setFormData((prev) => ({
139 ...prev,
140 zaAktivnosta_id: value,
141 tema: selectedAktivnost ? selectedAktivnost.naslov : "",
142 }));
143 return;
144 }
145
146 setFormData((prev) => ({
147 ...prev,
148 [name]: value,
149 }));
150 };
151 const vidoviIsprasuvanje = ["PREZENTACIJA_PROEKT", "TABLA"];
152
153 return (
154 <>
155 <NavbarKlasen />
156 <div className="container-fluid">
157 <nav className="navbar navbar-expand-lg bg-dark align-items-center">
158 <div className="container-fluid ">
159 <div className="navbar-nav mx-auto ">
160 <Link
161 className="nav-link text-white"
162 to="/predmetenNastavnikDashboard"
163 >
164 Соопштенија
165 </Link>
166
167 <Link
168 className="nav-link text-white"
169 to={`/predmetenNastavnikDashboard/${classId}/weeklyPlan`}
170 >
171 Види неделни активности
172 </Link>
173
174 <Link
175 className="nav-link text-white"
176 to={`/predmetenNastavnikDashboard/${classId}/raspored`}
177 >
178 Види распоред
179 </Link>
180
181 <Link
182 className="nav-link text-white"
183 to={`/predmetenNastavnikDashboard/${classId}/students`}
184 >
185 Студенти
186 </Link>
187 </div>
188 </div>
189 </nav>
190
191 <div className="w-75 m-3 bg-secondary mx-auto rounded">
192 <h1 className="text-center text-white">
193 Внеси усна оценка за {studentInfo.ime} {studentInfo.prezime}
194 </h1>
195 {console.log(`aktivnosti: ${aktivnosti}`)}
196
197 <form onSubmit={handleSubmit}>
198 <div className="row m-3 align-items-center">
199 <label
200 htmlFor="ocenka"
201 className="col-form-label col-3 m-3 text-center text-white"
202 >
203 Внеси оценка од 1 до 5
204 </label>
205 <div className="col-8">
206 <input
207 name="ocenka"
208 type="number"
209 required
210 className="form-control w-75 m-3 mx-auto"
211 placeholder="Оценката мора да биде од 1 до 5"
212 min="1"
213 max="5"
214 value={formData.ocenka}
215 onChange={handleChange}
216 />
217 </div>
218 </div>
219 <div className="row mb-3 align-items-center">
220 <label
221 htmlFor="datum"
222 className="col-form-label col-3 m-3 text-center text-white"
223 >
224 Внеси датум на внесување на оценката
225 </label>
226 <div className="col-8">
227 <input
228 name="datum"
229 type="date"
230 className="form-control w-75 m-3 mx-auto"
231 required
232 value={formData.datum}
233 onChange={handleChange}
234 />
235 </div>
236 </div>
237 <div className="row mb-3 align-items-center">
238 <label
239 htmlFor="zabeleska"
240 className="col-3 col-form-label m-3 text-white"
241 >
242 забелешка
243 </label>
244 <textarea
245 name="zabeleska"
246 value={formData.zabeleska}
247 required
248 placeholder="Внесете забелешка за оценката доколку ја имате"
249 onChange={handleChange}
250 className="form-control w-75 mx-auto"
251 style={{ minHeight: "200px", resize: "horizontal" }}
252 />
253 </div>
254 <div className="row mb-3 align-items-center">
255 <label className="form-label m-3 col-3 text-center text-white">
256 Избери Предмет
257 </label>
258 <div className="col-8">
259 <select
260 name="predmetId"
261 value={formData.eZaPredmetot_Id}
262 required
263 onChange={handleChange}
264 className="form-control w-75 mx-auto"
265 >
266 <option value="">-- Избери предмет --</option>
267 {predmeti.map((n) => (
268 <option key={n.id} value={n.id}>
269 {n.ime} {n.fond_casovi}
270 </option>
271 ))}
272 </select>
273 </div>
274 </div>
275
276 <div className="row mb-3 align-items-center">
277 <label className="form-label text-center p-3 col-3 text-white">
278 Избери активност?
279 </label>
280 <div className="col-9">
281 <select
282 name="zaAktivnosta_id"
283 value={formData.zaAktivnosta_id}
284 required
285 onChange={handleChange}
286 className="form-control w-75 m-3 mx-auto"
287 >
288 <option value="">-- Избери активност --</option>
289 {aktivnosti.map((n) => {
290 const predmet = predmeti.find((p) => p.id === n.predmetId);
291 return (
292 <option key={n.id} value={n.id}>
293 Активност: {n.naslov} - Ден: {n.den} - Предмет:{" "}
294 {predmet ? predmet.ime : "непознато име"}
295 </option>
296 );
297 })}
298 </select>
299 </div>
300 </div>
301 <div className="row align-items-center mb-3">
302 <label
303 htmlFor="osvoeni_poeni"
304 className="form-label col-3 p-3 text-center text-white"
305 >
306 Внеси освоени поени за ученикот од 1 до 100
307 </label>
308 <div className="col-9">
309 <input
310 name="osvoeni_poeni"
311 type="number"
312 required
313 className="form-control w-75 mx-auto"
314 min="1"
315 max="100"
316 value={formData.osvoeni_poeni}
317 onChange={handleChange}
318 />
319 </div>
320 </div>
321 <div className="row mb-3 align-items-center">
322 <label
323 htmlFor="max_poeni"
324 className="text-white col-3 p-3 text-center form-label"
325 >
326 Внеси максимум поени што може да се освојат од 1 до 100
327 </label>
328 <div className="col-9">
329 <input
330 name="max_poeni"
331 type="number"
332 required
333 className="form-control m-3 w-75 mx-auto"
334 min="1"
335 max="100"
336 value={formData.max_poeni}
337 onChange={handleChange}
338 />
339 </div>
340 </div>
341 <div className="row mb-3 align-items-center">
342 <label
343 htmlFor="vidUsnoIsprasuvanje"
344 className="form-label col-3 p-3 text-center text-white"
345 >
346 Избери вид на усно испрашување
347 </label>
348 <div className="col-9">
349 <select
350 name="vidUsnoIsprasuvanje"
351 value={formData.vidUsnoIsprasuvanje}
352 required
353 onChange={handleChange}
354 className="form-control m-3 w-75 mx-auto"
355 >
356 <option value="">-- Избери вид усно испрашување --</option>
357 {vidoviIsprasuvanje.map((n) => (
358 <option key={n} value={n}>
359 {n}
360 </option>
361 ))}
362 </select>
363 </div>
364 </div>
365 <div className="text-center">
366 <button className="btn btn-primary m-3 " type="submit">
367 Внеси усна оценка
368 </button>
369 <a className="btn btn-danger m-3">Откажи</a>
370 </div>
371 </form>
372 </div>
373 </div>
374 </>
375 );
376};
377
378export default PredmetenNastavnik_CreateUsnaOcenka;
Note: See TracBrowser for help on using the repository browser.