na spokojnie jak obiad

This commit is contained in:
rzodkiew 2025-02-14 12:17:22 +01:00
parent 1c65005b0a
commit 5a15a8d5ac
6 changed files with 62 additions and 34 deletions

View File

@ -50,14 +50,19 @@
"Jan-Kowalski": { "Jan-Kowalski": {
"bad_frekwencja": 2, "bad_frekwencja": 2,
"good_frekwencja": 11, "good_frekwencja": 11,
"dobra_frekwencja": 123, "dobra_frekwencja": 0,
"aktywnosc": 1, "aktywnosc": 5,
"sprawdzian": 3 "sprawdzian": 3
}, },
"Anna-Nowak": { "Anna-Nowak": {
"good_frekwencja": 4 "good_frekwencja": 4,
"dobra_frekwencja": 1
}, },
"Piotr-Wiśniewski": { "Piotr-Wiśniewski": {
"dobra_frekwencja": 3 "dobra_frekwencja": 0,
"aktywnosc": 25
},
"Maria-Kowalczyk": {
"dobra_frekwencja": 1
} }
} }

View File

@ -10,13 +10,5 @@
{ {
"nazwa": "aktywnosc", "nazwa": "aktywnosc",
"punkty": 5 "punkty": 5
},
{
"nazwa": "sprawdzian",
"punkty": -20
},
{
"nazwa": "siema",
"punkty": 20
} }
] ]

9
backend/oceny.json Normal file
View File

@ -0,0 +1,9 @@
{
"progi": [
{ "min": 90, "ocena": 5 },
{ "min": 75, "ocena": 4 },
{ "min": 60, "ocena": 3 },
{ "min": 50, "ocena": 2 },
{ "min": 0, "ocena": 1 }
]
}

View File

@ -9,6 +9,7 @@ const PORT = 4000;
const UCZNIOWIE_FILE = path.join(__dirname, "uczniowie.json"); const UCZNIOWIE_FILE = path.join(__dirname, "uczniowie.json");
const KRYTERIA_FILE = path.join(__dirname, "kryteria.json"); const KRYTERIA_FILE = path.join(__dirname, "kryteria.json");
const DANE_FILE = path.join(__dirname, "dane.json"); const DANE_FILE = path.join(__dirname, "dane.json");
const OCENY_FILE = path.join(__dirname, "oceny.json"); // Nowy plik
// Middleware do obsługi JSON i CORS // Middleware do obsługi JSON i CORS
app.use(express.json()); app.use(express.json());
@ -42,14 +43,13 @@ app.get("/dane", (req, res) => {
fs.readFile(DANE_FILE, "utf8", (err, data) => { fs.readFile(DANE_FILE, "utf8", (err, data) => {
if (err) { if (err) {
console.error("Błąd odczytu danych:", err); console.error("Błąd odczytu danych:", err);
// Jeśli plik nie istnieje, utwórz go z domyślnymi danymi
const defaultData = {}; const defaultData = {};
fs.writeFile(DANE_FILE, JSON.stringify(defaultData, null, 2), err => { fs.writeFile(DANE_FILE, JSON.stringify(defaultData, null, 2), err => {
if (err) { if (err) {
console.error("Błąd tworzenia pliku danych:", err); console.error("Błąd tworzenia pliku danych:", err);
return res.status(500).send("Błąd tworzenia pliku danych."); return res.status(500).send("Błąd tworzenia pliku danych.");
} }
res.json(defaultData); // Zwróć puste dane res.json(defaultData);
}); });
} else { } else {
res.json(JSON.parse(data)); res.json(JSON.parse(data));
@ -69,6 +69,17 @@ app.post("/dane", (req, res) => {
}); });
}); });
// Endpoint do pobierania progów ocen
app.get("/oceny", (req, res) => {
fs.readFile(OCENY_FILE, "utf8", (err, data) => {
if (err) {
console.error("Błąd odczytu progów ocen:", err);
return res.status(500).send("Błąd odczytu progów ocen.");
}
res.json(JSON.parse(data));
});
});
// Endpoint do dodawania nowego kryterium // Endpoint do dodawania nowego kryterium
app.post("/kryteria", (req, res) => { app.post("/kryteria", (req, res) => {
const { nazwa, punkty } = req.body; const { nazwa, punkty } = req.body;
@ -81,7 +92,6 @@ app.post("/kryteria", (req, res) => {
return res.status(500).send("Błąd odczytu kryteriów."); return res.status(500).send("Błąd odczytu kryteriów.");
} }
const kryteria = JSON.parse(data); const kryteria = JSON.parse(data);
// Sprawdź, czy kryterium już istnieje
if (kryteria.some(k => k.nazwa === nazwa)) { if (kryteria.some(k => k.nazwa === nazwa)) {
return res.status(400).send("Kryterium już istnieje."); return res.status(400).send("Kryterium już istnieje.");
} }

View File

@ -15,22 +15,20 @@ document.addEventListener("DOMContentLoaded", () => {
let uczniowie = []; let uczniowie = [];
let kryteria = []; let kryteria = [];
let dane = {}; let dane = {};
let progiOcen = []; // Nowa zmienna na progi ocen
// Ładowanie danych z serwera // Ładowanie danych z serwera
Promise.all([ Promise.all([
fetch("http://localhost:4000/uczniowie").then(response => response.json()), fetch("http://localhost:4000/uczniowie").then(response => response.json()),
fetch("http://localhost:4000/kryteria").then(response => response.json()), fetch("http://localhost:4000/kryteria").then(response => response.json()),
fetch("http://localhost:4000/dane").then(response => response.json()) fetch("http://localhost:4000/dane").then(response => response.json()),
fetch("http://localhost:4000/oceny").then(response => response.json()) // Pobierz progi ocen
]) ])
.then(([uczniowieData, kryteriaData, daneData]) => { .then(([uczniowieData, kryteriaData, daneData, ocenyData]) => {
uczniowie = uczniowieData.uczniowie; uczniowie = uczniowieData.uczniowie;
kryteria = kryteriaData; kryteria = kryteriaData;
dane = daneData; dane = daneData;
progiOcen = ocenyData.progi; // Zapisz progi ocen
console.log("Uczniowie:", uczniowie);
console.log("Kryteria:", kryteria);
console.log("Dane:", dane);
renderStudents(); renderStudents();
renderStats(); renderStats();
renderCriteria(); renderCriteria();
@ -85,12 +83,18 @@ document.addEventListener("DOMContentLoaded", () => {
const studentKey = `${student.imie}-${student.nazwisko}`; const studentKey = `${student.imie}-${student.nazwisko}`;
const savedStudent = dane[studentKey]; const savedStudent = dane[studentKey];
let totalPoints = 0; let totalPoints = 0;
if (savedStudent) { if (savedStudent) {
kryteria.forEach(criteria => { kryteria.forEach(criteria => {
const count = savedStudent[criteria.nazwa] || 0; const count = savedStudent[criteria.nazwa] || 0;
totalPoints += count * criteria.punkty; totalPoints += count * criteria.punkty;
}); });
} }
// Wybierz ocenę na podstawie punktów
const ocena = progiOcen.find(prog => totalPoints >= prog.min)?.ocena || 1;
// Stwórz element statystyk
const studentDiv = document.createElement("div"); const studentDiv = document.createElement("div");
studentDiv.className = "stat-item"; studentDiv.className = "stat-item";
const name = document.createElement("strong"); const name = document.createElement("strong");
@ -98,13 +102,23 @@ document.addEventListener("DOMContentLoaded", () => {
const points = document.createElement("span"); const points = document.createElement("span");
points.className = "points"; points.className = "points";
points.textContent = `${totalPoints} pkt`; points.textContent = `${totalPoints} pkt`;
// Dodaj ocenę
const grade = document.createElement("span");
grade.className = "grade";
grade.textContent = `Ocena: ${ocena}`;
grade.style.marginLeft = "10px";
grade.style.fontWeight = "bold";
if (totalPoints > 0) { if (totalPoints > 0) {
points.classList.add("positive"); points.classList.add("positive");
} else if (totalPoints < 0) { } else if (totalPoints < 0) {
points.classList.add("negative"); points.classList.add("negative");
} }
studentDiv.appendChild(name); studentDiv.appendChild(name);
studentDiv.appendChild(points); studentDiv.appendChild(points);
studentDiv.appendChild(grade); // Dodaj ocenę do elementu
statsContent.appendChild(studentDiv); statsContent.appendChild(studentDiv);
}); });
} }
@ -114,7 +128,6 @@ document.addEventListener("DOMContentLoaded", () => {
criteriaListDiv.innerHTML = ""; criteriaListDiv.innerHTML = "";
editCriteriaNameSelect.innerHTML = ""; editCriteriaNameSelect.innerHTML = "";
deleteCriteriaNameSelect.innerHTML = ""; deleteCriteriaNameSelect.innerHTML = "";
if (!Array.isArray(kryteria) || kryteria.length === 0) { if (!Array.isArray(kryteria) || kryteria.length === 0) {
console.warn("Brak kryteriów do wyświetlenia."); console.warn("Brak kryteriów do wyświetlenia.");
const noCriteriaMessage = document.createElement("p"); const noCriteriaMessage = document.createElement("p");
@ -122,20 +135,16 @@ document.addEventListener("DOMContentLoaded", () => {
criteriaListDiv.appendChild(noCriteriaMessage); criteriaListDiv.appendChild(noCriteriaMessage);
return; return;
} }
kryteria.forEach(criteria => { kryteria.forEach(criteria => {
// Wyświetl kryterium na liście
const criteriaDiv = document.createElement("div"); const criteriaDiv = document.createElement("div");
criteriaDiv.textContent = `${criteria.nazwa}: ${criteria.punkty} pkt`; criteriaDiv.textContent = `${criteria.nazwa}: ${criteria.punkty} pkt`;
criteriaListDiv.appendChild(criteriaDiv); criteriaListDiv.appendChild(criteriaDiv);
// Dodaj opcję do edycji
const editOption = document.createElement("option"); const editOption = document.createElement("option");
editOption.value = criteria.nazwa; editOption.value = criteria.nazwa;
editOption.textContent = criteria.nazwa; editOption.textContent = criteria.nazwa;
editCriteriaNameSelect.appendChild(editOption); editCriteriaNameSelect.appendChild(editOption);
// Dodaj opcję do usunięcia
const deleteOption = document.createElement("option"); const deleteOption = document.createElement("option");
deleteOption.value = criteria.nazwa; deleteOption.value = criteria.nazwa;
deleteOption.textContent = criteria.nazwa; deleteOption.textContent = criteria.nazwa;
@ -159,8 +168,8 @@ document.addEventListener("DOMContentLoaded", () => {
criteriaTab.addEventListener("click", () => { criteriaTab.addEventListener("click", () => {
studentsList.style.display = "none"; studentsList.style.display = "none";
statsContent.style.display = "none"; statsContent.style.display = "none";
criteriaContent.style.display = "block"; // Pokaż zakładkę "Zarządzanie kryteriami" criteriaContent.style.display = "block";
renderCriteria(); // Odśwież listę kryteriów renderCriteria();
}); });
// Dodawanie nowego kryterium // Dodawanie nowego kryterium
@ -168,12 +177,10 @@ document.addEventListener("DOMContentLoaded", () => {
event.preventDefault(); event.preventDefault();
const nazwa = document.getElementById("new-criteria-name").value.trim(); const nazwa = document.getElementById("new-criteria-name").value.trim();
const punkty = parseInt(document.getElementById("new-criteria-points").value); const punkty = parseInt(document.getElementById("new-criteria-points").value);
if (!nazwa || isNaN(punkty)) { if (!nazwa || isNaN(punkty)) {
alert("Wprowadź poprawne dane."); alert("Wprowadź poprawne dane.");
return; return;
} }
fetch("http://localhost:4000/kryteria", { fetch("http://localhost:4000/kryteria", {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@ -200,12 +207,10 @@ document.addEventListener("DOMContentLoaded", () => {
const nazwa = editCriteriaNameSelect.value; const nazwa = editCriteriaNameSelect.value;
const nowaNazwa = document.getElementById("edit-criteria-new-name").value.trim(); const nowaNazwa = document.getElementById("edit-criteria-new-name").value.trim();
const punkty = parseInt(document.getElementById("edit-criteria-points").value); const punkty = parseInt(document.getElementById("edit-criteria-points").value);
if (!nowaNazwa || isNaN(punkty)) { if (!nowaNazwa || isNaN(punkty)) {
alert("Wprowadź poprawne dane."); alert("Wprowadź poprawne dane.");
return; return;
} }
fetch(`http://localhost:4000/kryteria/${encodeURIComponent(nazwa)}`, { fetch(`http://localhost:4000/kryteria/${encodeURIComponent(nazwa)}`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@ -230,7 +235,6 @@ document.addEventListener("DOMContentLoaded", () => {
deleteCriteriaForm.addEventListener("submit", event => { deleteCriteriaForm.addEventListener("submit", event => {
event.preventDefault(); event.preventDefault();
const nazwa = deleteCriteriaNameSelect.value; const nazwa = deleteCriteriaNameSelect.value;
fetch(`http://localhost:4000/kryteria/${encodeURIComponent(nazwa)}`, { fetch(`http://localhost:4000/kryteria/${encodeURIComponent(nazwa)}`, {
method: "DELETE" method: "DELETE"
}) })

View File

@ -12,6 +12,14 @@ body {
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
} }
.grade {
color: #007bff; /* Niebieski kolor */
font-size: 1.1em;
margin-left: 10px;
font-weight: bold;
}
h1 { h1 {
text-align: center; text-align: center;
color: #333; color: #333;