| 1 | import React, { useState, useEffect } from "react";
|
|---|
| 2 | import axios from "axios";
|
|---|
| 3 | import { Link, useParams } from "react-router-dom";
|
|---|
| 4 | import NavbarRoditel from "../../../components/NavbarRoditel/NavbarRoditel";
|
|---|
| 5 |
|
|---|
| 6 | const Roditel_UcenikPage = () => {
|
|---|
| 7 | const [ucenici, setUcenici] = useState([]);
|
|---|
| 8 | const [student, setStudent] = useState(null);
|
|---|
| 9 | const [classInfo, setClassInfo] = useState(null);
|
|---|
| 10 | const [klasen, setKlasen] = useState(null);
|
|---|
| 11 | const [studentsInClass, setStudentsInClass] = useState([]);
|
|---|
| 12 | const [soopstenija, setSoopstenija] = useState([]);
|
|---|
| 13 | const [loading, setLoading] = useState(true);
|
|---|
| 14 | const { studentId } = useParams();
|
|---|
| 15 | const [roditelInfo, setRoditelInfo] = useState(null);
|
|---|
| 16 |
|
|---|
| 17 | useEffect(() => {
|
|---|
| 18 | const fetchData = async () => {
|
|---|
| 19 | const parentRes = await axios.get("http://localhost:8080/api/auth/me", {
|
|---|
| 20 | withCredentials: true,
|
|---|
| 21 | });
|
|---|
| 22 | setRoditelInfo(parentRes.data);
|
|---|
| 23 | console.log("Parent data:", parentRes.data);
|
|---|
| 24 |
|
|---|
| 25 | if (!studentId) return;
|
|---|
| 26 |
|
|---|
| 27 | try {
|
|---|
| 28 | setLoading(true);
|
|---|
| 29 |
|
|---|
| 30 | const resStudent = await axios.get(
|
|---|
| 31 | `http://localhost:8080/api/users/ucenici/${studentId}`,
|
|---|
| 32 | {
|
|---|
| 33 | withCredentials: true,
|
|---|
| 34 | }
|
|---|
| 35 | );
|
|---|
| 36 | const studentData = resStudent.data;
|
|---|
| 37 | setStudent(studentData);
|
|---|
| 38 |
|
|---|
| 39 | const cId = studentData.uciVoKlasId;
|
|---|
| 40 | if (cId) {
|
|---|
| 41 | const [resClass, resKlasen, resStudents, resSoopstenija, resUcenici] =
|
|---|
| 42 | await Promise.all([
|
|---|
| 43 | axios.get(`http://localhost:8080/api/klas/${cId}`, {
|
|---|
| 44 | withCredentials: true,
|
|---|
| 45 | }),
|
|---|
| 46 | axios.get(
|
|---|
| 47 | `http://localhost:8080/api/klas/${cId}/klasenRakovoditel`,
|
|---|
| 48 | { withCredentials: true }
|
|---|
| 49 | ),
|
|---|
| 50 | axios.get(`http://localhost:8080/api/klas/${cId}/students`, {
|
|---|
| 51 | withCredentials: true,
|
|---|
| 52 | }),
|
|---|
| 53 | axios.get(`http://localhost:8080/api/klas/${cId}/soopstenija`, {
|
|---|
| 54 | withCredentials: true,
|
|---|
| 55 | }),
|
|---|
| 56 | axios.get(
|
|---|
| 57 | `http://localhost:8080/api/users/ucenici/by-parent/${parentRes.data.id}`,
|
|---|
| 58 | { withCredentials: true }
|
|---|
| 59 | ),
|
|---|
| 60 | ]);
|
|---|
| 61 | setUcenici(resUcenici.data);
|
|---|
| 62 | setClassInfo(resClass.data);
|
|---|
| 63 | setKlasen(resKlasen.data);
|
|---|
| 64 | setStudentsInClass(resStudents.data);
|
|---|
| 65 | setSoopstenija(resSoopstenija.data);
|
|---|
| 66 | }
|
|---|
| 67 | } catch (err) {
|
|---|
| 68 | console.error("Грешка при преземање податоци:", err);
|
|---|
| 69 | } finally {
|
|---|
| 70 | setLoading(false);
|
|---|
| 71 | }
|
|---|
| 72 | };
|
|---|
| 73 |
|
|---|
| 74 | fetchData();
|
|---|
| 75 | }, [studentId]);
|
|---|
| 76 |
|
|---|
| 77 | if (loading) return <div>Вчитување на податоци за вашето дете...</div>;
|
|---|
| 78 | const formatDate = (dateString) => {
|
|---|
| 79 | if (!dateString) return "";
|
|---|
| 80 | return new Date(dateString).toLocaleDateString("mk-MK");
|
|---|
| 81 | };
|
|---|
| 82 |
|
|---|
| 83 | if (!classInfo) {
|
|---|
| 84 | return (
|
|---|
| 85 | <div>
|
|---|
| 86 | <NavbarRoditel />
|
|---|
| 87 | <div>
|
|---|
| 88 | <h2>Не се пронајдени податоци за вашето дете или неговиот клас.</h2>
|
|---|
| 89 | </div>
|
|---|
| 90 | </div>
|
|---|
| 91 | );
|
|---|
| 92 | }
|
|---|
| 93 |
|
|---|
| 94 | if (!student) {
|
|---|
| 95 | return (
|
|---|
| 96 | <div>
|
|---|
| 97 | <NavbarRoditel />
|
|---|
| 98 | <div>
|
|---|
| 99 | <h2>Не се пронајдени податоци за ученик поврзан со вашиот профил.</h2>
|
|---|
| 100 | </div>
|
|---|
| 101 | </div>
|
|---|
| 102 | );
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | return (
|
|---|
| 106 | <>
|
|---|
| 107 | <NavbarRoditel />
|
|---|
| 108 |
|
|---|
| 109 | <div>
|
|---|
| 110 | <div className="row">
|
|---|
| 111 | <div className="col-12">
|
|---|
| 112 | <nav
|
|---|
| 113 | className="container text-white h-5 d-flex text-start p-3"
|
|---|
| 114 | style={{ backgroundColor: "#147176" }}
|
|---|
| 115 | >
|
|---|
| 116 | <div className="dropdown">
|
|---|
| 117 | <button
|
|---|
| 118 | className="btn btn-secondary dropdown-toggle"
|
|---|
| 119 | type="button"
|
|---|
| 120 | id="dropdownMenuButton"
|
|---|
| 121 | data-bs-toggle="dropdown"
|
|---|
| 122 | aria-haspopup="true"
|
|---|
| 123 | aria-expanded="false"
|
|---|
| 124 | >
|
|---|
| 125 | Мои ученици
|
|---|
| 126 | </button>
|
|---|
| 127 | <div
|
|---|
| 128 | className="dropdown-menu"
|
|---|
| 129 | aria-labelledby="dropdownMenuButton"
|
|---|
| 130 | >
|
|---|
| 131 | {loading ? (
|
|---|
| 132 | <div className="dropdown-item">Вчитување...</div>
|
|---|
| 133 | ) : ucenici.length > 0 ? (
|
|---|
| 134 | ucenici.map((k) => (
|
|---|
| 135 | <Link
|
|---|
| 136 | key={k.id}
|
|---|
| 137 | className="dropdown-item"
|
|---|
| 138 | to={`/roditelDashboard/ucenik/${k.id}/soopstenija`}
|
|---|
| 139 | >
|
|---|
| 140 | {k.ime} {k.prezime}
|
|---|
| 141 | </Link>
|
|---|
| 142 | ))
|
|---|
| 143 | ) : (
|
|---|
| 144 | <div className="dropdown-item">Нема Ученииц</div>
|
|---|
| 145 | )}
|
|---|
| 146 | </div>
|
|---|
| 147 | </div>
|
|---|
| 148 | </nav>
|
|---|
| 149 | </div>
|
|---|
| 150 | </div>
|
|---|
| 151 |
|
|---|
| 152 | <div className="container m-3 mx-auto bg-success text-white d-flex flex-row justify-content-between">
|
|---|
| 153 | <span className="fs-4 text-white text-decoration-underline p-3">
|
|---|
| 154 | Соопштенија
|
|---|
| 155 | </span>
|
|---|
| 156 | <Link
|
|---|
| 157 | className="fs-4 text-white text-decoration-none p-3"
|
|---|
| 158 | to={`/roditelDashboard/${classInfo.id}/weeklyPlan`}
|
|---|
| 159 | >
|
|---|
| 160 | Неделен план
|
|---|
| 161 | </Link>
|
|---|
| 162 | <Link
|
|---|
| 163 | className="fs-4 text-white text-decoration-none p-3"
|
|---|
| 164 | to={`/roditelDashboard/${classInfo.id}/raspored`}
|
|---|
| 165 | >
|
|---|
| 166 | Распоред
|
|---|
| 167 | </Link>
|
|---|
| 168 |
|
|---|
| 169 | <Link
|
|---|
| 170 | className="fs-4 text-white text-decoration-none p-3"
|
|---|
| 171 | to={`/roditelDashboard/student/${student?.id}/grades`}
|
|---|
| 172 | >
|
|---|
| 173 | Оценки
|
|---|
| 174 | </Link>
|
|---|
| 175 | <Link
|
|---|
| 176 | className="fs-4 text-white text-decoration-none p-3"
|
|---|
| 177 | to={`/roditelDashboard/student/${student?.id}/prisustva`}
|
|---|
| 178 | >
|
|---|
| 179 | Присуства
|
|---|
| 180 | </Link>
|
|---|
| 181 | </div>
|
|---|
| 182 | <div>
|
|---|
| 183 | <div className="row m-4 pl-3">
|
|---|
| 184 | <div className="col-8">
|
|---|
| 185 | <h1>
|
|---|
| 186 | Клас {classInfo?.oddelenie}-{classInfo?.paralelka} – Огласна
|
|---|
| 187 | табла
|
|---|
| 188 | </h1>
|
|---|
| 189 | {soopstenija.length > 0 ? (
|
|---|
| 190 | soopstenija.map((s) => (
|
|---|
| 191 | <div className="card" key={s.id}>
|
|---|
| 192 | <div>
|
|---|
| 193 | <div className="p-3 fs-4">
|
|---|
| 194 | <p className="front-start d-inline-block">
|
|---|
| 195 | <span className="fw-bold">Креирано од:</span>{" "}
|
|---|
| 196 | {klasen?.ime} {klasen?.prezime} (Класен)
|
|---|
| 197 | </p>
|
|---|
| 198 | <span className="float-end">
|
|---|
| 199 | Објавено на: {formatDate(s.kreiranoNa)}
|
|---|
| 200 | </span>
|
|---|
| 201 | </div>
|
|---|
| 202 | </div>
|
|---|
| 203 | <div className="p-3 bg-info text-white">
|
|---|
| 204 | <h3>{s.naslov}</h3>
|
|---|
| 205 | <p>{s.sodrzina}</p>
|
|---|
| 206 | </div>
|
|---|
| 207 | </div>
|
|---|
| 208 | ))
|
|---|
| 209 | ) : (
|
|---|
| 210 | <p>Нема активни соопштенија за овој клас.</p>
|
|---|
| 211 | )}
|
|---|
| 212 | </div>
|
|---|
| 213 |
|
|---|
| 214 | <div className="col-4 ">
|
|---|
| 215 | <h3>Информации за вашето дете</h3>
|
|---|
| 216 | <p>
|
|---|
| 217 | <strong>Име:</strong> {student?.ime} {student?.prezime}
|
|---|
| 218 | </p>
|
|---|
| 219 |
|
|---|
| 220 | <div>
|
|---|
| 221 | <h3>Информации за класот</h3>
|
|---|
| 222 |
|
|---|
| 223 | <div>
|
|---|
| 224 | <h4>Класен раководител</h4>
|
|---|
| 225 | <p>
|
|---|
| 226 | {klasen
|
|---|
| 227 | ? `${klasen.ime} ${klasen.prezime}`
|
|---|
| 228 | : "Не е назначен"}
|
|---|
| 229 | </p>
|
|---|
| 230 | </div>
|
|---|
| 231 |
|
|---|
| 232 | <div>
|
|---|
| 233 | <h4>Ученици ({studentsInClass.length})</h4>
|
|---|
| 234 | <ul>
|
|---|
| 235 | {studentsInClass.map((s) => (
|
|---|
| 236 | <li key={s.id}>
|
|---|
| 237 | {s.ime} {s.prezime}{" "}
|
|---|
| 238 | {s.id === student?.id && "(Вашето дете)"}
|
|---|
| 239 | </li>
|
|---|
| 240 | ))}
|
|---|
| 241 | </ul>
|
|---|
| 242 | </div>
|
|---|
| 243 | </div>
|
|---|
| 244 | </div>
|
|---|
| 245 | </div>
|
|---|
| 246 | </div>
|
|---|
| 247 | </div>
|
|---|
| 248 | </>
|
|---|
| 249 | );
|
|---|
| 250 | };
|
|---|
| 251 |
|
|---|
| 252 | export default Roditel_UcenikPage;
|
|---|