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": {
"bad_frekwencja": 2,
"good_frekwencja": 11,
"dobra_frekwencja": 123,
"aktywnosc": 1,
"dobra_frekwencja": 0,
"aktywnosc": 5,
"sprawdzian": 3
},
"Anna-Nowak": {
"good_frekwencja": 4
"good_frekwencja": 4,
"dobra_frekwencja": 1
},
"Piotr-Wiśniewski": {
"dobra_frekwencja": 3
"dobra_frekwencja": 0,
"aktywnosc": 25
},
"Maria-Kowalczyk": {
"dobra_frekwencja": 1
}
}

View File

@ -10,13 +10,5 @@
{
"nazwa": "aktywnosc",
"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 KRYTERIA_FILE = path.join(__dirname, "kryteria.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
app.use(express.json());
@ -42,14 +43,13 @@ app.get("/dane", (req, res) => {
fs.readFile(DANE_FILE, "utf8", (err, data) => {
if (err) {
console.error("Błąd odczytu danych:", err);
// Jeśli plik nie istnieje, utwórz go z domyślnymi danymi
const defaultData = {};
fs.writeFile(DANE_FILE, JSON.stringify(defaultData, null, 2), err => {
if (err) {
console.error("Błąd tworzenia pliku danych:", err);
return res.status(500).send("Błąd tworzenia pliku danych.");
}
res.json(defaultData); // Zwróć puste dane
res.json(defaultData);
});
} else {
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
app.post("/kryteria", (req, res) => {
const { nazwa, punkty } = req.body;
@ -81,7 +92,6 @@ app.post("/kryteria", (req, res) => {
return res.status(500).send("Błąd odczytu kryteriów.");
}
const kryteria = JSON.parse(data);
// Sprawdź, czy kryterium już istnieje
if (kryteria.some(k => k.nazwa === nazwa)) {
return res.status(400).send("Kryterium już istnieje.");
}

View File

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

View File

@ -12,6 +12,14 @@ body {
border-radius: 8px;
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 {
text-align: center;
color: #333;