source: frontend/web3-eDnevnik_Frontend/src/pages/dashboards/Klasen_RakovoditelDashboard/KlasenRakovoditelDashboardPage.jsx@ 81cdf2d

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

initial commit

  • Property mode set to 100644
File size: 9.0 KB
Line 
1import React, { useState, useEffect } from "react";
2import axios from "axios";
3import styles from "../Klasen_RakovoditelDashboard/KlasenRakovoditelDashboardPageStyles.module.css";
4import NavbarKlasen from "../../../components/navbarKlasen/NavbarKlasen.jsx";
5import { Link } from "react-router-dom";
6
7const KlasenRakovoditelDashboardViewPage = ({ teacherId }) => {
8 const [classId, setClassId] = useState(null);
9 const [classInfo, setClassInfo] = useState(null);
10 const [klasen, setKlasen] = useState(null);
11 const [students, setStudents] = useState([]);
12 const [soopstenija, setSoopstenija] = useState([]);
13 const [loading, setLoading] = useState(true);
14 const [parents, setParents] = useState([]);
15
16 useEffect(() => {
17 const initializeDashboard = async () => {
18 if (!teacherId) return;
19
20 try {
21 setLoading(true);
22
23 const resClassInitial = await axios.get(
24 `http://localhost:8080/api/users/nastavnici/klasniRakovoditeli/${teacherId}/klas`,
25 { withCredentials: true }
26 );
27
28 const foundClass = resClassInitial.data;
29
30 if (foundClass?.id) {
31 const cId = foundClass.id;
32 setClassId(cId);
33 const resStudents = await axios.get(
34 `http://localhost:8080/api/klas/${cId}/students`,
35 {
36 withCredentials: true,
37 }
38 );
39 const studentsData = resStudents.data;
40 setStudents(studentsData);
41
42 const parentIds = [
43 ...new Set(
44 studentsData.map((s) => s.staratelId).filter((id) => id)
45 ),
46 ];
47
48 const parentRequests = parentIds.map((id) =>
49 axios.get(`http://localhost:8080/api/users/roditeli/${id}`, {
50 withCredentials: true,
51 })
52 );
53
54 const parentResponses = await Promise.all(parentRequests);
55 const parentsData = parentResponses.map((res) => res.data);
56
57 setParents(parentsData);
58
59 const [resClass, resKlasen, resSoopstenija] = await Promise.all([
60 axios.get(`http://localhost:8080/api/klas/${cId}`, {
61 withCredentials: true,
62 }),
63 axios.get(
64 `http://localhost:8080/api/klas/${cId}/klasenRakovoditel`,
65 { withCredentials: true }
66 ),
67
68 axios.get(`http://localhost:8080/api/klas/${cId}/soopstenija`, {
69 withCredentials: true,
70 }),
71 ]);
72
73 setClassInfo(resClass.data);
74 setKlasen(resKlasen.data);
75 setStudents(resStudents.data);
76 setSoopstenija(resSoopstenija.data);
77 }
78 } catch (err) {
79 console.error("Грешка при иницијализација:", err);
80 } finally {
81 setLoading(false);
82 }
83 };
84
85 initializeDashboard();
86 }, [teacherId]);
87
88 const formatDate = (dateString) => {
89 if (!dateString) return "";
90 return new Date(dateString).toLocaleDateString("mk-MK");
91 };
92
93 if (loading) return <div className={styles.loader}>Вчитување...</div>;
94
95 if (!classId) {
96 return (
97 <div className={styles.teacherWrapper}>
98 <NavbarKlasen />
99 <div className={styles.container}>
100 <h2 className={styles.errorMessage}>
101 Не сте доделени на активен клас.
102 </h2>
103 </div>
104 </div>
105 );
106 }
107
108 return (
109 <div className={styles.container}>
110 <NavbarKlasen />
111 <div className="container mt-5 mh-100">
112 <div className="row">
113 <div className="col-8">
114 <nav
115 className="container text-white h-25 d-flex justify-content-center text-center p-3"
116 style={{ backgroundColor: "#147176" }}
117 >
118 <Link
119 className="text-white text-decoration-none m-2 fw-bold fs-md"
120 to={"/dashboard"}
121 >
122 Соопштенија
123 </Link>
124 <Link
125 to={`/klasenRakovoditelDashboard/${classId}/weeklyPlan`}
126 className="text-white text-decoration-none m-2 fw-bold"
127 >
128 Види неделни активности
129 </Link>
130 <Link
131 to={`/klasenRakovoditelDashboard/${classId}/raspored`}
132 className="text-white text-decoration-none m-2 fw-bold"
133 >
134 Види распоред
135 </Link>
136 <Link
137 to={`/klasenRakovoditelDashboard/${classId}/students`}
138 className="text-white text-decoration-none m-2 fw-bold"
139 >
140 Студенти
141 </Link>
142 <Link
143 to={`/klasenRakovoditelDashboard/${classId}/subjects`}
144 className="text-white text-decoration-none m-2 fw-bold"
145 >
146 Види слушани предмети
147 </Link>
148 </nav>
149 <div
150 className="row"
151 style={{ marginTop: 20, marginBottom: 10, marginRight: 0 }}
152 >
153 <div className="col-9 fs-4 fw-bold">
154 Клас {classInfo?.oddelenie}-{classInfo?.paralelka} – Соопштенија
155 </div>
156 <div className="col p-0 m-0">
157 <Link
158 to="/klasenRakovoditelDashboard/createSoopstenie"
159 className=" btn btn-primary text-decoration-none"
160 >
161 Креирај соопштение
162 </Link>
163 </div>
164 </div>
165
166 <div className="d-flex flex-column gap-3">
167 {soopstenija.length > 0 ? (
168 soopstenija.map((s) => (
169 <div key={s.id} className="card shadow-sm">
170 <div className="card-body">
171 <div className="d-flex align-items-center mb-3">
172 <div
173 className="rounded-circle bg-secondary me-3"
174 style={{
175 width: "50px",
176 height: "50px",
177 flexShrink: 0,
178 }}
179 />
180 <div>
181 <span className="fw-bold d-block">
182 {klasen?.ime} {klasen?.prezime}
183 </span>
184 <small className="text-muted">
185 {formatDate(s.kreiranoNa)}
186 </small>
187 </div>
188 </div>
189 <h5 className="card-title">{s.naslov}</h5>
190 <p className="card-text">{s.sodrzina}</p>
191 <span
192 className="fw-bold"
193 style={{ cursor: "pointer", color: "#147176" }}
194 >
195 Отстрани соопштение
196 </span>
197 </div>
198 </div>
199 ))
200 ) : (
201 <p className="text-muted text-center">
202 Нема активни соопштенија.
203 </p>
204 )}
205 </div>
206 </div>
207
208 <div className="col">
209 <div className={styles.infoCard}>
210 <h2 className="mt-0 fw-semibold">Информации за класот</h2>
211
212 <div className={styles.infoSection}>
213 <h4 className={styles.sectionLabel}>Класен раководител</h4>
214 <p className={styles.teacherName}>
215 {klasen ? `${klasen.ime} ${klasen.prezime}` : "Не е назначен"}
216 </p>
217 </div>
218
219 <div className={styles.infoSection}>
220 <h4 className={styles.sectionLabel}>
221 Ученици ({students.length})
222 </h4>
223 <ul className={styles.participantList}>
224 {students.map((student) => (
225 <li key={student.id} className={styles.participantItem}>
226 {student.ime} {student.prezime}
227 </li>
228 ))}
229 {students.length === 0 && <li>Нема запишани ученици</li>}
230 </ul>
231 </div>
232 <div className={styles.infoSection}>
233 <h4 className={styles.sectionLabel}>
234 Родители ({parents.length})
235 </h4>
236 <ul className={styles.participantList}>
237 {parents.map((parent) => (
238 <li key={parent.id} className={styles.participantItem}>
239 {parent.ime} {parent.prezime}
240 </li>
241 ))}
242 {parents.length === 0 && <li>Нема податоци за родители</li>}
243 </ul>
244 </div>
245 </div>
246 </div>
247 </div>
248 </div>
249 </div>
250 );
251};
252
253export default KlasenRakovoditelDashboardViewPage;
Note: See TracBrowser for help on using the repository browser.