source: frontend/web3-eDnevnik_Frontend/src/pages/PredmetenNastavnikPages/PredmetenNastavnik_CreatePismenaOcenka/PredmetenNastavnik_CreatePismenaOcenka.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.7 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_CreatePismenaOcenka = () => {
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 vid: "",
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}/enterPismenaOcenka`,
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 = [
152 "PISMENA_RABOTA",
153 "TEST",
154 "RASKAZUVANJE_LEKTIRA",
155 "ESEJ",
156 ];
157
158 return (
159 <>
160 <NavbarKlasen />
161 <div className="container-fluid">
162 <nav className="navbar navbar-expand-lg bg-dark align-items-center">
163 <div className="container-fluid ">
164 <div className="navbar-nav mx-auto ">
165 <Link
166 className="nav-link text-white"
167 to="/predmetenNastavnikDashboard"
168 >
169 Соопштенија
170 </Link>
171
172 <Link
173 className="nav-link text-white"
174 to={`/predmetenNastavnikDashboard/${classId}/weeklyPlan`}
175 >
176 Види неделни активности
177 </Link>
178
179 <Link
180 className="nav-link text-white"
181 to={`/predmetenNastavnikDashboard/${classId}/raspored`}
182 >
183 Види распоред
184 </Link>
185
186 <Link
187 className="nav-link text-white"
188 to={`/predmetenNastavnikDashboard/${classId}/students`}
189 >
190 Студенти
191 </Link>
192 </div>
193 </div>
194 </nav>
195
196 <div className="w-75 m-3 bg-secondary mx-auto rounded">
197 <h1 className="text-center text-white">
198 Внеси писмена оценка за {studentInfo.ime} {studentInfo.prezime}
199 </h1>
200 {console.log(`aktivnosti: ${aktivnosti}`)}
201
202 <form onSubmit={handleSubmit}>
203 <div className="row m-3 align-items-center">
204 <label
205 htmlFor="ocenka"
206 className="col-form-label col-3 m-3 text-center text-white"
207 >
208 Внеси оценка од 1 до 5
209 </label>
210 <div className="col-8">
211 <input
212 name="ocenka"
213 type="number"
214 required
215 className="form-control w-75 m-3 mx-auto"
216 placeholder="Оценката мора да биде од 1 до 5"
217 min="1"
218 max="5"
219 value={formData.ocenka}
220 onChange={handleChange}
221 />
222 </div>
223 </div>
224 <div className="row mb-3 align-items-center">
225 <label
226 htmlFor="datum"
227 className="col-form-label col-3 m-3 text-center text-white"
228 >
229 Внеси датум на внесување на оценката
230 </label>
231 <div className="col-8">
232 <input
233 name="datum"
234 type="date"
235 className="form-control w-75 m-3 mx-auto"
236 required
237 value={formData.datum}
238 onChange={handleChange}
239 />
240 </div>
241 </div>
242 <div className="row mb-3 align-items-center">
243 <label
244 htmlFor="zabeleska"
245 className="col-3 col-form-label m-3 text-white"
246 >
247 забелешка
248 </label>
249 <textarea
250 name="zabeleska"
251 value={formData.zabeleska}
252 required
253 placeholder="Внесете забелешка за оценката доколку ја имате"
254 onChange={handleChange}
255 className="form-control w-75 mx-auto"
256 style={{ minHeight: "200px", resize: "horizontal" }}
257 />
258 </div>
259 <div className="row mb-3 align-items-center">
260 <label className="form-label m-3 col-3 text-center text-white">
261 Избери Предмет
262 </label>
263 <div className="col-8">
264 <select
265 name="predmetId"
266 value={formData.eZaPredmetot_Id} //treba nekako da se zeme id?
267 required
268 onChange={handleChange}
269 className="form-control w-75 mx-auto"
270 >
271 <option value="">-- Избери предмет --</option>
272 {predmeti.map((n) => (
273 <option key={n.id} value={n.id}>
274 {n.ime} {n.fond_casovi}
275 </option>
276 ))}
277 </select>
278 </div>
279 </div>
280
281 <div className="row mb-3 align-items-center">
282 <label className="form-label text-center p-3 col-3 text-white">
283 Избери активност?
284 </label>
285 <div className="col-9">
286 <select
287 name="zaAktivnosta_id"
288 value={formData.zaAktivnosta_id}
289 required
290 onChange={handleChange}
291 className="form-control w-75 m-3 mx-auto"
292 >
293 <option value="">-- Избери активност --</option>
294 {aktivnosti.map((n) => {
295 const predmet = predmeti.find((p) => p.id === n.predmetId);
296 return (
297 <option key={n.id} value={n.id}>
298 Активност: {n.naslov} - Ден: {n.den} - Предмет:{" "}
299 {predmet ? predmet.ime : "непознато име"}
300 </option>
301 );
302 })}
303 </select>
304 </div>
305 </div>
306 <div className="row align-items-center mb-3">
307 <label
308 htmlFor="osvoeni_poeni"
309 className="form-label col-3 p-3 text-center text-white"
310 >
311 Внеси освоени поени за ученикот од 1 до 100
312 </label>
313 <div className="col-9">
314 <input
315 name="osvoeni_poeni"
316 type="number"
317 required
318 className="form-control w-75 mx-auto"
319 min="1"
320 max="100"
321 value={formData.osvoeni_poeni}
322 onChange={handleChange}
323 />
324 </div>
325 </div>
326 <div className="row mb-3 align-items-center">
327 <label
328 htmlFor="max_poeni"
329 className="text-white col-3 p-3 text-center form-label"
330 >
331 Внеси максимум поени што може да се освојат од 1 до 100
332 </label>
333 <div className="col-9">
334 <input
335 name="max_poeni"
336 type="number"
337 required
338 className="form-control m-3 w-75 mx-auto"
339 min="1"
340 max="100"
341 value={formData.max_poeni}
342 onChange={handleChange}
343 />
344 </div>
345 </div>
346 <div className="row mb-3 align-items-center">
347 <label
348 htmlFor="vid"
349 className="form-label col-3 p-3 text-center text-white"
350 >
351 Избери вид на усно испрашување
352 </label>
353 <div className="col-9">
354 <select
355 name="vid"
356 value={formData.vid}
357 required
358 onChange={handleChange}
359 className="form-control m-3 w-75 mx-auto"
360 >
361 <option value="">-- Избери вид писмено испрашување --</option>
362 {vidoviIsprasuvanje.map((n) => (
363 <option key={n} value={n}>
364 {n}
365 </option>
366 ))}
367 </select>
368 </div>
369 </div>
370 <div className="text-center">
371 <button className="btn btn-primary m-3 " type="submit">
372 Внеси писмена оценка
373 </button>
374 <a className="btn btn-danger m-3">Откажи</a>
375 </div>
376 </form>
377 </div>
378 </div>
379 </>
380 );
381};
382
383export default PredmetenNastavnik_CreatePismenaOcenka;
Note: See TracBrowser for help on using the repository browser.