na spokojnie jak obiad 3

This commit is contained in:
rzodkiew 2025-02-14 14:31:21 +01:00
parent c5388b5690
commit 7595d1bd8f
5 changed files with 127 additions and 142 deletions

View File

@ -51,13 +51,16 @@
"bad_frekwencja": 2,
"good_frekwencja": 11,
"dobra_frekwencja": 0,
"aktywnosc": 1,
"aktywnosc": 0,
"sprawdzian": 3,
"siema": 25
"siema": 2,
"zla_frekwencja": 0,
"konkursy": 0
},
"Anna-Nowak": {
"good_frekwencja": 4,
"dobra_frekwencja": 1
"dobra_frekwencja": 0,
"aktywnosc": 10
},
"Piotr-Wiśniewski": {
"dobra_frekwencja": 0,

View File

@ -14,5 +14,9 @@
{
"nazwa": "siema",
"punkty": 2
},
{
"nazwa": "konkursy",
"punkty": 15
}
]

View File

@ -12,13 +12,10 @@
<!-- Zakładki -->
<div class="tabs">
<button id="students-tab">Uczniowie</button>
<button id="stats-tab">Statystyka</button>
<button id="criteria-tab">Zarządzanie kryteriami</button>
</div>
<!-- Lista uczniów -->
<div id="students-list"></div>
<!-- Statystyki -->
<div id="stats-content" style="display: none;"></div>
<!-- Zarządzanie kryteriami -->
<div id="criteria-content" style="display: none;">
<h2>Lista kryteriów</h2>

177
script.js
View File

@ -1,10 +1,8 @@
document.addEventListener("DOMContentLoaded", () => {
const studentsList = document.getElementById("students-list");
const statsContent = document.getElementById("stats-content");
const criteriaContent = document.getElementById("criteria-content");
const saveButton = document.getElementById("save-button");
const studentsTab = document.getElementById("students-tab");
const statsTab = document.getElementById("stats-tab");
const criteriaTab = document.getElementById("criteria-tab");
const addCriteriaForm = document.getElementById("add-criteria-form");
const editCriteriaForm = document.getElementById("edit-criteria-form");
@ -15,26 +13,25 @@ document.addEventListener("DOMContentLoaded", () => {
let uczniowie = [];
let kryteria = [];
let dane = {};
let progiOcen = []; // Nowa zmienna na progi ocen
let progiOcen = [];
// Ł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/oceny").then(response => response.json()) // Pobierz progi ocen
fetch("http://localhost:4000/oceny").then(response => response.json())
])
.then(([uczniowieData, kryteriaData, daneData, ocenyData]) => {
uczniowie = uczniowieData.uczniowie;
kryteria = kryteriaData;
dane = daneData;
progiOcen = ocenyData.progi; // Zapisz progi ocen
progiOcen = ocenyData.progi;
console.log("Uczniowie:", uczniowie);
console.log("Kryteria:", kryteria);
console.log("Dane:", dane);
console.log("Progi ocen:", progiOcen);
renderStudents();
renderStats();
renderCriteria();
})
.catch(error => console.error("Błąd ładowania danych:", error));
@ -48,8 +45,12 @@ document.addEventListener("DOMContentLoaded", () => {
const summary = document.createElement("summary");
summary.textContent = `${student.imie} ${student.nazwisko} (${student.klasa})`;
details.appendChild(summary);
const criteriaList = document.createElement("div");
criteriaList.className = "criteria-list";
let totalPoints = 0;
kryteria.forEach(criteria => {
const criteriaItem = document.createElement("div");
criteriaItem.className = "criteria-item";
@ -63,116 +64,86 @@ document.addEventListener("DOMContentLoaded", () => {
input.min = "0";
const savedStudent = dane[studentKey];
input.value = savedStudent?.[criteria.nazwa] || 0;
// Zapisz zmiany lokalnie w pamięci
input.addEventListener("input", () => {
if (!savedStudent) {
if (!dane[studentKey]) {
dane[studentKey] = {};
}
dane[studentKey][criteria.nazwa] = parseInt(input.value) || 0;
renderStats();
});
criteriaItem.appendChild(label);
criteriaItem.appendChild(pointsInfo);
criteriaItem.appendChild(input);
// Dodaj podkategorie, jeśli istnieją
if (criteria.podkategorie && criteria.podkategorie.length > 0) {
const subCriteriaList = document.createElement("div");
subCriteriaList.className = "sub-criteria-list";
criteria.podkategorie.forEach(subCriteria => {
const subCriteriaItem = document.createElement("div");
subCriteriaItem.className = "sub-criteria-item";
const subLabel = document.createElement("span");
subLabel.textContent = subCriteria.nazwa;
const subPointsInfo = document.createElement("span");
subPointsInfo.className = "points-info";
subPointsInfo.textContent = `(${subCriteria.punkty} pkt)`;
const subInput = document.createElement("input");
subInput.type = "number";
subInput.min = "0";
subInput.value = savedStudent?.[subCriteria.nazwa] || 0;
// Zapisz zmiany lokalnie w pamięci
subInput.addEventListener("input", () => {
if (!dane[studentKey]) {
dane[studentKey] = {};
}
dane[studentKey][subCriteria.nazwa] = parseInt(subInput.value) || 0;
});
subCriteriaItem.appendChild(subLabel);
subCriteriaItem.appendChild(subPointsInfo);
subCriteriaItem.appendChild(subInput);
subCriteriaList.appendChild(subCriteriaItem);
});
criteriaItem.appendChild(subCriteriaList);
}
criteriaList.appendChild(criteriaItem);
});
details.appendChild(criteriaList);
studentsList.appendChild(details);
});
}
// Renderuj statystyki
function renderStats() {
statsContent.innerHTML = "";
uczniowie.forEach(student => {
const studentKey = `${student.imie}-${student.nazwisko}`;
const savedStudent = dane[studentKey];
let totalPoints = 0;
if (savedStudent) {
kryteria.forEach(criteria => {
const count = savedStudent[criteria.nazwa] || 0;
// Oblicz sumę punktów
const count = savedStudent?.[criteria.nazwa] || 0;
totalPoints += count * criteria.punkty;
// Jeśli są podkategorie, dodaj ich punkty
if (criteria.podkategorie) {
criteria.podkategorie.forEach(subCriteria => {
const subCount = savedStudent?.[subCriteria.nazwa] || 0;
totalPoints += subCount * subCriteria.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";
// Dodaj sekcję z punktami i oceną w prawym górnym rogu
const statsSection = document.createElement("div");
statsSection.className = "stats-section";
statsSection.innerHTML = `
<div class="stats-box">
<span class="total-points">Punkty: ${totalPoints}</span>
<span class="grade">Ocena: ${ocena}</span>
</div>
`;
details.appendChild(statsSection);
// Imię i nazwisko
const name = document.createElement("span");
name.className = "name";
name.textContent = `${student.imie} ${student.nazwisko}`;
// Klasa
const className = document.createElement("span");
className.className = "class";
className.textContent = `(${student.klasa})`;
// Punkty
const points = document.createElement("span");
points.className = "points";
points.textContent = `${totalPoints} pkt`;
// Ocena
const grade = document.createElement("span");
grade.className = "grade";
grade.textContent = `Ocena: ${ocena}`;
// Dodaj elementy do kontenera
studentDiv.appendChild(name);
studentDiv.appendChild(className);
studentDiv.appendChild(points);
studentDiv.appendChild(grade);
// Dodaj do zawartości statystyk
statsContent.appendChild(studentDiv);
details.appendChild(criteriaList);
studentsList.appendChild(details);
});
// Dodaj sekcję z progami ocen
renderGradeThresholds();
}
// Renderuj progi ocen
function renderGradeThresholds() {
const thresholdsDiv = document.createElement("div");
thresholdsDiv.id = "grade-thresholds";
const title = document.createElement("h3");
title.textContent = "Progi punktowe na oceny";
thresholdsDiv.appendChild(title);
const table = document.createElement("table");
const headerRow = document.createElement("tr");
const headers = ["Ocena", "Minimalne punkty"];
headers.forEach(headerText => {
const th = document.createElement("th");
th.textContent = headerText;
headerRow.appendChild(th);
});
table.appendChild(headerRow);
progiOcen.forEach(prog => {
const row = document.createElement("tr");
const gradeCell = document.createElement("td");
gradeCell.textContent = prog.ocena;
row.appendChild(gradeCell);
const pointsCell = document.createElement("td");
pointsCell.textContent = `${prog.min} pkt`;
row.appendChild(pointsCell);
table.appendChild(row);
});
thresholdsDiv.appendChild(table);
statsContent.appendChild(thresholdsDiv);
}
// Renderuj listę kryteriów
@ -208,21 +179,13 @@ document.addEventListener("DOMContentLoaded", () => {
// Przełączanie między zakładkami
studentsTab.addEventListener("click", () => {
studentsList.style.display = "block";
statsContent.style.display = "none";
criteriaContent.style.display = "none";
});
statsTab.addEventListener("click", () => {
studentsList.style.display = "none";
statsContent.style.display = "block";
criteriaContent.style.display = "none";
});
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

View File

@ -4,6 +4,7 @@ body {
margin: 20px;
background-color: #f4f4f9;
}
.container {
max-width: 800px;
margin: 0 auto;
@ -11,23 +12,29 @@ body {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
position: relative; /* Dodane dla pozycjonowania stats-section */
}
h1 {
text-align: center;
color: #333;
}
label {
display: block;
margin-top: 20px;
font-weight: bold;
}
select, input {
select,
input {
width: 100%;
padding: 10px;
margin-top: 5px;
border: 1px solid #ccc;
border-radius: 4px;
}
button {
display: block;
margin: 20px auto;
@ -38,6 +45,7 @@ button {
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
@ -48,6 +56,7 @@ button:hover {
gap: 10px;
margin-bottom: 20px;
}
.tabs button {
padding: 10px;
border: none;
@ -57,6 +66,7 @@ button:hover {
cursor: pointer;
flex: 1;
}
.tabs button:hover {
background-color: #0056b3;
}
@ -68,61 +78,69 @@ button:hover {
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f9f9f9;
position: relative; /* Dodane dla pozycjonowania stats-section */
}
#students-list summary {
font-weight: bold;
cursor: pointer;
}
.criteria-list {
margin-top: 10px;
}
.criteria-item {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.criteria-item span {
margin-right: 10px;
}
.points-info {
color: #555;
font-size: 0.9em;
}
input[type="number"] {
width: 60px;
padding: 5px;
margin-left: 10px;
}
/* Statystyki */
#stats-content .stat-item {
display: flex;
justify-content: space-between;
align-items: center;
/* Sekcja statystyk w prawym górnym rogu */
.stats-section {
position: absolute;
top: 10px;
right: 10px;
background-color: #e6f7ff; /* Lekko turkusowe tło */
border: 1px solid #b3e5fc; /* Cienka obramówka */
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f9f9f9;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Delikatny cień */
z-index: 10;
}
#stats-content .name {
.stats-box {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 5px;
}
.total-points {
font-size: 14px;
font-weight: bold;
flex: 2;
}
#stats-content .class {
flex: 1;
text-align: center;
}
#stats-content .points {
flex: 1;
text-align: right;
font-weight: bold;
}
#stats-content .grade {
flex: 1;
text-align: right;
color: #007bff;
font-size: 1.1em;
}
.grade {
font-size: 16px;
font-weight: bold;
color: #28a745;
}
/* Zarządzanie kryteriami */