Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f00f5f4738 | ||
|
|
23ceb4f367 | ||
|
|
c01a69586a | ||
|
|
a107c51fa2 | ||
|
|
e171ce93b6 | ||
|
|
de59809872 | ||
|
|
004b198f52 | ||
|
|
d35b50d5e4 | ||
|
|
48a5155772 | ||
|
|
3f3e16b4e5 | ||
|
|
12ecf72052 | ||
|
|
80feac12b2 | ||
|
|
757c6b6451 | ||
|
|
67aa3ed836 | ||
|
|
9ac962daf6 | ||
|
|
a446afa153 | ||
|
|
8037f2f241 | ||
|
|
bf16c91a0a | ||
|
|
ca71eba13f | ||
|
|
a88a4b2ed6 | ||
|
|
f70f8d682b | ||
|
|
084308abab | ||
|
|
5a25de4c45 | ||
|
|
4180fe823b | ||
|
|
636a325470 | ||
|
|
0f9bae45a5 | ||
|
|
86cab01fba | ||
|
|
eb3924f60f | ||
|
|
8c57152fe4 | ||
|
|
9d877a1d68 | ||
|
|
1ca8e24805 | ||
|
|
8a8d81b67f | ||
|
|
245142c833 | ||
|
|
7e1d4cd9a7 | ||
|
|
f29f7a2366 | ||
|
|
6e0d3b6b7f |
18
README.md
@@ -8,9 +8,9 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/QwIT-Development/firka-extension/releases">
|
||||
<!--<a href="https://github.com/QwIT-Development/firka-extension/releases">
|
||||
<img src="https://img.shields.io/github/downloads-pre/QwIT-Development/firka-extension/latest/total?style=for-the-badge&logo=github&logoColor=EAF7CC&label=Let%C3%B6lt%C3%A9sek&labelColor=141905&color=A7DC22" alt="Downloads">
|
||||
</a>
|
||||
</a>-->
|
||||
<a href="https://discord.gg/6DvjyPAw2T">
|
||||
<img src="https://img.shields.io/discord/1111649116020285532?style=for-the-badge&logo=discord&logoColor=EAF7CC&label=Discord&labelColor=0D1202&color=A7DC22" alt="Discord">
|
||||
</a>
|
||||
@@ -31,7 +31,7 @@
|
||||
## 📱 Funkciók
|
||||
|
||||
- **Modern Dizájn**: Teljesen újratervezett, modern felhasználói felület
|
||||
- **Személyre Szabható Témák**: Világos és sötét módok, kék és zöld színsémákkal
|
||||
- **Személyre Szabható Témák**: Világos és sötét mód vagy akár egyedi témáddal
|
||||
- **Továbbfejlesztett Felületek**:
|
||||
- Átdolgozott bejelentkezési képernyő
|
||||
- Átláthatóbb jegynapló
|
||||
@@ -39,7 +39,6 @@
|
||||
- Fejlett hiányzás kezelés
|
||||
- Egyszerűsített szerepkör választó
|
||||
- Új kezdőlap elrendezés
|
||||
- Továbbfejlesztett profilkezelő
|
||||
|
||||
## 🚀 Telepítés
|
||||
|
||||
@@ -47,10 +46,9 @@
|
||||
|
||||
## ⚙️ Beállítások
|
||||
|
||||
A bővítmény beállításait a böngésző eszköztárán található Filx ikonra kattintva érheted el. Itt módosíthatod:
|
||||
A bővítmény beállításait a böngésző eszköztárán található Firka ikonra kattintva érheted el. Itt módosíthatod:
|
||||
|
||||
- A felület színsémáját (Világos/Sötét)
|
||||
- Az fő színeket (Kék/Zöld)
|
||||
- A felület témáját, legyen az világos, sötét vagy akár egyedi témáddal.
|
||||
|
||||
## 💡 Támogatott Oldalak
|
||||
|
||||
@@ -59,17 +57,17 @@ A bővítmény jelenleg az alábbi e-KRÉTA oldalakat támogatja:
|
||||
- Bejelentkezés
|
||||
- Kijelentkezés
|
||||
- Szerepkörválasztó
|
||||
- Órarend
|
||||
- Órarend (Házi feladatok, Számonkérések)
|
||||
- Faliújság
|
||||
- Hiányzások
|
||||
- Házi feladatok
|
||||
- Jegyek
|
||||
- Intézménykereső
|
||||
- Üzenetek
|
||||
- Profil (Béta)
|
||||
|
||||
## 👥 Csapat
|
||||
|
||||
- **[Zan1456](https://github.com/Zan1456)** - Vezető Fejlesztő
|
||||
- **[BalazsManus](https://github.com/olajcsere)** - Fejlesztő
|
||||
- **[Xou](https://yoursit.ee/xou)** - Designer
|
||||
|
||||
## 🤝 Közreműködés
|
||||
|
||||
@@ -139,6 +139,7 @@ body {
|
||||
}
|
||||
.dropdown-item:hover {
|
||||
background:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
}
|
||||
.kreta-main {
|
||||
flex:1;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
async function collectAbsencesData() {
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
@@ -281,7 +281,7 @@ async function transformAbsencesPage() {
|
||||
container.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(createTemplate.header(), 'text/html');
|
||||
const doc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
headerDiv.appendChild(tempDiv.firstChild);
|
||||
|
||||
@@ -219,6 +219,51 @@ h2 {
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
/* Mobile view: author below content */
|
||||
@media (max-width: 768px) {
|
||||
.news-item .widget-row {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.news-item .widget-meta {
|
||||
order: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.news-item .widget-details {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.news-author {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.widget-date {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.news-author {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop view: limit author width and wrap text */
|
||||
@media (min-width: 769px) {
|
||||
.news-author {
|
||||
max-width: 180px;
|
||||
white-space: normal;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-empty {
|
||||
@@ -346,6 +391,7 @@ h2 {
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--accent-15);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dropdown-item svg {
|
||||
|
||||
@@ -292,18 +292,22 @@ class DashboardDataManager {
|
||||
|
||||
class DashboardRenderer {
|
||||
constructor(data) {
|
||||
this.baseData = data;
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.data = {
|
||||
...data,
|
||||
...this.baseData,
|
||||
schoolInfo: {
|
||||
name:
|
||||
cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
id: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || "",
|
||||
await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
DEFAULT_VALUES.TIMER,
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
|
||||
@@ -475,14 +479,15 @@ class DashboardRenderer {
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
async render() {
|
||||
await this.init();
|
||||
document.body.innerHTML = '';
|
||||
|
||||
const kretaContainer = document.createElement('div');
|
||||
kretaContainer.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const headerDoc = parser.parseFromString(createTemplate.header(), 'text/html');
|
||||
const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
@@ -573,7 +578,7 @@ class DashboardApplication {
|
||||
const dashboardData = await dataManager.extractAllData();
|
||||
|
||||
const renderer = new DashboardRenderer(dashboardData);
|
||||
renderer.render();
|
||||
await renderer.render();
|
||||
} catch (error) {
|
||||
console.error("Error initializing dashboard:", error);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
try {
|
||||
currentLanguage = language;
|
||||
|
||||
cookieManager.set("languagePreference", language);
|
||||
await storageManager.set("languagePreference", language);
|
||||
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
await loadTranslations(language);
|
||||
@@ -82,20 +83,25 @@
|
||||
}
|
||||
|
||||
async function initializeLanguage() {
|
||||
const cookieLanguage = cookieManager.get("languagePreference");
|
||||
const localStorageLanguage = localStorage.getItem("languagePreference");
|
||||
try {
|
||||
const storageLanguage = await storageManager.get("languagePreference");
|
||||
const localStorageLanguage = localStorage.getItem("languagePreference");
|
||||
const language = storageLanguage || localStorageLanguage || "hu";
|
||||
|
||||
const language = cookieLanguage || localStorageLanguage || "hu";
|
||||
await setLanguage(language);
|
||||
loadTranslationsForPage();
|
||||
|
||||
await setLanguage(language);
|
||||
loadTranslationsForPage();
|
||||
|
||||
if (cookieLanguage !== localStorageLanguage) {
|
||||
if (cookieLanguage) {
|
||||
localStorage.setItem("languagePreference", cookieLanguage);
|
||||
} else if (localStorageLanguage) {
|
||||
cookieManager.set("languagePreference", localStorageLanguage);
|
||||
if (storageLanguage !== localStorageLanguage) {
|
||||
if (storageLanguage) {
|
||||
localStorage.setItem("languagePreference", storageLanguage);
|
||||
} else if (localStorageLanguage) {
|
||||
await storageManager.set("languagePreference", localStorageLanguage);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error initializing language:", error);
|
||||
await setLanguage("hu");
|
||||
loadTranslationsForPage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,8 +127,7 @@
|
||||
function loadTranslationsForPage() {
|
||||
try {
|
||||
applyTranslations();
|
||||
|
||||
// Figyeljük a DOM változásokat és alkalmazzuk a fordításokat új elemekre
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'childList') {
|
||||
@@ -142,8 +147,7 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Ha maga az elem is tartalmaz data-i18n attribútumot
|
||||
|
||||
if (node.hasAttribute && node.hasAttribute('data-i18n')) {
|
||||
const key = node.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
@@ -9,12 +9,7 @@ function checkMaintenancePage() {
|
||||
const maintenanceContent = document.querySelector(".login_content");
|
||||
const bodyText = document.body ? document.body.textContent : "";
|
||||
|
||||
const specificMaintenanceMessage =
|
||||
"Kedves Felhasználók! A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik. Köszönjük türelmüket és megértésüket! KRÉTA Csapat";
|
||||
const hasSpecificMessage =
|
||||
bodyText.includes("Kedves Felhasználók!") &&
|
||||
bodyText.includes("A KRÉTA rendszer jelenleg frissítés alatt van") &&
|
||||
bodyText.includes("KRÉTA Csapat");
|
||||
const hasSpecificMessage = bodyText.includes("A KRÉTA rendszer jelenleg frissítés alatt van");
|
||||
|
||||
const hasGeneralMaintenance =
|
||||
maintenanceContent &&
|
||||
|
||||
@@ -49,15 +49,17 @@
|
||||
.nav-item {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
padding:clamp(0.5rem,1.5vw,1rem) 0.5rem;
|
||||
padding:8px 14px 8px 12px;
|
||||
color:var(--text-secondary);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
white-space:nowrap;
|
||||
border-radius:8px;
|
||||
border-radius:20px;
|
||||
transition:all 0.2s ease;
|
||||
gap:0.5rem;
|
||||
text-decoration:none;
|
||||
background:var(--button-secondaryFill);
|
||||
box-shadow:0px 1px var(--shadow-blur,2px) 0px var(--accent-shadow);
|
||||
}
|
||||
.nav-item.active {
|
||||
display:flex;
|
||||
@@ -70,13 +72,13 @@
|
||||
}
|
||||
.nav-item:hover {
|
||||
color:var(--text-primary);
|
||||
background-color:var(--hover);
|
||||
background-color:var(--accent-15);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
.nav-item.active:hover {
|
||||
color:var(--accent-accent);
|
||||
background-color:var(--accent-hover);
|
||||
background-color:var(--accent-15);
|
||||
text-decoration:none;
|
||||
}
|
||||
.nav-item img,.nav-item svg {
|
||||
@@ -146,6 +148,7 @@
|
||||
background:var(--hover);
|
||||
color:var(--accent-accent);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
|
||||
@@ -11,16 +11,16 @@ const DEFAULT_VALUES = {
|
||||
TIMER: "45:00",
|
||||
};
|
||||
|
||||
function updateHeaderInfo() {
|
||||
async function updateHeaderInfo() {
|
||||
const schoolName = document.querySelector(".nav-school-name");
|
||||
const userName = document.querySelector(".nav-user-name");
|
||||
const logoutTimer = document.querySelector(".nav-logout-timer");
|
||||
|
||||
const userData = {
|
||||
schoolName:
|
||||
cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
schoolId: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || "",
|
||||
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
await storageManager.get("schoolName", DEFAULT_VALUES.SCHOOL),
|
||||
schoolId: await storageManager.get("schoolCode", ""),
|
||||
name: await storageManager.get("userName", DEFAULT_VALUES.USER),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
DEFAULT_VALUES.TIMER,
|
||||
@@ -59,8 +59,8 @@ function startLogoutTimer(timeString) {
|
||||
setInterval(updateTimer, 1000);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
updateHeaderInfo();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
});
|
||||
|
||||
function setupUserDropdown() {
|
||||
@@ -169,8 +169,8 @@ function setupMobileNavigation() {
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
updateHeaderInfo();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
:root {
|
||||
--background:#DAE4F7;
|
||||
--background-0:#dae4f700;
|
||||
--background:#FAFFF0;
|
||||
--background-0:#fafff000;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:2px;
|
||||
--text-primary:#050B15;
|
||||
--text-secondary:#050b15cc;
|
||||
--text-teritary:#050b1580;
|
||||
--card-card:#EDF3FF;
|
||||
--card-translucent:#edf3ff80;
|
||||
--button-secondaryFill:#FBFCFF;
|
||||
--accent-accent:#3673EE;
|
||||
--accent-secondary:#1C469A;
|
||||
--accent-shadow:#1c469a26;
|
||||
--accent-15:#3673ee26;
|
||||
--text-primary:#394C0A;
|
||||
--text-secondary:#394c0acc;
|
||||
--text-teritary:#394c0a80;
|
||||
--card-card:#F3FBDE;
|
||||
--card-translucent:#f3fbde80;
|
||||
--button-secondaryFill:#FEFFFD;
|
||||
--accent-accent:#A7DC22;
|
||||
--accent-secondary:#6E8F1B;
|
||||
--accent-shadow:#647e2226;
|
||||
--accent-15:#a7dc2226;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#8F531B;
|
||||
--warning-15:#ffa04626;
|
||||
@@ -66,40 +66,6 @@
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
:root[data-theme="dark-blue"] {
|
||||
--background:#070A0E;
|
||||
--background-0:#070a0e00;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:0;
|
||||
--text-primary:#EBF1FD;
|
||||
--text-secondary:#ebf1fdcc;
|
||||
--text-teritary:#ebf1fd80;
|
||||
--card-card:#0F131B;
|
||||
--card-translucent:#0f131b80;
|
||||
--button-secondaryFill:#131822;
|
||||
--accent-accent:#3673EE;
|
||||
--accent-secondary:#AEC8FC;
|
||||
--accent-shadow:#0000;
|
||||
--accent-15:#3673ee26;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#f0b37a;
|
||||
--warning-15:#ffa04626;
|
||||
--warning-card:#201203;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#f59ec5;
|
||||
--error-15:#ff54a126;
|
||||
--error-card:#1e030f;
|
||||
--grades-1:#FF54A1;
|
||||
--grades-2:#FFA046;
|
||||
--grades-3:#F9CF00;
|
||||
--grades-4:#92EA3B;
|
||||
--grades-5:#22CCAD;
|
||||
--grades-background-1:#FF54A126;
|
||||
--grades-background-2:#FFA04626;
|
||||
--grades-background-3:#F9CF0026;
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
:root[data-theme="dark-green"] {
|
||||
--background:#0D1202;
|
||||
--background-0:#0E130200;
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
(() => {
|
||||
function setTheme(theme) {
|
||||
async function setTheme(theme) {
|
||||
try {
|
||||
const actualTheme = theme === "default" ? "light-blue" : theme;
|
||||
|
||||
document.documentElement.setAttribute("data-theme", actualTheme);
|
||||
cookieManager.set("themePreference", actualTheme);
|
||||
localStorage.setItem("themePreference", actualTheme);
|
||||
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
await storageManager.set("themePreference", theme);
|
||||
chrome.runtime
|
||||
.sendMessage({
|
||||
action: "themeChanged",
|
||||
theme: actualTheme,
|
||||
theme: theme,
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch (error) {
|
||||
@@ -104,22 +100,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
function initializeTheme() {
|
||||
const cookieTheme = cookieManager.get("themePreference");
|
||||
const localStorageTheme = localStorage.getItem("themePreference");
|
||||
async function initializeTheme() {
|
||||
try {
|
||||
const theme = await storageManager.get("themePreference", "light-green");
|
||||
|
||||
const theme = cookieTheme || localStorageTheme || "light-green";
|
||||
|
||||
setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
|
||||
if (cookieTheme !== localStorageTheme) {
|
||||
if (cookieTheme) {
|
||||
localStorage.setItem("themePreference", cookieTheme);
|
||||
} else if (localStorageTheme) {
|
||||
cookieManager.set("themePreference", localStorageTheme);
|
||||
}
|
||||
await setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
} catch (error) {
|
||||
console.error("Error initializing theme:", error);
|
||||
await setTheme("light-green");
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,17 +138,20 @@
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const observer = new MutationObserver(async (mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
const savedTheme =
|
||||
cookieManager.get("themePreference") ||
|
||||
localStorage.getItem("themePreference");
|
||||
|
||||
try {
|
||||
const savedTheme = await storageManager.get("themePreference");
|
||||
|
||||
if (
|
||||
(!currentTheme && savedTheme) ||
|
||||
(currentTheme !== savedTheme && savedTheme)
|
||||
) {
|
||||
setTheme(savedTheme);
|
||||
if (
|
||||
(!currentTheme && savedTheme) ||
|
||||
(currentTheme !== savedTheme && savedTheme)
|
||||
) {
|
||||
await setTheme(savedTheme);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking theme in observer:", error);
|
||||
}
|
||||
|
||||
const titleChanged = mutations.some(
|
||||
|
||||
@@ -317,6 +317,7 @@ body {
|
||||
}
|
||||
.dropdown-item:hover {
|
||||
background:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
}
|
||||
.kreta-main {
|
||||
flex:1;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
window.currentGradesData = gradesData;
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(generatePageHTML(
|
||||
const doc = parser.parseFromString(await generatePageHTML(
|
||||
gradesData,
|
||||
studentAverage,
|
||||
classAverage,
|
||||
@@ -61,24 +61,24 @@
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return processAPIGradesData(data);
|
||||
return await processAPIGradesData(data);
|
||||
} catch (error) {
|
||||
console.error("Error fetching grades from API:", error);
|
||||
return extractGradesDataFromDOM();
|
||||
return await extractGradesDataFromDOM();
|
||||
}
|
||||
}
|
||||
|
||||
function processAPIGradesData(apiData) {
|
||||
async function processAPIGradesData(apiData) {
|
||||
const subjects = [];
|
||||
|
||||
if (!apiData.Data || !Array.isArray(apiData.Data)) {
|
||||
return {
|
||||
schoolInfo: {
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
@@ -195,11 +195,11 @@
|
||||
|
||||
return {
|
||||
schoolInfo: {
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
name: await storageManager.get("schoolName", "Iskola"),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
name: await storageManager.get("userName", "Felhasználó"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
@@ -208,7 +208,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
function extractGradesDataFromDOM() {
|
||||
async function extractGradesDataFromDOM() {
|
||||
const subjects = [];
|
||||
const rows = document.querySelectorAll(
|
||||
"#Osztalyzatok_7895TanuloErtekelesByTanuloGrid tbody tr",
|
||||
@@ -293,11 +293,11 @@
|
||||
|
||||
return {
|
||||
schoolInfo: {
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
name: await storageManager.get("schoolName", "Iskola"),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
name: await storageManager.get("userName", "Felhasználó"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
@@ -376,7 +376,7 @@
|
||||
return distribution;
|
||||
}
|
||||
|
||||
function generatePageHTML(data, studentAverage, classAverage) {
|
||||
async function generatePageHTML(data, studentAverage, classAverage) {
|
||||
const totalGrades = data.subjects.reduce(
|
||||
(sum, subject) => sum + subject.grades.length,
|
||||
0,
|
||||
@@ -393,7 +393,7 @@
|
||||
|
||||
return `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
${await createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="grades-overview">
|
||||
|
||||
@@ -1,753 +0,0 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.kreta-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: minmax(250px, 350px) 1fr minmax(180px, 250px);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.school-info {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.school-details span {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.school-details span {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
width: 200px;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.user-dropdown.show {
|
||||
display: block;
|
||||
animation: dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--accent-15);
|
||||
}
|
||||
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
.filter-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.filter-header h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
/* Checkbox oszlop stílusai */
|
||||
.checkbox-header {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
padding: 8px !important;
|
||||
}
|
||||
|
||||
.homework-checkbox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
border: 2px solid var(--accent-30);
|
||||
border-radius: 4px;
|
||||
background-color: var(--card-card);
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.homework-checkbox:hover {
|
||||
border-color: var(--accent);
|
||||
background-color: var(--accent-15);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.homework-checkbox:checked {
|
||||
background-color: var(--accent);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.homework-checkbox:checked::after {
|
||||
content: '✓';
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.homework-checkbox:focus {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.homework-checkbox:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Megjelölt házi feladatok stílusai */
|
||||
.table-row.user-completed {
|
||||
opacity: 0.6;
|
||||
background-color: var(--accent-15) !important;
|
||||
}
|
||||
|
||||
.table-row.user-completed .table-cell {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.table-row.user-completed .status-badge.completed {
|
||||
background-color: var(--success);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Mobil nézet checkbox stílusai */
|
||||
@media (max-width: 768px) {
|
||||
.checkbox-header {
|
||||
width: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
width: 40px;
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
.homework-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.homework-checkbox:checked::after {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.table-row.user-completed {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.filter-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.filter-group select,
|
||||
.filter-group input {
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.filter-group select:focus,
|
||||
.filter-group input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px var(--accent-accent);
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 1rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.filter-button {
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.filter-button.primary {
|
||||
background-color: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.filter-button.secondary {
|
||||
background-color: var(--accent-15);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.filter-button:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--accent-accent);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.stat-card.urgent .stat-number {
|
||||
color: #ff4757;
|
||||
}
|
||||
|
||||
.stat-card.completed .stat-number {
|
||||
color: #2ed573;
|
||||
}
|
||||
|
||||
.homework-container {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.homework-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
background: var(--accent-15);
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.table-header th {
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: var(--accent-15);
|
||||
}
|
||||
|
||||
.table-row.due-tomorrow {
|
||||
background-color: rgba(255, 71, 87, 0.1);
|
||||
}
|
||||
|
||||
.table-row.due-tomorrow:hover {
|
||||
background-color: rgba(255, 71, 87, 0.2);
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 16px;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.date-cell {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.subject-cell {
|
||||
font-weight: 500;
|
||||
color: var(--accent-accent);
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.teacher-cell {
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.status-cell {
|
||||
text-align: center;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.status-badge.pending {
|
||||
background-color: rgba(255, 193, 7, 0.2);
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.status-badge.urgent {
|
||||
background-color: rgba(255, 71, 87, 0.2);
|
||||
color: #ff4757;
|
||||
}
|
||||
|
||||
.status-badge.completed {
|
||||
background-color: rgba(46, 213, 115, 0.2);
|
||||
color: #2ed573;
|
||||
}
|
||||
|
||||
.homework-list-items {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.date-header h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.homework-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
margin: 0 16px 12px 16px;
|
||||
background: var(--accent-15);
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.homework-item:hover {
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.homework-item.due-tomorrow {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.homework-item.due-tomorrow .homework-subject,
|
||||
.homework-item.due-tomorrow .homework-content,
|
||||
.homework-item.due-tomorrow .homework-teacher {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.homework-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.homework-subject {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.homework-content {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.homework-teacher {
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: var(--text-secondary);
|
||||
display: none;
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.filter-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.homework-header {
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.homework-container {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.homework-table,
|
||||
.table-header,
|
||||
.table-row,
|
||||
.table-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.date-group {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.date-group-header {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
border-radius: 12px 12px 0 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.date-group-content {
|
||||
background: var(--card-card);
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 0 0 12px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.table-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.table-cell:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.table-cell::before {
|
||||
content: attr(data-label);
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: none;
|
||||
white-space: normal;
|
||||
text-overflow: initial;
|
||||
overflow: visible;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: clamp(4px, 1vw, 8px);
|
||||
height: clamp(4px, 1vw, 8px);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
}
|
||||
@@ -1,712 +0,0 @@
|
||||
async function fetchHomeworkData() {
|
||||
try {
|
||||
const currentDomain = window.location.hostname;
|
||||
const apiUrl = `https://${currentDomain}/api/TanuloHaziFeladatApi/GetTanulotHaziFeladatGrid?sort=HaziFeladatHatarido-asc&page=1&pageSize=100&group=&filter=&data=%7B%22RegiHaziFeladatokElrejtese%22%3Afalse%7D&_=${Date.now()}`;
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching homework data:", error);
|
||||
return { Data: [], Total: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
async function collectHomeworkData() {
|
||||
const apiData = await fetchHomeworkData();
|
||||
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
const homeworkItems = [];
|
||||
|
||||
if (apiData.Data && Array.isArray(apiData.Data)) {
|
||||
apiData.Data.forEach((item) => {
|
||||
homeworkItems.push({
|
||||
id: item.ID,
|
||||
subject: item.TantargyNev || "",
|
||||
teacher: item.TanarNeve || "",
|
||||
description: item.HaziFeladatSzoveg || "",
|
||||
createdDate: formatApiDate(item.HaziFeladatRogzitesDatuma),
|
||||
deadline: formatApiDate(item.HaziFeladatHatarido),
|
||||
completed: item.MegoldottHF_BOOL || false,
|
||||
classGroup: item.OsztalyCsoport || "",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const groupedHomework = {};
|
||||
homeworkItems.forEach((homework) => {
|
||||
const deadlineDate = homework.deadline.split(" ")[0];
|
||||
if (!groupedHomework[deadlineDate]) {
|
||||
groupedHomework[deadlineDate] = [];
|
||||
}
|
||||
groupedHomework[deadlineDate].push(homework);
|
||||
});
|
||||
|
||||
return { basicData, homeworkItems, groupedHomework };
|
||||
}
|
||||
|
||||
function formatApiDate(dateString) {
|
||||
if (!dateString) return "";
|
||||
|
||||
try {
|
||||
const date = new Date(dateString);
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
const dayNames = [
|
||||
LanguageManager.t("common.sunday"),
|
||||
LanguageManager.t("common.monday"),
|
||||
LanguageManager.t("common.tuesday"),
|
||||
LanguageManager.t("common.wednesday"),
|
||||
LanguageManager.t("common.thursday"),
|
||||
LanguageManager.t("common.friday"),
|
||||
LanguageManager.t("common.saturday"),
|
||||
];
|
||||
const dayName = dayNames[date.getDay()];
|
||||
|
||||
return `${month}.${day}. (${dayName})`;
|
||||
} catch (error) {
|
||||
return dateString;
|
||||
}
|
||||
}
|
||||
|
||||
function isTomorrow(dateStr) {
|
||||
if (!dateStr) return false;
|
||||
|
||||
const parts = dateStr.split(".");
|
||||
if (parts.length < 3) return false;
|
||||
|
||||
const year = parseInt(parts[0].trim());
|
||||
const month = parseInt(parts[1].trim()) - 1;
|
||||
const day = parseInt(parts[2].trim());
|
||||
|
||||
const homeworkDate = new Date(year, month, day);
|
||||
|
||||
const tomorrow = new Date();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
tomorrow.setHours(0, 0, 0, 0);
|
||||
|
||||
const dayAfterTomorrow = new Date(tomorrow);
|
||||
dayAfterTomorrow.setDate(dayAfterTomorrow.getDate() + 1);
|
||||
|
||||
return homeworkDate >= tomorrow && homeworkDate < dayAfterTomorrow;
|
||||
}
|
||||
|
||||
async function transformHomeworkPage() {
|
||||
const { basicData, homeworkItems, groupedHomework } =
|
||||
await collectHomeworkData();
|
||||
document.body.innerHTML = '';
|
||||
const kretaContainer = document.createElement('div');
|
||||
kretaContainer.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const headerDoc = parser.parseFromString(createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(headerDiv);
|
||||
const main = document.createElement('main');
|
||||
main.className = 'kreta-main';
|
||||
|
||||
const filterCard = document.createElement('div');
|
||||
filterCard.className = 'filter-card';
|
||||
|
||||
const filterHeader = document.createElement('div');
|
||||
filterHeader.className = 'filter-header';
|
||||
const filterTitle = document.createElement('h2');
|
||||
filterTitle.textContent = LanguageManager.t('homework.filter_title');
|
||||
filterHeader.appendChild(filterTitle);
|
||||
|
||||
const filterContent = document.createElement('div');
|
||||
filterContent.className = 'filter-content';
|
||||
|
||||
const subjectGroup = document.createElement('div');
|
||||
subjectGroup.className = 'filter-group';
|
||||
const subjectLabel = document.createElement('label');
|
||||
subjectLabel.textContent = LanguageManager.t('homework.subject');
|
||||
const subjectSelect = document.createElement('select');
|
||||
subjectSelect.id = 'subjectFilter';
|
||||
|
||||
const allSubjectsOption = document.createElement('option');
|
||||
allSubjectsOption.value = '';
|
||||
allSubjectsOption.textContent = LanguageManager.t('homework.all_subjects');
|
||||
subjectSelect.appendChild(allSubjectsOption);
|
||||
|
||||
[...new Set(homeworkItems.map((item) => item.subject))]
|
||||
.sort()
|
||||
.forEach((subject) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject;
|
||||
option.textContent = subject;
|
||||
subjectSelect.appendChild(option);
|
||||
});
|
||||
|
||||
subjectGroup.appendChild(subjectLabel);
|
||||
subjectGroup.appendChild(subjectSelect);
|
||||
|
||||
const teacherGroup = document.createElement('div');
|
||||
teacherGroup.className = 'filter-group';
|
||||
const teacherLabel = document.createElement('label');
|
||||
teacherLabel.textContent = LanguageManager.t('homework.teacher');
|
||||
const teacherSelect = document.createElement('select');
|
||||
teacherSelect.id = 'teacherFilter';
|
||||
|
||||
const allTeachersOption = document.createElement('option');
|
||||
allTeachersOption.value = '';
|
||||
allTeachersOption.textContent = LanguageManager.t('homework.all_teachers');
|
||||
teacherSelect.appendChild(allTeachersOption);
|
||||
|
||||
[...new Set(homeworkItems.map((item) => item.teacher))]
|
||||
.sort()
|
||||
.forEach((teacher) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = teacher;
|
||||
option.textContent = teacher;
|
||||
teacherSelect.appendChild(option);
|
||||
});
|
||||
|
||||
teacherGroup.appendChild(teacherLabel);
|
||||
teacherGroup.appendChild(teacherSelect);
|
||||
|
||||
const deadlineGroup = document.createElement('div');
|
||||
deadlineGroup.className = 'filter-group';
|
||||
const deadlineLabel = document.createElement('label');
|
||||
deadlineLabel.textContent = LanguageManager.t('homework.due_date');
|
||||
const deadlineSelect = document.createElement('select');
|
||||
deadlineSelect.id = 'deadlineFilter';
|
||||
|
||||
const deadlineOptions = [
|
||||
{ value: '', text: LanguageManager.t('homework.all_deadlines') },
|
||||
{ value: 'tomorrow', text: LanguageManager.t('homework.tomorrow_deadline') },
|
||||
{ value: 'thisWeek', text: LanguageManager.t('homework.this_week') },
|
||||
{ value: 'nextWeek', text: LanguageManager.t('homework.next_week') }
|
||||
];
|
||||
|
||||
deadlineOptions.forEach(({ value, text }) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value;
|
||||
option.textContent = text;
|
||||
deadlineSelect.appendChild(option);
|
||||
});
|
||||
|
||||
deadlineGroup.appendChild(deadlineLabel);
|
||||
deadlineGroup.appendChild(deadlineSelect);
|
||||
|
||||
filterContent.appendChild(subjectGroup);
|
||||
filterContent.appendChild(teacherGroup);
|
||||
filterContent.appendChild(deadlineGroup);
|
||||
|
||||
filterCard.appendChild(filterHeader);
|
||||
filterCard.appendChild(filterContent);
|
||||
|
||||
const statsOverview = document.createElement('div');
|
||||
statsOverview.className = 'stats-overview';
|
||||
statsOverview.id = 'statsOverview';
|
||||
|
||||
const statCards = [
|
||||
{ id: 'totalHomework', label: LanguageManager.t('homework.total_homework'), className: '' },
|
||||
{ id: 'urgentHomework', label: LanguageManager.t('homework.urgent_homework'), className: 'urgent' },
|
||||
{ id: 'completedHomework', label: LanguageManager.t('homework.completed_homework'), className: 'completed' },
|
||||
{ id: 'pendingHomework', label: LanguageManager.t('homework.pending_homework'), className: '' }
|
||||
];
|
||||
|
||||
statCards.forEach(({ id, label, className }) => {
|
||||
const statCard = document.createElement('div');
|
||||
statCard.className = `stat-card ${className}`.trim();
|
||||
|
||||
const statNumber = document.createElement('div');
|
||||
statNumber.className = 'stat-number';
|
||||
statNumber.id = id;
|
||||
statNumber.textContent = '0';
|
||||
|
||||
const statLabel = document.createElement('div');
|
||||
statLabel.className = 'stat-label';
|
||||
statLabel.textContent = label;
|
||||
|
||||
statCard.appendChild(statNumber);
|
||||
statCard.appendChild(statLabel);
|
||||
statsOverview.appendChild(statCard);
|
||||
});
|
||||
|
||||
const homeworkContainer = document.createElement('div');
|
||||
homeworkContainer.className = 'homework-container';
|
||||
|
||||
const homeworkTable = document.createElement('table');
|
||||
homeworkTable.className = 'homework-table';
|
||||
homeworkTable.id = 'homeworkTable';
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
thead.className = 'table-header';
|
||||
const headerRow = document.createElement('tr');
|
||||
|
||||
const headers = [
|
||||
'✓',
|
||||
LanguageManager.t('homework.due_date'),
|
||||
LanguageManager.t('homework.subject'),
|
||||
LanguageManager.t('homework.description'),
|
||||
LanguageManager.t('homework.teacher'),
|
||||
LanguageManager.t('homework.status')
|
||||
];
|
||||
|
||||
headers.forEach((headerText, index) => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = headerText;
|
||||
if (index === 0) {
|
||||
th.className = 'checkbox-header';
|
||||
}
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
||||
thead.appendChild(headerRow);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
tbody.id = 'homeworkTableBody';
|
||||
const homeworkHTML = generateHomeworkHTML(homeworkItems);
|
||||
|
||||
if (homeworkHTML.trim()) {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(`<table><tbody>${homeworkHTML}</tbody></table>`, 'text/html');
|
||||
const tempTbody = doc.querySelector('tbody');
|
||||
while (tempTbody.firstChild) {
|
||||
tbody.appendChild(tempTbody.firstChild);
|
||||
}
|
||||
} else {
|
||||
const emptyRow = document.createElement('tr');
|
||||
const emptyCell = document.createElement('td');
|
||||
emptyCell.colSpan = 5;
|
||||
emptyCell.textContent = LanguageManager.t('homework.no_homework') || 'Nincs házi feladat';
|
||||
emptyCell.style.textAlign = 'center';
|
||||
emptyCell.style.padding = '20px';
|
||||
emptyRow.appendChild(emptyCell);
|
||||
tbody.appendChild(emptyRow);
|
||||
}
|
||||
|
||||
homeworkTable.appendChild(thead);
|
||||
homeworkTable.appendChild(tbody);
|
||||
homeworkContainer.appendChild(homeworkTable);
|
||||
|
||||
main.appendChild(filterCard);
|
||||
main.appendChild(statsOverview);
|
||||
main.appendChild(homeworkContainer);
|
||||
|
||||
kretaContainer.appendChild(main);
|
||||
document.body.appendChild(kretaContainer);
|
||||
|
||||
setupFilters(homeworkItems, groupedHomework);
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
setupMobileGrouping();
|
||||
updateStatistics();
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function generateHomeworkHTML(homeworkItems) {
|
||||
const sortedHomework = homeworkItems.sort((a, b) => {
|
||||
const dateA = new Date(
|
||||
a.deadline.split(" ")[0].split(".").reverse().join("-"),
|
||||
);
|
||||
const dateB = new Date(
|
||||
b.deadline.split(" ")[0].split(".").reverse().join("-"),
|
||||
);
|
||||
return dateA - dateB;
|
||||
});
|
||||
|
||||
return sortedHomework
|
||||
.map((homework) => {
|
||||
const isUrgent = isTomorrow(homework.deadline);
|
||||
const isUserCompleted = getHomeworkCompletionStatus(homework.id);
|
||||
const status = homework.completed || isUserCompleted
|
||||
? "completed"
|
||||
: isUrgent
|
||||
? "urgent"
|
||||
: "pending";
|
||||
const statusText = homework.completed || isUserCompleted
|
||||
? LanguageManager.t("homework.completed")
|
||||
: isUrgent
|
||||
? LanguageManager.t("homework.urgent")
|
||||
: LanguageManager.t("homework.pending");
|
||||
|
||||
return `
|
||||
<tr class="table-row ${isUrgent ? "due-tomorrow" : ""} ${isUserCompleted ? "user-completed" : ""}"
|
||||
data-subject="${homework.subject}"
|
||||
data-teacher="${homework.teacher}"
|
||||
data-deadline="${homework.deadline}"
|
||||
data-homework-id="${homework.id}">
|
||||
<td class="table-cell checkbox-cell">
|
||||
<input type="checkbox" class="homework-checkbox"
|
||||
data-homework-id="${homework.id}"
|
||||
${isUserCompleted ? "checked" : ""}
|
||||
title="${isUserCompleted ? 'Megcsinált házi - kattints a visszaállításhoz' : 'Kattints a megjelöléshez'}">
|
||||
</td>
|
||||
<td class="table-cell date-cell" data-label="${LanguageManager.t("homework.due_date")}:">${homework.deadline}</td>
|
||||
<td class="table-cell subject-cell" data-label="${LanguageManager.t("homework.subject")}:">${homework.subject}</td>
|
||||
<td class="table-cell description-cell" data-label="${LanguageManager.t("homework.description")}:">${homework.description}</td>
|
||||
<td class="table-cell teacher-cell" data-label="${LanguageManager.t("homework.teacher")}:">${homework.teacher}</td>
|
||||
<td class="table-cell status-cell" data-label="${LanguageManager.t("homework.status")}:">
|
||||
<span class="status-badge ${status}">${statusText}</span>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
function formatDateHeader(dateStr) {
|
||||
if (!dateStr) return "";
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const parts = dateStr.split(".");
|
||||
if (parts.length < 2) return dateStr;
|
||||
|
||||
const month = parseInt(parts[0].trim()) - 1;
|
||||
const day = parseInt(parts[1].trim());
|
||||
const currentYear = today.getFullYear();
|
||||
|
||||
const date = new Date(currentYear, month, day);
|
||||
|
||||
if (date.toDateString() === today.toDateString()) {
|
||||
return LanguageManager.t("common.today") + " - " + dateStr;
|
||||
} else if (date.toDateString() === tomorrow.toDateString()) {
|
||||
return LanguageManager.t("common.tomorrow") + " - " + dateStr;
|
||||
}
|
||||
|
||||
const weekdays = [
|
||||
LanguageManager.t("common.sunday"),
|
||||
LanguageManager.t("common.monday"),
|
||||
LanguageManager.t("common.tuesday"),
|
||||
LanguageManager.t("common.wednesday"),
|
||||
LanguageManager.t("common.thursday"),
|
||||
LanguageManager.t("common.friday"),
|
||||
LanguageManager.t("common.saturday"),
|
||||
];
|
||||
return `${weekdays[date.getDay()]} - ${dateStr}`;
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return "";
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
function setupFilters(homeworkItems, groupedHomework) {
|
||||
const subjectFilter = document.getElementById("subjectFilter");
|
||||
const teacherFilter = document.getElementById("teacherFilter");
|
||||
const deadlineFilter = document.getElementById("deadlineFilter");
|
||||
|
||||
const applyFilters = () => {
|
||||
const selectedSubject = subjectFilter.value;
|
||||
const selectedTeacher = teacherFilter.value;
|
||||
const selectedDeadline = deadlineFilter.value;
|
||||
|
||||
const tableRows = document.querySelectorAll(".table-row");
|
||||
|
||||
tableRows.forEach((row) => {
|
||||
const subject = row.getAttribute("data-subject");
|
||||
const teacher = row.getAttribute("data-teacher");
|
||||
const deadline = row.getAttribute("data-deadline");
|
||||
|
||||
let showRow = true;
|
||||
|
||||
if (selectedSubject && subject !== selectedSubject) {
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
if (selectedTeacher && teacher !== selectedTeacher) {
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
if (selectedDeadline) {
|
||||
const parts = deadline.split(" ")[0].split(".");
|
||||
if (parts.length >= 2) {
|
||||
const month = parseInt(parts[0].trim()) - 1;
|
||||
const day = parseInt(parts[1].trim());
|
||||
const currentYear = new Date().getFullYear();
|
||||
const date = new Date(currentYear, month, day);
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const startOfWeek = new Date(today);
|
||||
const dayOfWeek = today.getDay() || 7;
|
||||
startOfWeek.setDate(today.getDate() - dayOfWeek + 1);
|
||||
|
||||
const endOfWeek = new Date(startOfWeek);
|
||||
endOfWeek.setDate(startOfWeek.getDate() + 6);
|
||||
|
||||
const startOfNextWeek = new Date(endOfWeek);
|
||||
startOfNextWeek.setDate(endOfWeek.getDate() + 1);
|
||||
|
||||
const endOfNextWeek = new Date(startOfNextWeek);
|
||||
endOfNextWeek.setDate(startOfNextWeek.getDate() + 6);
|
||||
|
||||
if (
|
||||
selectedDeadline === "tomorrow" &&
|
||||
date.toDateString() !== tomorrow.toDateString()
|
||||
) {
|
||||
showRow = false;
|
||||
} else if (
|
||||
selectedDeadline === "thisWeek" &&
|
||||
(date < startOfWeek || date > endOfWeek)
|
||||
) {
|
||||
showRow = false;
|
||||
} else if (
|
||||
selectedDeadline === "nextWeek" &&
|
||||
(date < startOfNextWeek || date > endOfNextWeek)
|
||||
) {
|
||||
showRow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
row.style.display = showRow ? "" : "none";
|
||||
});
|
||||
|
||||
updateDateGroupsVisibility();
|
||||
updateStatistics();
|
||||
setupHomeworkCheckboxes();
|
||||
};
|
||||
|
||||
subjectFilter.addEventListener("change", applyFilters);
|
||||
teacherFilter.addEventListener("change", applyFilters);
|
||||
deadlineFilter.addEventListener("change", applyFilters);
|
||||
}
|
||||
|
||||
function updateStatistics() {
|
||||
const visibleRows = document.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
|
||||
let totalCount = 0;
|
||||
let urgentCount = 0;
|
||||
let completedCount = 0;
|
||||
let pendingCount = 0;
|
||||
|
||||
visibleRows.forEach((row) => {
|
||||
totalCount++;
|
||||
|
||||
if (row.classList.contains("due-tomorrow")) {
|
||||
urgentCount++;
|
||||
}
|
||||
|
||||
const statusBadge = row.querySelector(".status-badge");
|
||||
if (statusBadge) {
|
||||
if (statusBadge.classList.contains("completed")) {
|
||||
completedCount++;
|
||||
} else if (statusBadge.classList.contains("pending")) {
|
||||
pendingCount++;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById("totalHomework").textContent = totalCount;
|
||||
document.getElementById("urgentHomework").textContent = urgentCount;
|
||||
document.getElementById("completedHomework").textContent = completedCount;
|
||||
document.getElementById("pendingHomework").textContent = pendingCount;
|
||||
}
|
||||
|
||||
function setupMobileGrouping() {
|
||||
function handleResize() {
|
||||
if (window.innerWidth <= 480) {
|
||||
createMobileGroups();
|
||||
} else {
|
||||
removeMobileGroups();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
handleResize();
|
||||
}
|
||||
|
||||
function createMobileGroups() {
|
||||
const tableBody = document.getElementById("homeworkTableBody");
|
||||
const rows = Array.from(tableBody.querySelectorAll(".table-row"));
|
||||
|
||||
if (rows.length === 0) return;
|
||||
|
||||
const groupedByDate = {};
|
||||
|
||||
rows.forEach((row) => {
|
||||
const deadline = row.getAttribute("data-deadline");
|
||||
const dateKey = deadline.split(" ")[0];
|
||||
|
||||
if (!groupedByDate[dateKey]) {
|
||||
groupedByDate[dateKey] = [];
|
||||
}
|
||||
groupedByDate[dateKey].push(row);
|
||||
});
|
||||
|
||||
tableBody.innerHTML = "";
|
||||
|
||||
Object.keys(groupedByDate)
|
||||
.sort()
|
||||
.forEach((date) => {
|
||||
const dateGroup = document.createElement("div");
|
||||
dateGroup.className = "date-group";
|
||||
dateGroup.setAttribute("data-date", date);
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "date-group-header";
|
||||
header.textContent = formatDateHeader(date);
|
||||
|
||||
const content = document.createElement("div");
|
||||
content.className = "date-group-content";
|
||||
|
||||
groupedByDate[date].forEach((row) => {
|
||||
content.appendChild(row);
|
||||
});
|
||||
|
||||
dateGroup.appendChild(header);
|
||||
dateGroup.appendChild(content);
|
||||
tableBody.appendChild(dateGroup);
|
||||
});
|
||||
|
||||
setupHomeworkCheckboxes();
|
||||
}
|
||||
|
||||
function removeMobileGroups() {
|
||||
const tableBody = document.getElementById("homeworkTableBody");
|
||||
const dateGroups = tableBody.querySelectorAll(".date-group");
|
||||
|
||||
if (dateGroups.length === 0) return;
|
||||
|
||||
const allRows = [];
|
||||
dateGroups.forEach((group) => {
|
||||
const rows = group.querySelectorAll(".table-row");
|
||||
rows.forEach((row) => allRows.push(row));
|
||||
});
|
||||
|
||||
tableBody.innerHTML = "";
|
||||
allRows.forEach((row) => tableBody.appendChild(row));
|
||||
|
||||
setupHomeworkCheckboxes();
|
||||
}
|
||||
|
||||
function updateDateGroupsVisibility() {
|
||||
const dateGroups = document.querySelectorAll(".date-group");
|
||||
|
||||
dateGroups.forEach((group) => {
|
||||
const visibleRows = group.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
group.style.display = visibleRows.length > 0 ? "block" : "none";
|
||||
});
|
||||
}
|
||||
|
||||
function getHomeworkCompletionStatus(homeworkId) {
|
||||
const completedHomework = cookieManager.get('completedHomework');
|
||||
if (!completedHomework) return false;
|
||||
|
||||
try {
|
||||
const completedList = JSON.parse(completedHomework);
|
||||
return completedList.includes(homeworkId.toString());
|
||||
} catch (error) {
|
||||
console.error('Error parsing completed homework cookie:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function setHomeworkCompletionStatus(homeworkId, isCompleted) {
|
||||
let completedHomework = cookieManager.get('completedHomework');
|
||||
let completedList = [];
|
||||
|
||||
if (completedHomework) {
|
||||
try {
|
||||
completedList = JSON.parse(completedHomework);
|
||||
} catch (error) {
|
||||
console.error('Error parsing completed homework cookie:', error);
|
||||
completedList = [];
|
||||
}
|
||||
}
|
||||
|
||||
const homeworkIdStr = homeworkId.toString();
|
||||
|
||||
if (isCompleted) {
|
||||
if (!completedList.includes(homeworkIdStr)) {
|
||||
completedList.push(homeworkIdStr);
|
||||
}
|
||||
} else {
|
||||
completedList = completedList.filter(id => id !== homeworkIdStr);
|
||||
}
|
||||
|
||||
cookieManager.set('completedHomework', JSON.stringify(completedList));
|
||||
}
|
||||
|
||||
function setupHomeworkCheckboxes() {
|
||||
const checkboxes = document.querySelectorAll('.homework-checkbox');
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
const homeworkId = this.getAttribute('data-homework-id');
|
||||
const isChecked = this.checked;
|
||||
const row = this.closest('.table-row');
|
||||
setHomeworkCompletionStatus(homeworkId, isChecked);
|
||||
|
||||
if (isChecked) {
|
||||
row.classList.add('user-completed');
|
||||
this.title = 'Megcsinált házi - kattints a visszaállításhoz';
|
||||
} else {
|
||||
row.classList.remove('user-completed');
|
||||
this.title = 'Kattints a megjelöléshez';
|
||||
}
|
||||
|
||||
const statusBadge = row.querySelector('.status-badge');
|
||||
if (statusBadge) {
|
||||
if (isChecked) {
|
||||
statusBadge.className = 'status-badge completed';
|
||||
statusBadge.textContent = LanguageManager.t('homework.completed');
|
||||
} else {
|
||||
const isUrgent = row.classList.contains('due-tomorrow');
|
||||
if (isUrgent) {
|
||||
statusBadge.className = 'status-badge urgent';
|
||||
statusBadge.textContent = LanguageManager.t('homework.urgent');
|
||||
} else {
|
||||
statusBadge.className = 'status-badge pending';
|
||||
statusBadge.textContent = LanguageManager.t('homework.pending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateStatistics();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (window.location.href.includes("/Tanulo/TanuloHaziFeladat")) {
|
||||
transformHomeworkPage().then(() => {
|
||||
setupHomeworkCheckboxes();
|
||||
}).catch((error) => {
|
||||
console.error("Error transforming homework page:", error);
|
||||
});
|
||||
}
|
||||
127
i18n/en.json
@@ -8,9 +8,7 @@
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"themes": {
|
||||
"light_blue": "Light Blue",
|
||||
"light_green": "Light Green",
|
||||
"dark_blue": "Dark Blue",
|
||||
"dark_green": "Dark Green",
|
||||
"dark_red": "Dark Red",
|
||||
"dark_purple": "Dark Purple",
|
||||
@@ -34,6 +32,33 @@
|
||||
"title": "Support",
|
||||
"description": "If you like our work and would like to support the development, you can do so in the following way:",
|
||||
"kofi": "Ko-Fi"
|
||||
},
|
||||
"custom_theme": {
|
||||
"title": "Custom Theme",
|
||||
"create": "Create New Theme",
|
||||
"import": "Import Theme",
|
||||
"editor_title": "Theme Editor",
|
||||
"import_title": "Import Theme",
|
||||
"name": "Theme name",
|
||||
"background": "Background",
|
||||
"text": "Text",
|
||||
"accent": "Accent colors",
|
||||
"main_background": "Main background",
|
||||
"card_background": "Card background",
|
||||
"primary_text": "Primary text",
|
||||
"secondary_text": "Secondary text",
|
||||
"primary_accent": "Primary accent",
|
||||
"secondary_accent": "Secondary accent",
|
||||
"preview": "Preview",
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"import_string": "Theme ID",
|
||||
"apply": "Apply",
|
||||
"edit": "Edit",
|
||||
"export": "Export",
|
||||
"delete": "Delete",
|
||||
"no_themes": "No custom themes yet",
|
||||
"delete_confirm": "Are you sure you want to delete the \"{name}\" theme?"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
@@ -42,7 +67,6 @@
|
||||
"grades": "Grades",
|
||||
"homework": "Homework",
|
||||
"absences": "Absences",
|
||||
"other": "Other",
|
||||
"messages": "Messages",
|
||||
"profile": "Profile",
|
||||
"settings": "Settings",
|
||||
@@ -75,6 +99,7 @@
|
||||
"teacher": "Teacher",
|
||||
"average": "Average",
|
||||
"chart_title": "Grades",
|
||||
"semester_evaluation": "Semester evaluation",
|
||||
"semester_evaluations": "Semester evaluations",
|
||||
"year_end_evaluations": "End of year tickets",
|
||||
"semester_average": "Semester average",
|
||||
@@ -116,7 +141,36 @@
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"found_current_week": "Found current week",
|
||||
"open_homework": "Open homework"
|
||||
"open_homework": "Open homework",
|
||||
"all_day": "All day",
|
||||
"special_day": "Special day",
|
||||
"unknown_subject": "Unknown subject",
|
||||
"lesson_topic": "Lesson topic",
|
||||
"homework_completed": "Completed homework",
|
||||
"homework_mark_completed": "Mark as completed",
|
||||
"homework_mark_uncompleted": "Completed - click to undo",
|
||||
"custom_homework": "Custom homework",
|
||||
"custom_test": "Custom test",
|
||||
"add_homework_test": "Add homework or test",
|
||||
"close": "Close",
|
||||
"add": "Add",
|
||||
"homework_details_loading": "Loading homework details...",
|
||||
"homework_details_error": "Error occurred while loading homework details.",
|
||||
"test_details_loading": "Loading details...",
|
||||
"test_details_error": "Failed to load test details.",
|
||||
"test_details_error_general": "Error occurred while loading test details.",
|
||||
"custom_homework_title": "Custom homework:",
|
||||
"custom_tests_title": "Custom tests:",
|
||||
"delete_homework_confirm": "Are you sure you want to delete this homework?",
|
||||
"delete_test_confirm": "Are you sure you want to delete this test?",
|
||||
"task_label": "Task:",
|
||||
"deadline_label": "Deadline:",
|
||||
"name_label": "Name:",
|
||||
"type_label": "Type:",
|
||||
"announce_date_label": "Announcement date:",
|
||||
"no_name": "No name",
|
||||
"no_type": "No type specified",
|
||||
"no_date": "No date"
|
||||
},
|
||||
"homework": {
|
||||
"title": "Homework",
|
||||
@@ -307,10 +361,6 @@
|
||||
"november": "November",
|
||||
"december": "December"
|
||||
},
|
||||
"search": {
|
||||
"title": "Choose school",
|
||||
"select_institution": "Please select an institution to continue!"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Student Book",
|
||||
"student_description": "View grades, absences, timetable and other information.",
|
||||
@@ -331,7 +381,7 @@
|
||||
"description": "Firka is an open source project that creates a custom user interface for the KRÉTA system.",
|
||||
"support_title": "Support",
|
||||
"support_description": "If you like our work and want to support development, you can do so in the following way:",
|
||||
"version": "v1.1.0"
|
||||
"version": "v1.3.0"
|
||||
},
|
||||
"app": {
|
||||
"title": "Firka - KRÉTA",
|
||||
@@ -350,7 +400,64 @@
|
||||
"error_message": "An error occurred during password reset",
|
||||
"success_message": "Password reset link sent to your email address",
|
||||
"invalid_data": "Invalid data",
|
||||
"invalid_email": "Invalid email address format",
|
||||
"invalid_email": "Invalid email format",
|
||||
"recaptcha_required": "Please complete the reCAPTCHA"
|
||||
},
|
||||
"modal": {
|
||||
"add_item_title": "Add new item",
|
||||
"type_label": "Type:",
|
||||
"homework_option": "Homework",
|
||||
"test_option": "Test",
|
||||
"description_label": "Description:",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save"
|
||||
},
|
||||
"search": {
|
||||
"title": "Choose school",
|
||||
"select_institution": "Please select an institution to continue!",
|
||||
"choose_school": "Choose school",
|
||||
"privacy_policy": "Privacy policy"
|
||||
},
|
||||
"icons": {
|
||||
"cancel": "cancel",
|
||||
"pending": "pending"
|
||||
},
|
||||
"messages": {
|
||||
"title": "Messages",
|
||||
"back": "Back",
|
||||
"surveys": "Surveys",
|
||||
"loading": "Loading messages...",
|
||||
"error": {
|
||||
"title": "Error occurred",
|
||||
"description": "Failed to load messages.",
|
||||
"retry": "Retry"
|
||||
},
|
||||
"empty": {
|
||||
"title": "No messages",
|
||||
"description": "There are currently no received messages."
|
||||
},
|
||||
"sender": "Sender",
|
||||
"subject": "Subject",
|
||||
"date": "Date",
|
||||
"unread": "Unread",
|
||||
"read": "Read",
|
||||
"message_detail": {
|
||||
"title": "Message Details",
|
||||
"loading": "Loading message...",
|
||||
"error": "Error loading message.",
|
||||
"from": "From",
|
||||
"to": "To",
|
||||
"subject": "Subject",
|
||||
"date": "Date",
|
||||
"content": "Content",
|
||||
"attachments": "Attachments",
|
||||
"no_attachments": "No attachments",
|
||||
"reply": "Reply",
|
||||
"forward": "Forward",
|
||||
"delete": "Delete",
|
||||
"mark_read": "Mark as read",
|
||||
"mark_unread": "Mark as unread",
|
||||
"back_to_messages": "Back to messages"
|
||||
}
|
||||
}
|
||||
}
|
||||
123
i18n/hu.json
@@ -34,6 +34,33 @@
|
||||
"title": "Támogatás",
|
||||
"description": "Ha tetszik a munkánk és szeretnéd támogatni a fejlesztést, az alábbi módon teheted meg:",
|
||||
"kofi": "Ko-Fi"
|
||||
},
|
||||
"custom_theme": {
|
||||
"title": "Egyéni Téma",
|
||||
"create": "Új Téma Létrehozása",
|
||||
"import": "Téma Importálása",
|
||||
"editor_title": "Téma Szerkesztő",
|
||||
"import_title": "Téma Importálása",
|
||||
"name": "Téma neve",
|
||||
"background": "Háttér",
|
||||
"text": "Szöveg",
|
||||
"accent": "Kiemelő színek",
|
||||
"main_background": "Fő háttér",
|
||||
"card_background": "Kártya háttér",
|
||||
"primary_text": "Elsődleges szöveg",
|
||||
"secondary_text": "Másodlagos szöveg",
|
||||
"primary_accent": "Elsődleges kiemelő",
|
||||
"secondary_accent": "Másodlagos kiemelő",
|
||||
"preview": "Előnézet",
|
||||
"save": "Mentés",
|
||||
"cancel": "Mégse",
|
||||
"import_string": "Téma azonosító",
|
||||
"apply": "Alkalmaz",
|
||||
"edit": "Szerkeszt",
|
||||
"export": "Export",
|
||||
"delete": "Töröl",
|
||||
"no_themes": "Még nincsenek egyéni témák",
|
||||
"delete_confirm": "Biztosan törölni szeretnéd a \"{name}\" témát?"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
@@ -42,7 +69,6 @@
|
||||
"grades": "Jegyek",
|
||||
"homework": "Házi feladatok",
|
||||
"absences": "Mulasztások",
|
||||
"other": "Egyéb",
|
||||
"messages": "Üzenetek",
|
||||
"profile": "Profil",
|
||||
"settings": "Beállítások",
|
||||
@@ -75,6 +101,7 @@
|
||||
"teacher": "Tanár",
|
||||
"average": "Átlag",
|
||||
"chart_title": "Jegyek",
|
||||
"semester_evaluation": "Félévi értékelés",
|
||||
"semester_evaluations": "Félévi értékelések",
|
||||
"year_end_evaluations": "Év végi értékelések",
|
||||
"semester_average": "Félévi átlag",
|
||||
@@ -116,7 +143,36 @@
|
||||
"thursday": "Csütörtök",
|
||||
"friday": "Péntek",
|
||||
"found_current_week": "Megtalált jelenlegi hét",
|
||||
"open_homework": "Ugrás a házi feladatokhoz"
|
||||
"open_homework": "Ugrás a házi feladatokhoz",
|
||||
"all_day": "Egész nap",
|
||||
"special_day": "Különleges nap",
|
||||
"unknown_subject": "Ismeretlen tantárgy",
|
||||
"lesson_topic": "Óra témája",
|
||||
"homework_completed": "Megoldott házi feladat",
|
||||
"homework_mark_completed": "Megoldottként jelöl",
|
||||
"homework_mark_uncompleted": "Megoldva - kattints a visszavonáshoz",
|
||||
"custom_homework": "Saját házi feladat",
|
||||
"custom_test": "Saját számonkérés",
|
||||
"add_homework_test": "Házi feladat vagy számonkérés hozzáadása",
|
||||
"close": "Bezárás",
|
||||
"add": "Hozzáadás",
|
||||
"homework_details_loading": "Házi feladat részletek betöltése...",
|
||||
"homework_details_error": "Hiba történt a házi feladat részletek betöltésekor.",
|
||||
"test_details_loading": "Részletek betöltése...",
|
||||
"test_details_error": "Nem sikerült betölteni a számonkérés részleteit.",
|
||||
"test_details_error_general": "Hiba történt a számonkérés részletek betöltése során.",
|
||||
"custom_homework_title": "Saját házi feladatok:",
|
||||
"custom_tests_title": "Saját számonkérések:",
|
||||
"delete_homework_confirm": "Biztosan törölni szeretnéd ezt a házi feladatot?",
|
||||
"delete_test_confirm": "Biztosan törölni szeretnéd ezt a számonkérést?",
|
||||
"task_label": "Feladat:",
|
||||
"deadline_label": "Határidő:",
|
||||
"name_label": "Megnevezés:",
|
||||
"type_label": "Típus:",
|
||||
"announce_date_label": "Bejelentés dátuma:",
|
||||
"no_name": "Nincs megnevezés",
|
||||
"no_type": "Nincs típus megadva",
|
||||
"no_date": "Nincs dátum"
|
||||
},
|
||||
"homework": {
|
||||
"title": "Házi feladatok",
|
||||
@@ -307,10 +363,6 @@
|
||||
"november": "november",
|
||||
"december": "december"
|
||||
},
|
||||
"search": {
|
||||
"title": "Válassz iskolát",
|
||||
"select_institution": "Kérjük, válasszon egy intézményt a folytatáshoz!"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Ellenőrzőkönyv",
|
||||
"student_description": "Jegyek, hiányzások, órarended és egyéb információk megtekintése.",
|
||||
@@ -331,7 +383,7 @@
|
||||
"description": "A Firka egy nyílt forráskódú projekt, amely a KRÉTA rendszerhez készít saját felhasználói felületet.",
|
||||
"support_title": "Támogatás",
|
||||
"support_description": "Ha tetszik a munkánk és szeretnéd támogatni a fejlesztést, az alábbi módon teheted meg:",
|
||||
"version": "v1.1.0"
|
||||
"version": "v1.3.0"
|
||||
},
|
||||
"app": {
|
||||
"title": "Firka - KRÉTA",
|
||||
@@ -352,5 +404,62 @@
|
||||
"invalid_data": "Hibás adatok",
|
||||
"invalid_email": "Érvénytelen e-mail cím formátum",
|
||||
"recaptcha_required": "Kérjük, töltse ki a reCAPTCHA-t"
|
||||
},
|
||||
"modal": {
|
||||
"add_item_title": "Új elem hozzáadása",
|
||||
"type_label": "Típus:",
|
||||
"homework_option": "Házi feladat",
|
||||
"test_option": "Számonkérés",
|
||||
"description_label": "Leírás:",
|
||||
"cancel": "Mégse",
|
||||
"save": "Mentés"
|
||||
},
|
||||
"search": {
|
||||
"choose_school": "Válassz iskolát",
|
||||
"privacy_policy": "Adatkezelési tájékoztató",
|
||||
"title": "Válassz iskolát",
|
||||
"select_institution": "Kérjük, válasszon egy intézményt a folytatáshoz!"
|
||||
},
|
||||
"icons": {
|
||||
"cancel": "cancel",
|
||||
"pending": "pending"
|
||||
},
|
||||
"messages": {
|
||||
"title": "Üzenetek",
|
||||
"back": "Vissza",
|
||||
"surveys": "Felmérések",
|
||||
"loading": "Üzenetek betöltése...",
|
||||
"error": {
|
||||
"title": "Hiba történt",
|
||||
"description": "Nem sikerült betölteni az üzeneteket.",
|
||||
"retry": "Újrapróbálás"
|
||||
},
|
||||
"empty": {
|
||||
"title": "Nincsenek üzenetek",
|
||||
"description": "Jelenleg nincsenek beérkezett üzenetek."
|
||||
},
|
||||
"sender": "Feladó",
|
||||
"subject": "Tárgy",
|
||||
"date": "Dátum",
|
||||
"unread": "Olvasatlan",
|
||||
"read": "Olvasott",
|
||||
"message_detail": {
|
||||
"title": "Üzenet részletei",
|
||||
"loading": "Üzenet betöltése...",
|
||||
"error": "Hiba történt az üzenet betöltése során.",
|
||||
"from": "Feladó",
|
||||
"to": "Címzett",
|
||||
"subject": "Tárgy",
|
||||
"date": "Dátum",
|
||||
"content": "Tartalom",
|
||||
"attachments": "Mellékletek",
|
||||
"no_attachments": "Nincsenek mellékletek",
|
||||
"reply": "Válasz",
|
||||
"forward": "Továbbítás",
|
||||
"delete": "Törlés",
|
||||
"mark_read": "Olvasottként jelöl",
|
||||
"mark_unread": "Olvasatlanként jelöl",
|
||||
"back_to_messages": "Vissza az üzenetekhez"
|
||||
}
|
||||
}
|
||||
}
|
||||
1
icons/delete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill="#A7DC22" d="M9 7h9v11a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V7z"/><path stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7h-2M4 7h2m0 0h12M6 7v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7m-9-.5A2.5 2.5 0 0 1 11.5 4h1A2.5 2.5 0 0 1 15 6.5v0"/></g></svg>
|
||||
|
After Width: | Height: | Size: 384 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 6.362A9.7 9.7 0 0 1 12 5c6.307 0 9.367 5.683 9.91 6.808c.06.123.06.261 0 .385c-.352.728-1.756 3.362-4.41 5.131M14 18.8a10 10 0 0 1-2 .2c-6.307 0-9.367-5.683-9.91-6.808a.44.44 0 0 1 0-.386c.219-.452.84-1.632 1.91-2.885m6 .843A3 3 0 0 1 14.236 14M3 3l18 18"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m3 3l18 18"/><path fill="#A7DC22" fill-rule="evenodd" d="M5.4 6.23c-.44.33-.843.678-1.21 1.032a15.1 15.1 0 0 0-3.001 4.11a1.44 1.44 0 0 0 0 1.255a15.1 15.1 0 0 0 3 4.111C5.94 18.423 8.518 20 12 20c2.236 0 4.1-.65 5.61-1.562l-3.944-3.943a3 3 0 0 1-4.161-4.161L5.401 6.229zm15.266 9.608a15 15 0 0 0 2.145-3.21a1.44 1.44 0 0 0 0-1.255a15.1 15.1 0 0 0-3-4.111C18.06 5.577 15.483 4 12 4a10.8 10.8 0 0 0-2.808.363z" clip-rule="evenodd"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 458 B After Width: | Height: | Size: 631 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12 5c-6.307 0-9.367 5.683-9.91 6.808a.44.44 0 0 0 0 .384C2.632 13.317 5.692 19 12 19s9.367-5.683 9.91-6.808a.44.44 0 0 0 0-.384C21.368 10.683 18.308 5 12 5"/><circle cx="12" cy="12" r="3"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#A7DC22" fill-rule="evenodd" d="M4.19 7.262C5.94 5.577 8.517 4 12 4s6.06 1.577 7.81 3.262a15.1 15.1 0 0 1 3.001 4.11c.193.399.193.857 0 1.255a15.1 15.1 0 0 1-3 4.111C18.06 18.423 15.483 20 12 20s-6.06-1.577-7.81-3.262a15.1 15.1 0 0 1-3.001-4.11a1.44 1.44 0 0 1 0-1.255a15.1 15.1 0 0 1 3-4.111zM12 15a3 3 0 1 0 0-6a3 3 0 0 0 0 6" clip-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 453 B |
1
icons/messages-active.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 21a3 3 0 0 1-3-3v-3h5a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2h5v3a3 3 0 0 1-3 3H6zm15-8h-5a2 2 0 0 0-2 2h-4a2 2 0 0 0-2-2H3V6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v7z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 329 B |
1
icons/messages-inactive.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="#6E8F1B"><path d="M5 13h3a2 2 0 0 1 2 2h4a2 2 0 0 1 2-2h3V6a1 1 0 0 0-1-1H6a1 1 0 0 0-1 1v7zm14 2h-3a2 2 0 0 1-2 2h-4a2 2 0 0 1-2-2H5v3a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-3zM3 6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v12a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V6z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 348 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 21a3 3 0 0 1-3-3v-3h5a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2h5v3a3 3 0 0 1-3 3H6zm15-8h-5a2 2 0 0 0-2 2h-4a2 2 0 0 0-2-2H3V6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v7z" fill="#A7DC22"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 327 B |
1
icons/plus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h7m7 0h-7m0 0V5m0 7v7"/></svg>
|
||||
|
After Width: | Height: | Size: 222 B |
1
icons/select-all.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#A7DC22" fill-rule="evenodd" d="M10 2a3 3 0 0 0-2.83 2H6a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3h-1.17A3 3 0 0 0 14 2zM9 5a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2h-4a1 1 0 0 1-1-1m6.78 6.625a1 1 0 1 0-1.56-1.25l-3.303 4.128l-1.21-1.21a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.488-.082l4-5z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 426 B |
1
icons/select-none.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#A7DC22" fill-rule="evenodd" d="M10 2a3 3 0 0 0-2.83 2H6a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3h12a3 3 0 0 0 3-3V7a3 3 0 0 0-3-3h-1.17A3 3 0 0 0 14 2zM9 5a1 1 0 0 1 1-1h4a1 1 0 1 1 0 2h-4a1 1 0 0 1-1-1m6 8a1 1 0 1 1 0 2H9a1 1 0 1 1 0-2z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 354 B |
1
icons/select.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M8.949 2.684a1 1 0 0 0-1.898.632l1 3a1 1 0 1 0 1.898-.632l-1-3zm6.758 3.023a1 1 0 0 0-1.414-1.414l-2 2a1 1 0 0 0 1.414 1.414l2-2zM3.317 7.051a1 1 0 0 0-.633 1.898l3 1a1 1 0 1 0 .632-1.898l-3-1zm7.025 2.01a1 1 0 0 0-1.282 1.28l4 11a1 1 0 0 0 1.868.03l1.437-3.591l3.928 3.927a1 1 0 1 0 1.414-1.414l-3.928-3.928l3.592-1.436a1 1 0 0 0-.03-1.869l-11-4zm-2.635 4.646a1 1 0 1 0-1.414-1.414l-2 2a1 1 0 1 0 1.414 1.414l2-2z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 591 B |
1
icons/trash.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M11 5a1 1 0 0 0-1 1h4a1 1 0 0 0-1-1h-2zm0-2a3 3 0 0 0-3 3H4a1 1 0 0 0 0 2h1v10a3 3 0 0 0 3 3h8a3 3 0 0 0 3-3V8h1a1 1 0 1 0 0-2h-4a3 3 0 0 0-3-3h-2zm0 8a1 1 0 1 0-2 0v5a1 1 0 1 0 2 0v-5zm4 0a1 1 0 1 0-2 0v5a1 1 0 1 0 2 0v-5z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 400 B |
1
icons/undo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 9v5h5m11 2c-.497-4.5-3.367-8-8-8c-2.73 0-5.929 2.268-7.294 5.5"/></svg>
|
||||
|
After Width: | Height: | Size: 261 B |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 53 KiB |
BIN
images/firefoxact.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
@@ -12,13 +12,6 @@
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
:root[data-theme="dark-blue"] {
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
:root[data-theme="dark-green"] {
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
|
||||
@@ -12,13 +12,6 @@
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
:root[data-theme="dark-blue"] {
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
:root[data-theme="dark-green"] {
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
|
||||
@@ -104,10 +104,8 @@ async function transformTwoFactorPage() {
|
||||
|
||||
function applyTheme() {
|
||||
try {
|
||||
if (typeof getCookie === "function") {
|
||||
const theme = getCookie("theme") || "light-blue";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
}
|
||||
const theme = localStorage.getItem("themePreference") || "light-green";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(() => {
|
||||
function transformLogoutPage() {
|
||||
async function transformLogoutPage() {
|
||||
const theme =
|
||||
cookieManager.get("themePreference") ||
|
||||
await storageManager.get("themePreference", null) ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
const instituteCode = cookieManager.get("schoolSubdomain");
|
||||
const instituteCode = await storageManager.get("schoolSubdomain", null);
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
const newHTML = `
|
||||
@@ -65,8 +65,18 @@
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", transformLogoutPage);
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setTimeout(() => {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}, 100);
|
||||
transformLogoutPage();
|
||||
});
|
||||
} else {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
transformLogoutPage();
|
||||
}
|
||||
})();
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.3.2",
|
||||
"version": "1.3.5",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -12,6 +12,12 @@
|
||||
"128": "images/firka_logo_128.png"
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"storage"
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "tools/background.js"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "firxa@zan1456.hu",
|
||||
@@ -31,7 +37,8 @@
|
||||
"icons/*.svg",
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/cookieManager.js"
|
||||
"tools/storageManager.js",
|
||||
"tools/storageTest.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
@@ -52,13 +59,14 @@
|
||||
"https://*.e-kreta.hu/Adminisztracio/Profil*",
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*",
|
||||
"https://intezmenykereso.e-kreta.hu/*"
|
||||
"https://intezmenykereso.e-kreta.hu/*",
|
||||
"https://eugyintezes.e-kreta.hu/*"
|
||||
],
|
||||
"js": [
|
||||
"global/language.js",
|
||||
"global/theme.js",
|
||||
"tools/loadingScreen.js",
|
||||
"tools/cookieManager.js",
|
||||
"tools/storageManager.js",
|
||||
"tools/helper.js",
|
||||
"tools/createTemplate.js",
|
||||
"global/maintenance.js",
|
||||
@@ -181,18 +189,6 @@
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*"
|
||||
],
|
||||
"js": [
|
||||
"homework/homework.js"
|
||||
],
|
||||
"css": [
|
||||
"homework/homework.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"
|
||||
@@ -216,6 +212,19 @@
|
||||
"search/search.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://eugyintezes.e-kreta.hu/*",
|
||||
"https://eugyintezes.e-kreta.hu/"
|
||||
],
|
||||
"js": [
|
||||
"messages/messages.js"
|
||||
],
|
||||
"css": [
|
||||
"messages/messages.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
]
|
||||
}
|
||||
232
manifest_fox.json
Normal file
@@ -0,0 +1,232 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.3.4",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
},
|
||||
"action": {
|
||||
"default_popup": "settings/index.html",
|
||||
"default_icon": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"storage"
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "tools/background.js",
|
||||
"scripts": ["tools/background.js"],
|
||||
"persistent": false
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "firxa@zan1456.hu",
|
||||
"strict_min_version": "109.0",
|
||||
"data_collection_permissions": {
|
||||
"required": ["none"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": [
|
||||
"settings/*",
|
||||
"global/language.js",
|
||||
"images/*",
|
||||
"fonts/*.woff2",
|
||||
"icons/*.svg",
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/storageManager.js",
|
||||
"tools/storageTest.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Login*",
|
||||
"https://idp.e-kreta.hu/Account/Logout*",
|
||||
"https://idp.e-kreta.hu/Account/LoginWithTwoFactor*",
|
||||
"https://*.e-kreta.hu/Hianyzas/Hianyzasok*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*",
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*",
|
||||
"https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*",
|
||||
"https://*.e-kreta.hu/Orarend/InformaciokOrarend*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/Profil*",
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*",
|
||||
"https://intezmenykereso.e-kreta.hu/*",
|
||||
"https://eugyintezes.e-kreta.hu/*"
|
||||
],
|
||||
"js": [
|
||||
"global/language.js",
|
||||
"global/theme.js",
|
||||
"tools/loadingScreen.js",
|
||||
"tools/storageManager.js",
|
||||
"tools/helper.js",
|
||||
"tools/createTemplate.js",
|
||||
"global/maintenance.js",
|
||||
"global/navigation.js"
|
||||
],
|
||||
"css": [
|
||||
"tools/loadingScreen.css",
|
||||
"global/theme.css",
|
||||
"global/navigation.css",
|
||||
"global/maintenance.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Login*"
|
||||
],
|
||||
"js": [
|
||||
"login/login.js"
|
||||
],
|
||||
"css": [
|
||||
"login/login.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/account/loginwithtwofactor*"
|
||||
],
|
||||
"js": [
|
||||
"login/twofactor.js"
|
||||
],
|
||||
"css": [
|
||||
"login/twofactor.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Hianyzas/Hianyzasok*"
|
||||
],
|
||||
"js": [
|
||||
"absences/absences.js"
|
||||
],
|
||||
"css": [
|
||||
"absences/absences.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Logout*"
|
||||
],
|
||||
"js": [
|
||||
"logout/logout.js"
|
||||
],
|
||||
"css": [
|
||||
"logout/logout.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*"
|
||||
],
|
||||
"js": [
|
||||
"roleselect/roleselect.js"
|
||||
],
|
||||
"css": [
|
||||
"roleselect/roleselect.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*"
|
||||
],
|
||||
"js": [
|
||||
"dashboard/dashboard.js"
|
||||
],
|
||||
"css": [
|
||||
"dashboard/dashboard.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*"
|
||||
],
|
||||
"js": [
|
||||
"grades/grades.js",
|
||||
"grades/chart.js"
|
||||
],
|
||||
"css": [
|
||||
"grades/grades.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Orarend/InformaciokOrarend*"
|
||||
],
|
||||
"js": [
|
||||
"timetable/timetable.js"
|
||||
],
|
||||
"css": [
|
||||
"timetable/timetable.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/Profil*"
|
||||
],
|
||||
"js": [
|
||||
"profile/profile.js"
|
||||
],
|
||||
"css": [
|
||||
"profile/profile.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"
|
||||
],
|
||||
"js": [
|
||||
"forgotpassword/forgotpassword.js"
|
||||
],
|
||||
"css": [
|
||||
"forgotpassword/forgotpassword.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://intezmenykereso.e-kreta.hu/"
|
||||
],
|
||||
"js": [
|
||||
"search/search.js"
|
||||
],
|
||||
"css": [
|
||||
"search/search.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://eugyintezes.e-kreta.hu/uzenetek/",
|
||||
"https://eugyintezes.e-kreta.hu/uzenetek"
|
||||
],
|
||||
"js": [
|
||||
"messages/messages.js"
|
||||
],
|
||||
"css": [
|
||||
"messages/messages.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
]
|
||||
}
|
||||
669
messages/messages.css
Normal file
@@ -0,0 +1,669 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.messages-container {
|
||||
background-color: var(--background);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.bulk-actions-card {
|
||||
margin: 0 auto 1rem;
|
||||
max-width: 900px;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.bulk-actions-left,
|
||||
.bulk-actions-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.bulk-btn {
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.bulk-btn:hover:not(:disabled) {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.bulk-btn.active {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.bulk-btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.view-toggle {
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.view-toggle button {
|
||||
background: transparent;
|
||||
border: none;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.view-toggle button.active {
|
||||
color: var(--accent-accent);
|
||||
background: var(--accent-15);
|
||||
}
|
||||
|
||||
.bulk-btn img,
|
||||
.view-toggle button img {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.bulk-actions-card {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.bulk-actions-left,
|
||||
.bulk-actions-right {
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px;
|
||||
}
|
||||
.bulk-btn,
|
||||
.view-toggle button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.bulk-btn img,
|
||||
.view-toggle button img {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.bulk-btn,
|
||||
.view-toggle button {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
.bulk-btn img,
|
||||
.view-toggle button img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.messages-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||
gap: 1.5rem;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.messages-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.message-card {
|
||||
background-color: var(--card-card);
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.message-card.selected {
|
||||
background-color: var(--card-translucent);
|
||||
border-color: var(--accent-15);
|
||||
}
|
||||
|
||||
.message-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
border-color: var(--primary-color);
|
||||
}
|
||||
|
||||
.message-card.unread {
|
||||
border-left: 4px solid var(--accent-accent);
|
||||
}
|
||||
|
||||
.message-card.unread::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
|
||||
}
|
||||
|
||||
.message-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 1rem;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.sender-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.sender-name {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
font-size: 0.95rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.unread-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: var(--accent-accent);
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.7;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
.message-date {
|
||||
font-size: 0.8rem;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.message-subject {
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
line-height: 1.4;
|
||||
margin-bottom: 1rem;
|
||||
display: -webkit-box;
|
||||
line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.attachment-indicator {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
font-size: 1.2rem;
|
||||
color: var(--text-secondary);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 400px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 3px solid var(--border-color);
|
||||
border-top: 3px solid var(--primary-color);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.loading-content p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 400px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.empty-content {
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.empty-content h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.empty-content p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.error-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 400px;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.error-content {
|
||||
text-align: center;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.error-content h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--error-color);
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.error-content p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.retry-btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background-color: var(--primary-color);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.retry-btn:hover {
|
||||
background-color: var(--primary-hover);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
backdrop-filter: blur(4px);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
body.modal-open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
max-width: 1200px;
|
||||
width: 95%;
|
||||
max-height: 95%;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
border: 1px solid var(--background-0);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid var(--background-0);
|
||||
background: var(--background);
|
||||
border-radius: 12px 12px 0 0;
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 1.5em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
color: var(--text-secondary);
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
background: var(--background-0);
|
||||
color: var(--text-primary);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 20px;
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.modal-body iframe {
|
||||
min-height: 600px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
|
||||
border: 1px solid var(--background-0);
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #f3f3f3;
|
||||
border-top: 4px solid #1976d2;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin: 0 auto 20px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.error-content {
|
||||
text-align: center;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
.error-content h3 {
|
||||
color: #d32f2f;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.error-content p {
|
||||
color: #666;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.message-details {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.message-info {
|
||||
background-color: var(--card-card);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 20px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.info-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.info-label {
|
||||
font-weight: bold;
|
||||
min-width: 80px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
flex: 1;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.message-content h4 {
|
||||
margin: 0 0 15px 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.message-text {
|
||||
background-color: var(--card-card);
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.message-text p {
|
||||
margin: 0 0 10px 0;
|
||||
}
|
||||
|
||||
.message-text p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.message-text a {
|
||||
color: #1976d2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.message-text a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.message-attachments {
|
||||
background: #f9f9f9;
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.message-attachments h4 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #333;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.message-attachments ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.message-attachments li {
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.message-attachments a {
|
||||
color: #1976d2;
|
||||
text-decoration: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.message-attachments a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.messages-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-main {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.message-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.message-card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.message-date {
|
||||
align-self: flex-end;
|
||||
margin-top: -0.5rem;
|
||||
}
|
||||
|
||||
.sender-name {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.message-subject {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.messages-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.message-card {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.sender-name {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.message-subject {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.attachment-indicator {
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
670
messages/messages.js
Normal file
@@ -0,0 +1,670 @@
|
||||
(() => {
|
||||
async function waitForTranslations() {
|
||||
let attempts = 0;
|
||||
const maxAttempts = 200;
|
||||
while (
|
||||
(typeof window.LanguageManager === 'undefined') ||
|
||||
(window.LanguageManager && window.LanguageManager.t('navigation.dashboard') === 'navigation.dashboard')
|
||||
) {
|
||||
if (attempts++ > maxAttempts) break;
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
}
|
||||
}
|
||||
function formatDate(dateString) {
|
||||
if (!dateString) {
|
||||
return 'Ismeretlen dátum';
|
||||
}
|
||||
|
||||
const date = new Date(dateString);
|
||||
if (isNaN(date.getTime())) {
|
||||
return 'Érvénytelen dátum';
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const diffTime = Math.abs(now - date);
|
||||
const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (diffDays === 0) {
|
||||
return 'Ma';
|
||||
} else if (diffDays === 1) {
|
||||
return 'Tegnap';
|
||||
} else if (diffDays <= 7) {
|
||||
return `${diffDays} napja`;
|
||||
} else {
|
||||
return date.toLocaleDateString('hu-HU', {
|
||||
year: 'numeric',
|
||||
month: 'short',
|
||||
day: 'numeric'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeHTML(html) {
|
||||
const div = document.createElement('div');
|
||||
div.textContent = html;
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
class APIManager {
|
||||
static async fetchMessages() {
|
||||
try {
|
||||
const response = await fetch('https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/beerkezett', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '8023',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 && window.location.href.startsWith('https://eugyintezes.e-kreta.hu/uzenetek')) {
|
||||
window.location.reload();
|
||||
throw new Error('401');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching messages:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
static async fetchDeletedMessages() {
|
||||
const response = await fetch('https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/torolt', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
}
|
||||
});
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 && window.location.href.startsWith('https://eugyintezes.e-kreta.hu/uzenetek')) {
|
||||
window.location.reload();
|
||||
throw new Error('401');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
return await response.json();
|
||||
}
|
||||
|
||||
static async markMessagesRead(isRead, ids) {
|
||||
const payload = {
|
||||
isOlvasott: !!isRead,
|
||||
postaladaElemAzonositoLista: ids.map(Number)
|
||||
};
|
||||
const response = await fetch('https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/olvasott', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 && window.location.href.startsWith('https://eugyintezes.e-kreta.hu/uzenetek')) {
|
||||
window.location.reload();
|
||||
throw new Error('401');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
static async moveToTrash(ids, toTrash = true) {
|
||||
const payload = {
|
||||
isKuka: !!toTrash,
|
||||
postaladaElemAzonositoLista: ids.map(Number)
|
||||
};
|
||||
const response = await fetch('https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/kuka', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 && window.location.href.startsWith('https://eugyintezes.e-kreta.hu/uzenetek')) {
|
||||
window.location.reload();
|
||||
throw new Error('401');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function openMessageModal(messageId, isRead = true) {
|
||||
document.body.classList.add('modal-open');
|
||||
try {
|
||||
const modalOverlay = document.createElement('div');
|
||||
modalOverlay.className = 'modal-overlay';
|
||||
modalOverlay.onclick = (e) => {
|
||||
if (e.target === modalOverlay) {
|
||||
closeMessageModal();
|
||||
}
|
||||
};
|
||||
|
||||
const modalContent = document.createElement('div');
|
||||
modalContent.className = 'modal-content';
|
||||
modalContent.innerHTML = `
|
||||
<div class="modal-header">
|
||||
<h2>Üzenet részletei</h2>
|
||||
<button class="modal-close" onclick="closeMessageModal()">×</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="loading-content">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>Üzenet betöltése...</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
modalOverlay.appendChild(modalContent);
|
||||
document.body.appendChild(modalOverlay);
|
||||
|
||||
if (!isRead) {
|
||||
try {
|
||||
await markMessageAsRead(messageId);
|
||||
const cardEl = document.querySelector(`.message-card[data-id="${messageId}"]`);
|
||||
if (cardEl) {
|
||||
cardEl.classList.remove('unread');
|
||||
const indicator = cardEl.querySelector('.unread-indicator');
|
||||
if (indicator) indicator.remove();
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
const response = await fetch(`https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/${messageId}`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'Content-Length': '8023',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const messageData = await response.json();
|
||||
displayMessageDetails(modalContent, messageData);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading message details:', error);
|
||||
const modalContent = document.querySelector('.modal-content');
|
||||
if (modalContent) {
|
||||
modalContent.querySelector('.modal-body').innerHTML = `
|
||||
<div class="error-content">
|
||||
<h3>Hiba történt</h3>
|
||||
<p>Az üzenet betöltése sikertelen.</p>
|
||||
<button class="retry-btn" onclick="openMessageModal(${messageId})">Újrapróbálás</button>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function displayMessageDetails(modalContent, messageData) {
|
||||
const message = messageData.uzenet;
|
||||
const sender = message.feladoNev + (message.feladoTitulus ? ` (${message.feladoTitulus})` : '');
|
||||
const date = formatDate(message.kuldesDatum);
|
||||
const subject = message.targy || 'Nincs tárgy';
|
||||
const content = message.szoveg || 'Nincs tartalom';
|
||||
|
||||
modalContent.querySelector('.modal-body').innerHTML = `
|
||||
<div class="message-details">
|
||||
<div class="message-info">
|
||||
<div class="info-row">
|
||||
<span class="info-label">Feladó:</span>
|
||||
<span class="info-value">${sanitizeHTML(sender)}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">Dátum:</span>
|
||||
<span class="info-value">${date}</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="info-label">Tárgy:</span>
|
||||
<span class="info-value">${sanitizeHTML(subject)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<h4>Üzenet tartalma:</h4>
|
||||
<div class="message-text">${content}</div>
|
||||
</div>
|
||||
${message.csatolmanyok && message.csatolmanyok.length > 0 ? `
|
||||
<div class="message-attachments">
|
||||
<h4>Mellékletek:</h4>
|
||||
<ul>
|
||||
${message.csatolmanyok.map(attachment => `
|
||||
<li><a href="#" onclick="downloadAttachment('${attachment.azonosito}')">${sanitizeHTML(attachment.nev)}</a></li>
|
||||
`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function closeMessageModal() {
|
||||
const modalOverlay = document.querySelector('.modal-overlay');
|
||||
if (modalOverlay) {
|
||||
modalOverlay.remove();
|
||||
}
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
window.openMessageModal = openMessageModal;
|
||||
window.closeMessageModal = closeMessageModal;
|
||||
|
||||
function createLoadingState() {
|
||||
const loadingDiv = document.createElement('div');
|
||||
loadingDiv.className = 'loading-state';
|
||||
loadingDiv.innerHTML = `
|
||||
<div class="loading-content">
|
||||
<div class="loading-spinner"></div>
|
||||
<p>${LanguageManager.t('messages.loading', 'Üzenetek betöltése...')}</p>
|
||||
</div>
|
||||
`;
|
||||
return loadingDiv;
|
||||
}
|
||||
|
||||
function createErrorState(onRetry) {
|
||||
const errorDiv = document.createElement('div');
|
||||
errorDiv.className = 'error-state';
|
||||
errorDiv.innerHTML = `
|
||||
<div class="error-content">
|
||||
<h3>${LanguageManager.t('messages.error.title', 'Hiba történt')}</h3>
|
||||
<p>${LanguageManager.t('messages.error.description', 'Az üzenetek betöltése sikertelen volt.')}</p>
|
||||
<button class="retry-btn">${LanguageManager.t('messages.error.retry', 'Újrapróbálás')}</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const retryBtn = errorDiv.querySelector('.retry-btn');
|
||||
retryBtn.addEventListener('click', onRetry);
|
||||
|
||||
return errorDiv;
|
||||
}
|
||||
|
||||
function createEmptyState() {
|
||||
const emptyDiv = document.createElement('div');
|
||||
emptyDiv.className = 'empty-state';
|
||||
emptyDiv.innerHTML = `
|
||||
<div class="empty-content">
|
||||
<h3>${LanguageManager.t('messages.empty.title', 'Nincsenek üzenetek')}</h3>
|
||||
<p>${LanguageManager.t('messages.empty.description', 'Jelenleg nincsenek elérhető üzenetek.')}</p>
|
||||
</div>
|
||||
`;
|
||||
return emptyDiv;
|
||||
}
|
||||
|
||||
function createMessageCard(message) {
|
||||
const card = document.createElement('div');
|
||||
card.className = `message-card ${message.isElolvasva ? '' : 'unread'}`;
|
||||
card.dataset.id = String(message.azonosito);
|
||||
card.onclick = () => {
|
||||
if (selectionMode) {
|
||||
toggleSelect(message.azonosito, card);
|
||||
return;
|
||||
}
|
||||
openMessageModal(message.azonosito, !!message.isElolvasva);
|
||||
};
|
||||
|
||||
const senderName = message.uzenetFeladoNev || 'Ismeretlen feladó';
|
||||
const subject = message.uzenetTargy || 'Nincs tárgy';
|
||||
const date = formatDate(message.uzenetKuldesDatum);
|
||||
const hasAttachment = message.hasCsatolmany;
|
||||
|
||||
card.innerHTML = `
|
||||
<div class="message-card-header">
|
||||
<div class="sender-info">
|
||||
<span class="sender-name">${sanitizeHTML(senderName)}</span>
|
||||
${!message.isElolvasva ? '<span class="unread-indicator"></span>' : ''}
|
||||
</div>
|
||||
<div class="message-date">${date}</div>
|
||||
</div>
|
||||
<div class="message-subject">${sanitizeHTML(subject)}</div>
|
||||
${hasAttachment ? '<div class="attachment-indicator">📎</div>' : ''}
|
||||
`;
|
||||
|
||||
|
||||
return card;
|
||||
}
|
||||
|
||||
async function markMessageAsRead(messageId) {
|
||||
const payload = {
|
||||
isOlvasott: true,
|
||||
postaladaElemAzonositoLista: [Number(messageId)]
|
||||
};
|
||||
const response = await fetch('https://eugyintezes.e-kreta.hu/api/v1/kommunikacio/postaladaelemek/olvasott', {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase'
|
||||
},
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!response.ok) {
|
||||
if (response.status === 401 && window.location.href.startsWith('https://eugyintezes.e-kreta.hu/uzenetek')) {
|
||||
window.location.reload();
|
||||
throw new Error('401');
|
||||
}
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
}
|
||||
|
||||
function createMessagesGrid(messages) {
|
||||
const gridContainer = document.createElement('div');
|
||||
gridContainer.className = 'messages-grid';
|
||||
|
||||
if (messages.length === 0) {
|
||||
return createEmptyState();
|
||||
}
|
||||
|
||||
messages.forEach(message => {
|
||||
const messageCard = createMessageCard(message);
|
||||
gridContainer.appendChild(messageCard);
|
||||
});
|
||||
|
||||
return gridContainer;
|
||||
}
|
||||
|
||||
let currentView = 'inbox';
|
||||
let selectionMode = false;
|
||||
const selection = new Set();
|
||||
|
||||
function renderBulkActions(container) {
|
||||
const bulk = document.createElement('div');
|
||||
bulk.className = 'bulk-actions-card';
|
||||
bulk.innerHTML = `
|
||||
<div class="bulk-actions-left">
|
||||
<div class="view-toggle">
|
||||
<button id="viewInboxBtn" class="${currentView==='inbox'?'active':''}" title="Beérkezett">
|
||||
<img src="${chrome.runtime.getURL('icons/messages-active.svg')}" alt="Beérkezett">
|
||||
</button>
|
||||
<button id="viewTrashBtn" class="${currentView==='trash'?'active':''}" title="Törölt">
|
||||
<img src="${chrome.runtime.getURL('icons/delete.svg')}" alt="Törölt">
|
||||
</button>
|
||||
</div>
|
||||
<button id="toggleSelectionModeBtn" class="bulk-btn" title="Kijelölés mód">
|
||||
<img src="${chrome.runtime.getURL('icons/select.svg')}" alt="Kijelölés mód">
|
||||
</button>
|
||||
<button id="selectAllBtn" class="bulk-btn" title="Mind kijelöl">
|
||||
<img src="${chrome.runtime.getURL('icons/select-all.svg')}" alt="Mind kijelöl">
|
||||
</button>
|
||||
<button id="clearSelectionBtn" class="bulk-btn" title="Kijelölés törlése">
|
||||
<img src="${chrome.runtime.getURL('icons/select-none.svg')}" alt="Kijelölés törlése">
|
||||
</button>
|
||||
</div>
|
||||
<div class="bulk-actions-right">
|
||||
<button id="markReadBtn" class="bulk-btn" title="Olvasott">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-on.svg')}" alt="Olvasott">
|
||||
</button>
|
||||
<button id="markUnreadBtn" class="bulk-btn" title="Olvasatlan">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-off.svg')}" alt="Olvasatlan">
|
||||
</button>
|
||||
<button id="deleteBtn" class="bulk-btn" title="Törlés">
|
||||
<img src="${chrome.runtime.getURL('icons/trash.svg')}" alt="Törlés">
|
||||
</button>
|
||||
<button id="restoreBtn" class="bulk-btn" title="Visszaállítás">
|
||||
<img src="${chrome.runtime.getURL('icons/undo.svg')}" alt="Visszaállítás">
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(bulk);
|
||||
|
||||
bulk.querySelector('#viewInboxBtn').addEventListener('click', () => switchView('inbox'));
|
||||
bulk.querySelector('#viewTrashBtn').addEventListener('click', () => switchView('trash'));
|
||||
bulk.querySelector('#toggleSelectionModeBtn').addEventListener('click', toggleSelectionMode);
|
||||
bulk.querySelector('#selectAllBtn').addEventListener('click', selectAllVisible);
|
||||
bulk.querySelector('#clearSelectionBtn').addEventListener('click', clearSelection);
|
||||
bulk.querySelector('#markReadBtn').addEventListener('click', () => bulkMark(true));
|
||||
bulk.querySelector('#markUnreadBtn').addEventListener('click', () => bulkMark(false));
|
||||
bulk.querySelector('#deleteBtn').addEventListener('click', bulkDelete);
|
||||
bulk.querySelector('#restoreBtn').addEventListener('click', bulkRestore);
|
||||
updateBulkActionsState();
|
||||
}
|
||||
|
||||
function updateBulkActionsState() {
|
||||
const ids = Array.from(selection);
|
||||
const bulk = document.querySelector('.bulk-actions-card');
|
||||
if (!bulk) return;
|
||||
const disableAll = ids.length === 0;
|
||||
bulk.querySelector('#markReadBtn').disabled = disableAll || currentView !== 'inbox';
|
||||
bulk.querySelector('#markUnreadBtn').disabled = disableAll || currentView !== 'inbox';
|
||||
bulk.querySelector('#deleteBtn').disabled = disableAll || currentView !== 'inbox';
|
||||
bulk.querySelector('#restoreBtn').disabled = disableAll || currentView !== 'trash';
|
||||
}
|
||||
|
||||
function selectAllVisible() {
|
||||
const cards = document.querySelectorAll('.messages-grid .message-card');
|
||||
cards.forEach(card => {
|
||||
const id = parseInt(card.dataset.id);
|
||||
selection.add(id);
|
||||
card.classList.add('selected');
|
||||
});
|
||||
updateBulkActionsState();
|
||||
}
|
||||
|
||||
function clearSelection() {
|
||||
selection.clear();
|
||||
document.querySelectorAll('.messages-grid .message-card.selected').forEach(card => card.classList.remove('selected'));
|
||||
updateBulkActionsState();
|
||||
}
|
||||
|
||||
function toggleSelect(id, card) {
|
||||
if (selection.has(id)) {
|
||||
selection.delete(id);
|
||||
card.classList.remove('selected');
|
||||
} else {
|
||||
selection.add(id);
|
||||
card.classList.add('selected');
|
||||
}
|
||||
updateBulkActionsState();
|
||||
}
|
||||
|
||||
function toggleSelectionMode() {
|
||||
selectionMode = !selectionMode;
|
||||
const btn = document.getElementById('toggleSelectionModeBtn');
|
||||
if (btn) {
|
||||
btn.classList.toggle('active', selectionMode);
|
||||
btn.title = selectionMode ? 'Kilépés kijelölésből' : 'Kijelölés mód';
|
||||
}
|
||||
if (!selectionMode) {
|
||||
clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
async function bulkMark(isRead) {
|
||||
const ids = Array.from(selection);
|
||||
if (ids.length === 0) return;
|
||||
await APIManager.markMessagesRead(isRead, ids);
|
||||
ids.forEach(id => {
|
||||
const card = document.querySelector(`.message-card[data-id="${id}"]`);
|
||||
if (!card) return;
|
||||
if (isRead) {
|
||||
card.classList.remove('unread');
|
||||
const ind = card.querySelector('.unread-indicator');
|
||||
if (ind) ind.remove();
|
||||
} else {
|
||||
card.classList.add('unread');
|
||||
if (!card.querySelector('.unread-indicator')) {
|
||||
const senderInfo = card.querySelector('.sender-info');
|
||||
const span = document.createElement('span');
|
||||
span.className = 'unread-indicator';
|
||||
senderInfo.appendChild(span);
|
||||
}
|
||||
}
|
||||
});
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
async function bulkDelete() {
|
||||
const ids = Array.from(selection);
|
||||
if (ids.length === 0) return;
|
||||
await APIManager.moveToTrash(ids, true);
|
||||
ids.forEach(id => {
|
||||
const card = document.querySelector(`.message-card[data-id="${id}"]`);
|
||||
if (card) card.remove();
|
||||
});
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
async function bulkRestore() {
|
||||
const ids = Array.from(selection);
|
||||
if (ids.length === 0) return;
|
||||
await APIManager.moveToTrash(ids, false);
|
||||
ids.forEach(id => {
|
||||
const card = document.querySelector(`.message-card[data-id="${id}"]`);
|
||||
if (card) card.remove();
|
||||
});
|
||||
clearSelection();
|
||||
}
|
||||
|
||||
async function switchView(view) {
|
||||
if (currentView === view) return;
|
||||
currentView = view;
|
||||
if (selectionMode) toggleSelectionMode();
|
||||
clearSelection();
|
||||
const container = document.querySelector('.messages-container');
|
||||
const grid = container.querySelector('.messages-grid') || container.querySelector('.empty-state') || container.querySelector('.error-state');
|
||||
if (grid) grid.remove();
|
||||
const toggleInbox = document.getElementById('viewInboxBtn');
|
||||
const toggleTrash = document.getElementById('viewTrashBtn');
|
||||
if (toggleInbox && toggleTrash) {
|
||||
toggleInbox.classList.toggle('active', currentView==='inbox');
|
||||
toggleTrash.classList.toggle('active', currentView==='trash');
|
||||
}
|
||||
const loadingState = createLoadingState();
|
||||
container.appendChild(loadingState);
|
||||
if (view === 'inbox') {
|
||||
await loadMessages(container);
|
||||
} else {
|
||||
await loadDeleted(container);
|
||||
}
|
||||
}
|
||||
|
||||
async function transformMessagesPage() {
|
||||
try {
|
||||
await waitForTranslations();
|
||||
document.body.innerHTML = '';
|
||||
const kretaContainer = document.createElement('div');
|
||||
kretaContainer.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(headerDiv);
|
||||
|
||||
const main = document.createElement('main');
|
||||
main.className = 'kreta-main';
|
||||
|
||||
const messagesContainer = document.createElement('div');
|
||||
messagesContainer.className = 'messages-container';
|
||||
|
||||
renderBulkActions(main);
|
||||
const loadingState = createLoadingState();
|
||||
messagesContainer.appendChild(loadingState);
|
||||
|
||||
main.appendChild(messagesContainer);
|
||||
kretaContainer.appendChild(main);
|
||||
document.body.appendChild(kretaContainer);
|
||||
|
||||
if (typeof setupUserDropdown === 'function') {
|
||||
setupUserDropdown();
|
||||
}
|
||||
if (typeof setupMobileNavigation === 'function') {
|
||||
setupMobileNavigation();
|
||||
}
|
||||
|
||||
await loadMessages(messagesContainer);
|
||||
|
||||
loadingScreen.hide();
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error transforming messages page:', error);
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}
|
||||
|
||||
async function loadMessages(container) {
|
||||
try {
|
||||
const messages = await APIManager.fetchMessages();
|
||||
|
||||
messages.sort((a, b) => {
|
||||
const dateA = new Date(a.uzenetKuldesDatum);
|
||||
const dateB = new Date(b.uzenetKuldesDatum);
|
||||
return dateB - dateA;
|
||||
});
|
||||
|
||||
const loadingState = container.querySelector('.loading-state');
|
||||
if (loadingState) {
|
||||
loadingState.remove();
|
||||
}
|
||||
|
||||
const messagesGrid = createMessagesGrid(messages);
|
||||
container.appendChild(messagesGrid);
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading messages:', error);
|
||||
|
||||
const loadingState = container.querySelector('.loading-state');
|
||||
if (loadingState) {
|
||||
loadingState.remove();
|
||||
}
|
||||
|
||||
const errorState = createErrorState(() => loadMessages(container));
|
||||
container.appendChild(errorState);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDeleted(container) {
|
||||
try {
|
||||
const messages = await APIManager.fetchDeletedMessages();
|
||||
messages.sort((a, b) => {
|
||||
const dateA = new Date(a.uzenetKuldesDatum);
|
||||
const dateB = new Date(b.uzenetKuldesDatum);
|
||||
return dateB - dateA;
|
||||
});
|
||||
const loadingState = container.querySelector('.loading-state');
|
||||
if (loadingState) {
|
||||
loadingState.remove();
|
||||
}
|
||||
const messagesGrid = createMessagesGrid(messages);
|
||||
container.appendChild(messagesGrid);
|
||||
} catch (error) {
|
||||
const loadingState = container.querySelector('.loading-state');
|
||||
if (loadingState) {
|
||||
loadingState.remove();
|
||||
}
|
||||
const errorState = createErrorState(() => loadDeleted(container));
|
||||
container.appendChild(errorState);
|
||||
}
|
||||
}
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', transformMessagesPage);
|
||||
} else {
|
||||
transformMessagesPage();
|
||||
}
|
||||
})();
|
||||
@@ -187,7 +187,7 @@ body {
|
||||
.logout-card:active {
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--error-shadow);
|
||||
}
|
||||
:root[data-theme="light-blue"] .role-card:hover,:root[data-theme="light-green"] .role-card:hover {
|
||||
:root[data-theme="light-green"] .role-card:hover {
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
@@ -253,10 +253,14 @@ to {
|
||||
}
|
||||
.side-roles {
|
||||
grid-template-columns:1fr;
|
||||
gap:1rem;
|
||||
gap:0.75rem;
|
||||
}
|
||||
.role-card {
|
||||
padding:1.5rem;
|
||||
padding:1rem;
|
||||
gap:1rem;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:200px;
|
||||
}
|
||||
.role-icon {
|
||||
width:40px;
|
||||
@@ -267,9 +271,53 @@ to {
|
||||
height:24px;
|
||||
}
|
||||
.role-text {
|
||||
font-size:1.2rem;
|
||||
font-size:1.5rem;
|
||||
}
|
||||
.role-description {
|
||||
font-size:1rem;
|
||||
font-size:1.2rem;
|
||||
}
|
||||
.user-name {
|
||||
font-size:18px;
|
||||
}
|
||||
.logout-timer {
|
||||
font-size:16px;
|
||||
}
|
||||
}
|
||||
@media (max-width:480px) {
|
||||
.kreta-container {
|
||||
padding:0.75rem;
|
||||
}
|
||||
.kreta-header {
|
||||
margin-bottom:1.5rem;
|
||||
}
|
||||
.side-roles {
|
||||
gap:0.5rem;
|
||||
}
|
||||
.role-card {
|
||||
padding:0.75rem;
|
||||
gap:0.75rem;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:160px;
|
||||
}
|
||||
.role-text {
|
||||
font-size:1.6rem;
|
||||
line-height:1.2;
|
||||
}
|
||||
.role-description {
|
||||
font-size:1.3rem;
|
||||
line-height:1.3;
|
||||
}
|
||||
.user-name {
|
||||
font-size:20px;
|
||||
}
|
||||
.logout-timer {
|
||||
font-size:18px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:0.9rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:1.1rem;
|
||||
}
|
||||
}
|
||||
@@ -120,12 +120,12 @@
|
||||
userNameEl?.textContent.trim() || LanguageManager.t("common.username");
|
||||
|
||||
if (schoolCode && fullSchoolName) {
|
||||
cookieManager.set("schoolCode", schoolCode);
|
||||
cookieManager.set("schoolName", fullSchoolName);
|
||||
cookieManager.set("schoolSubdomain", schoolSubdomain);
|
||||
await storageManager.set("schoolCode", schoolCode);
|
||||
await storageManager.set("schoolName", fullSchoolName);
|
||||
await storageManager.set("schoolSubdomain", schoolSubdomain);
|
||||
}
|
||||
if (userName) {
|
||||
cookieManager.set("userName", userName);
|
||||
await storageManager.set("userName", userName);
|
||||
}
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
|
||||
@@ -126,9 +126,11 @@ form {
|
||||
li.dropdown-item:hover,li.dropdown-item:focus {
|
||||
background-color:var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
text-decoration:none !important;
|
||||
}
|
||||
a.dropdown-item:hover,a.dropdown-item:focus {
|
||||
background-color:#00000000 !important;
|
||||
text-decoration:none !important;
|
||||
}
|
||||
.dropdown-item.active {
|
||||
background-color:var(--accent-accent) !important;
|
||||
|
||||
@@ -20,10 +20,10 @@ if (
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
}
|
||||
|
||||
function applyFirkaStyling() {
|
||||
async function applyFirkaStyling() {
|
||||
try {
|
||||
const theme =
|
||||
cookieManager.get("themePreference") ||
|
||||
await storageManager.get("themePreference") ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
@@ -68,8 +68,19 @@ h2 {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
font-weight:600;
|
||||
font-size:16px;
|
||||
color:var(--text-primary);
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
.custom-theme-editor .setting-header {
|
||||
justify-content:space-between;
|
||||
}
|
||||
|
||||
.setting-header > div:first-child {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
}
|
||||
.theme-grid,.language-grid {
|
||||
display:grid;
|
||||
@@ -140,16 +151,9 @@ h2 {
|
||||
color:var(--text-primary);
|
||||
font-size:12px;
|
||||
font-weight:500;
|
||||
font-family: "Montserrat", serif;
|
||||
}
|
||||
.theme-preview.light-blue {
|
||||
background:#DAE4F7;
|
||||
}
|
||||
.theme-preview.light-blue .preview-header {
|
||||
background:#EDF3FF;
|
||||
}
|
||||
.theme-preview.light-blue .preview-card {
|
||||
background:#FBFCFF;
|
||||
}
|
||||
|
||||
.theme-preview.light-green {
|
||||
background:#FAFFF0;
|
||||
}
|
||||
@@ -159,15 +163,7 @@ h2 {
|
||||
.theme-preview.light-green .preview-card {
|
||||
background:#FEFFFD;
|
||||
}
|
||||
.theme-preview.dark-blue {
|
||||
background:#070A0E;
|
||||
}
|
||||
.theme-preview.dark-blue .preview-header {
|
||||
background:#0F131B;
|
||||
}
|
||||
.theme-preview.dark-blue .preview-card {
|
||||
background:#131822;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green {
|
||||
background:#0D1202;
|
||||
}
|
||||
@@ -201,7 +197,14 @@ h2 {
|
||||
.about-content p,.support-content p {
|
||||
margin-bottom:12px;
|
||||
}
|
||||
.github-link {
|
||||
.about-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.about-link {
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
@@ -209,8 +212,10 @@ h2 {
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
transition:color 0.2s;
|
||||
padding: 4px 0;
|
||||
}
|
||||
.github-link:hover {
|
||||
|
||||
.about-link:hover {
|
||||
color:var(--accent-secondary);
|
||||
}
|
||||
.support-buttons {
|
||||
@@ -243,6 +248,357 @@ h2 {
|
||||
.version-info {
|
||||
color:var(--text-secondary);
|
||||
font-size:12px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.theme-editor-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.icon-btn {
|
||||
background: var(--button-secondaryFill);
|
||||
border: none !important;
|
||||
border-radius: 8px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.icon-btn:hover {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.icon-btn .material-icons-round {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.btn-primary, .btn-secondary {
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--accent-secondary);
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
border: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.btn-secondary:hover {
|
||||
background: var(--accent-15);
|
||||
}
|
||||
|
||||
.custom-themes-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.custom-theme-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.custom-theme-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.custom-theme-preview-mini {
|
||||
width: 40px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.custom-theme-preview-mini .color-strip {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.custom-theme-name {
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.custom-theme-actions {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
padding: 6px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background: var(--accent-15);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
transition: background 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.action-btn .material-icons-round {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.action-btn:hover {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.action-btn.delete:hover {
|
||||
background: var(--error-accent);
|
||||
}
|
||||
|
||||
.theme-editor-modal, .import-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.modal-header h3 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.close-modal {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.close-modal:hover {
|
||||
background: var(--accent-15);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: flex-end;
|
||||
padding: 16px;
|
||||
border-top: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.theme-name-input {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.theme-name-input label {
|
||||
display: block;
|
||||
margin-bottom: 4px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-name-input input {
|
||||
width: 100%;
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
.color-groups {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.color-group h4 {
|
||||
margin: 0 0 12px 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.color-inputs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.color-input-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.color-input-group label {
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.color-input-group input[type="color"] {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
background: var(--card-card);
|
||||
cursor: pointer;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.color-input-group input[type="color"]::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.color-input-group input[type="color"]::-webkit-color-swatch {
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.theme-preview-container h4 {
|
||||
margin: 0 0 12px 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.custom-theme-preview {
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
height: 120px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.custom-theme-preview .preview-header {
|
||||
height: 30px;
|
||||
background: var(--preview-background, var(--background));
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.custom-theme-preview .preview-content {
|
||||
padding: 12px;
|
||||
background: var(--preview-background, var(--background));
|
||||
}
|
||||
|
||||
.custom-theme-preview .preview-card {
|
||||
background: var(--preview-card, var(--card-card));
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.preview-text-primary {
|
||||
color: var(--preview-text-primary, var(--text-primary));
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.preview-text-secondary {
|
||||
color: var(--preview-text-secondary, var(--text-secondary));
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.preview-accent {
|
||||
background: var(--preview-accent, var(--accent-accent));
|
||||
color: white;
|
||||
padding: 6px 12px;
|
||||
border-radius: 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
display: inline-block;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.import-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.import-input label {
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.import-input textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
}
|
||||
.material-icons-round {
|
||||
font-size:18px;
|
||||
|
||||
@@ -31,15 +31,6 @@
|
||||
<span data-i18n="settings.theme">Téma</span>
|
||||
</div>
|
||||
<div class="theme-grid">
|
||||
<button class="theme-option" data-theme="default">
|
||||
<div class="theme-preview light-blue">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name" data-i18n="settings.themes.light_blue">Világos Kék</span>
|
||||
</button>
|
||||
<button class="theme-option" data-theme="light-green">
|
||||
<div class="theme-preview light-green">
|
||||
<div class="preview-header"></div>
|
||||
@@ -49,15 +40,7 @@
|
||||
</div>
|
||||
<span class="theme-name" data-i18n="settings.themes.light_green">Világos Zöld</span>
|
||||
</button>
|
||||
<button class="theme-option" data-theme="dark-blue">
|
||||
<div class="theme-preview dark-blue">
|
||||
<div class="preview-header"></div>
|
||||
<div class="preview-content">
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name" data-i18n="settings.themes.dark_blue">Sötét Kék</span>
|
||||
</button>
|
||||
|
||||
<button class="theme-option" data-theme="dark-green">
|
||||
<div class="theme-preview dark-green">
|
||||
<div class="preview-header"></div>
|
||||
@@ -69,7 +52,128 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="setting-section">
|
||||
<div class="setting-header">
|
||||
<div>
|
||||
<span class="material-icons-round">brush</span>
|
||||
<span data-i18n="settings.custom_theme.title">Egyéni Téma</span>
|
||||
</div>
|
||||
<div class="theme-editor-controls">
|
||||
<button class="icon-btn" id="createCustomTheme" title="Új Téma Létrehozása">
|
||||
<span class="material-icons-round">add</span>
|
||||
</button>
|
||||
<button class="icon-btn" id="importTheme" title="Téma Importálása">
|
||||
<span class="material-icons-round">file_download</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="custom-theme-editor">
|
||||
|
||||
<div class="custom-themes-list" id="customThemesList">
|
||||
</div>
|
||||
|
||||
<div class="theme-editor-modal" id="themeEditorModal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 data-i18n="settings.custom_theme.editor_title">Téma Szerkesztő</h3>
|
||||
<button class="close-modal" id="closeThemeEditor">
|
||||
<span class="material-icons-round">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="theme-name-input">
|
||||
<label for="themeName" data-i18n="settings.custom_theme.name">Téma neve:</label>
|
||||
<input type="text" id="themeName" placeholder="Saját téma" maxlength="30">
|
||||
</div>
|
||||
|
||||
<div class="color-groups">
|
||||
<div class="color-group">
|
||||
<h4 data-i18n="settings.custom_theme.background">Háttér</h4>
|
||||
<div class="color-inputs">
|
||||
<div class="color-input-group">
|
||||
<label for="background" data-i18n="settings.custom_theme.main_background">Fő háttér:</label>
|
||||
<input type="color" id="background" value="#DAE4F7">
|
||||
</div>
|
||||
<div class="color-input-group">
|
||||
<label for="cardCard" data-i18n="settings.custom_theme.card_background">Kártya háttér:</label>
|
||||
<input type="color" id="cardCard" value="#EDF3FF">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h4 data-i18n="settings.custom_theme.text">Szöveg</h4>
|
||||
<div class="color-inputs">
|
||||
<div class="color-input-group">
|
||||
<label for="textPrimary" data-i18n="settings.custom_theme.primary_text">Elsődleges szöveg:</label>
|
||||
<input type="color" id="textPrimary" value="#050B15">
|
||||
</div>
|
||||
<div class="color-input-group">
|
||||
<label for="textSecondary" data-i18n="settings.custom_theme.secondary_text">Másodlagos szöveg:</label>
|
||||
<input type="color" id="textSecondary" value="#050B15">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="color-group">
|
||||
<h4 data-i18n="settings.custom_theme.accent">Kiemelő színek</h4>
|
||||
<div class="color-inputs">
|
||||
<div class="color-input-group">
|
||||
<label for="accentAccent" data-i18n="settings.custom_theme.primary_accent">Elsődleges kiemelő:</label>
|
||||
<input type="color" id="accentAccent" value="#3673EE">
|
||||
</div>
|
||||
<div class="color-input-group">
|
||||
<label for="accentSecondary" data-i18n="settings.custom_theme.secondary_accent">Másodlagos kiemelő:</label>
|
||||
<input type="color" id="accentSecondary" value="#1C469A">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="theme-preview-container">
|
||||
<h4 data-i18n="settings.custom_theme.preview">Előnézet</h4>
|
||||
<div class="custom-theme-preview" id="customThemePreview">
|
||||
<div class="preview-content">
|
||||
<div class="preview-card">
|
||||
<div class="preview-text-primary">Elsődleges szöveg</div>
|
||||
<div class="preview-text-secondary">Másodlagos szöveg</div>
|
||||
<div class="preview-accent">Kiemelő szín</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-secondary" id="cancelThemeEdit" data-i18n="settings.custom_theme.cancel">Mégse</button>
|
||||
<button class="btn-primary" id="saveTheme" data-i18n="settings.custom_theme.save">Mentés</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="import-modal" id="importModal" style="display: none;">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h3 data-i18n="settings.custom_theme.import_title">Téma Importálása</h3>
|
||||
<button class="close-modal" id="closeImportModal">
|
||||
<span class="material-icons-round">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="import-input">
|
||||
<label for="themeImportString" data-i18n="settings.custom_theme.import_string">Téma azonosítója:</label>
|
||||
<textarea id="themeImportString" placeholder="Illeszd be ide a téma azonosítóját..." rows="4"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-secondary" id="cancelImport" data-i18n="settings.custom_theme.cancel">Mégse</button>
|
||||
<button class="btn-primary" id="confirmImport" data-i18n="settings.custom_theme.import">Importálás</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="setting-section">
|
||||
<div class="setting-header">
|
||||
<span class="material-icons-round">language</span>
|
||||
@@ -91,10 +195,20 @@
|
||||
<h2 data-i18n="settings.about.title">Névjegy</h2>
|
||||
<div class="about-content">
|
||||
<p data-i18n="settings.about.description">A Firka egy nyílt forráskódú projekt, amely a KRÉTA rendszerhez készít saját felhasználói felületet.</p>
|
||||
<a href="https://github.com/QwIT-Development/" target="_blank" class="github-link">
|
||||
<span class="material-icons-round">code</span>
|
||||
<span data-i18n="settings.about.github">GitHub</span>
|
||||
</a>
|
||||
<div class="about-links">
|
||||
<a href="https://firka.app" target="_blank" class="about-link">
|
||||
<span class="material-icons-round">language</span>
|
||||
<span>Weboldal</span>
|
||||
</a>
|
||||
<a href="https://github.com/QwIT-Development/" target="_blank" class="about-link">
|
||||
<span class="material-icons-round">code</span>
|
||||
<span data-i18n="settings.about.github">GitHub</span>
|
||||
</a>
|
||||
<a href="https://discord.gg/firka-1111649116020285532" target="_blank" class="about-link">
|
||||
<span class="material-icons-round">forum</span>
|
||||
<span>Discord</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -112,10 +226,10 @@
|
||||
</div>
|
||||
|
||||
<footer class="popup-footer">
|
||||
<div class="version-info" id="version">v1.1.0</div>
|
||||
<div class="version-info" id="version">v1.3.0</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="../tools/cookieManager.js"></script>
|
||||
<script src="../tools/storageManager.js"></script>
|
||||
<script src="../global/language.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
|
||||
@@ -3,66 +3,9 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
function isThemeDisabled(theme) {
|
||||
const blueThemesUnlocked =
|
||||
localStorage.getItem("blueThemesUnlocked") === "true";
|
||||
return (
|
||||
(theme === "default" ||
|
||||
theme === "light-blue" ||
|
||||
theme === "dark-blue") &&
|
||||
!blueThemesUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
function updateThemeAvailability() {
|
||||
const blueThemesUnlocked =
|
||||
localStorage.getItem("blueThemesUnlocked") === "true";
|
||||
document.querySelectorAll(".theme-option").forEach((button) => {
|
||||
const theme = button.dataset.theme;
|
||||
if (
|
||||
theme === "default" ||
|
||||
theme === "light-blue" ||
|
||||
theme === "dark-blue"
|
||||
) {
|
||||
if (blueThemesUnlocked) {
|
||||
button.style.display = "block";
|
||||
button.classList.remove("disabled");
|
||||
button.removeAttribute("disabled");
|
||||
} else {
|
||||
button.style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(";");
|
||||
|
||||
for (let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === " ") {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setCookie(name, value, days = 365) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
}
|
||||
|
||||
function getCurrentTheme() {
|
||||
return (
|
||||
localStorage.getItem("themePreference") ||
|
||||
getCookie("themePreference") ||
|
||||
"light-green"
|
||||
);
|
||||
}
|
||||
@@ -72,13 +15,12 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle("active", theme === currentTheme);
|
||||
});
|
||||
updateThemeAvailability();
|
||||
|
||||
}
|
||||
|
||||
function getCurrentLanguage() {
|
||||
return (
|
||||
localStorage.getItem("languagePreference") ||
|
||||
getCookie("languagePreference") ||
|
||||
"hu"
|
||||
);
|
||||
}
|
||||
@@ -91,7 +33,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
|
||||
async function applyLanguage(language) {
|
||||
setCookie("languagePreference", language);
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
updateLanguageButtons(language);
|
||||
@@ -108,7 +49,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
|
||||
async function applyTheme(theme) {
|
||||
setCookie("themePreference", theme);
|
||||
localStorage.setItem("themePreference", theme);
|
||||
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
@@ -154,11 +94,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
let initialTheme = getCurrentTheme();
|
||||
|
||||
if (isThemeDisabled(initialTheme)) {
|
||||
initialTheme = "light-green";
|
||||
}
|
||||
|
||||
updateThemeAvailability();
|
||||
await applyTheme(initialTheme);
|
||||
|
||||
const initialLanguage = getCurrentLanguage();
|
||||
@@ -175,53 +110,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
const versionElement = document.getElementById("version");
|
||||
versionElement.textContent = `v${manifest.version}`;
|
||||
|
||||
let clickCount = 0;
|
||||
versionElement.addEventListener("click", () => {
|
||||
clickCount++;
|
||||
if (clickCount >= 5) {
|
||||
localStorage.setItem("blueThemesUnlocked", "true");
|
||||
updateThemeAvailability();
|
||||
|
||||
const notification = document.createElement("div");
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
padding: 12px 20px;
|
||||
border-radius: 8px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 500;
|
||||
z-index: 10000;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
animation: slideIn 0.3s ease-out;
|
||||
`;
|
||||
notification.textContent =
|
||||
window.LanguageManager.t("common.success") +
|
||||
": " +
|
||||
window.LanguageManager.t("settings.blue_themes_unlocked");
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
@keyframes slideIn {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
style.remove();
|
||||
}, 3000);
|
||||
|
||||
clickCount = 0;
|
||||
}
|
||||
});
|
||||
|
||||
themeButtons.forEach((button) => {
|
||||
button.addEventListener("mouseover", () => {
|
||||
if (!button.hasAttribute("disabled")) {
|
||||
@@ -247,4 +135,436 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
window.addEventListener("languageChanged", (event) => {
|
||||
updateLanguageButtons(event.detail.language);
|
||||
});
|
||||
|
||||
class CustomThemeManager {
|
||||
constructor() {
|
||||
this.customThemes = this.loadCustomThemes();
|
||||
this.currentEditingTheme = null;
|
||||
this.initializeEventListeners();
|
||||
this.renderCustomThemes();
|
||||
}
|
||||
|
||||
loadCustomThemes() {
|
||||
const stored = localStorage.getItem('customThemes');
|
||||
return stored ? JSON.parse(stored) : [];
|
||||
}
|
||||
|
||||
saveCustomThemes() {
|
||||
localStorage.setItem('customThemes', JSON.stringify(this.customThemes));
|
||||
}
|
||||
|
||||
generateThemeId() {
|
||||
const existingIds = this.customThemes.map(theme => theme.id);
|
||||
let counter = 1;
|
||||
let id;
|
||||
|
||||
do {
|
||||
id = 'custom-' + counter;
|
||||
counter++;
|
||||
} while (existingIds.includes(id));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
createTheme(name, colors) {
|
||||
const theme = {
|
||||
id: this.generateThemeId(),
|
||||
name: name,
|
||||
colors: colors,
|
||||
created: new Date().toISOString()
|
||||
};
|
||||
this.customThemes.push(theme);
|
||||
this.saveCustomThemes();
|
||||
return theme;
|
||||
}
|
||||
|
||||
updateTheme(id, name, colors) {
|
||||
const index = this.customThemes.findIndex(t => t.id === id);
|
||||
if (index !== -1) {
|
||||
this.customThemes[index] = {
|
||||
...this.customThemes[index],
|
||||
name: name,
|
||||
colors: colors,
|
||||
updated: new Date().toISOString()
|
||||
};
|
||||
this.saveCustomThemes();
|
||||
return this.customThemes[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
deleteTheme(id) {
|
||||
this.customThemes = this.customThemes.filter(t => t.id !== id);
|
||||
this.saveCustomThemes();
|
||||
|
||||
const currentTheme = getCurrentTheme();
|
||||
if (currentTheme === id) {
|
||||
this.applyTheme('light-green');
|
||||
}
|
||||
}
|
||||
|
||||
applyTheme(themeId) {
|
||||
if (themeId.startsWith('custom-')) {
|
||||
const theme = this.customThemes.find(t => t.id === themeId);
|
||||
if (theme) {
|
||||
this.applyCustomThemeColors(theme.colors);
|
||||
localStorage.setItem("themePreference", themeId);
|
||||
}
|
||||
} else {
|
||||
document.documentElement.setAttribute('data-theme', themeId);
|
||||
localStorage.setItem("themePreference", themeId);
|
||||
}
|
||||
updateThemeButtons(themeId);
|
||||
}
|
||||
|
||||
applyCustomThemeColors(colors) {
|
||||
const root = document.documentElement;
|
||||
root.removeAttribute('data-theme');
|
||||
Object.entries(colors).forEach(([key, value]) => {
|
||||
const cssVar = this.convertToCSSVariable(key);
|
||||
root.style.setProperty(cssVar, value);
|
||||
});
|
||||
}
|
||||
|
||||
convertToCSSVariable(key) {
|
||||
return '--' + key.replace(/([A-Z])/g, '-$1').toLowerCase();
|
||||
}
|
||||
|
||||
exportTheme(themeId) {
|
||||
const theme = this.customThemes.find(t => t.id === themeId);
|
||||
if (!theme) return null;
|
||||
|
||||
const colors = theme.colors;
|
||||
const colorString = [
|
||||
colors.background.substring(1),
|
||||
colors.cardCard.substring(1),
|
||||
colors.textPrimary.substring(1),
|
||||
colors.textSecondary.substring(1),
|
||||
colors.accentAccent.substring(1),
|
||||
colors.accentSecondary.substring(1)
|
||||
].join('');
|
||||
|
||||
return theme.name + '|' + colorString;
|
||||
}
|
||||
|
||||
importTheme(themeString) {
|
||||
try {
|
||||
const parts = themeString.split('|');
|
||||
if (parts.length !== 2) {
|
||||
throw new Error('Invalid theme format - expected name|colors');
|
||||
}
|
||||
|
||||
const [themeName, colorString] = parts;
|
||||
if (colorString.length !== 36) {
|
||||
throw new Error('Invalid theme format - expected 36 hex characters');
|
||||
}
|
||||
|
||||
const hexPattern = /^[0-9A-Fa-f]{36}$/;
|
||||
if (!hexPattern.test(colorString)) {
|
||||
throw new Error('Invalid hex color format');
|
||||
}
|
||||
|
||||
const colors = [];
|
||||
for (let i = 0; i < 36; i += 6) {
|
||||
colors.push(colorString.substring(i, i + 6));
|
||||
}
|
||||
|
||||
const themeColors = {
|
||||
background: '#' + colors[0],
|
||||
cardCard: '#' + colors[1],
|
||||
textPrimary: '#' + colors[2],
|
||||
textSecondary: '#' + colors[3],
|
||||
accentAccent: '#' + colors[4],
|
||||
accentSecondary: '#' + colors[5]
|
||||
};
|
||||
|
||||
const importedTheme = this.createTheme(
|
||||
themeName + ' (Importált)',
|
||||
themeColors
|
||||
);
|
||||
|
||||
this.renderCustomThemes();
|
||||
return importedTheme;
|
||||
} catch (error) {
|
||||
console.error('Theme import failed:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
renderCustomThemes() {
|
||||
/*const container = document.getElementById('customThemesList');
|
||||
container.innerHTML = '';
|
||||
|
||||
if (this.customThemes.length === 0) {
|
||||
const emptyMessage = window.translations?.settings?.custom_theme?.no_themes || 'Még nincsenek egyéni témák';
|
||||
container.innerHTML = `<p style="color: var(--text-secondary); font-size: 12px; text-align: center; padding: 20px;">${emptyMessage}</p>`;
|
||||
return;
|
||||
}
|
||||
|
||||
this.customThemes.forEach(theme => {
|
||||
const themeElement = this.createThemeElement(theme);
|
||||
container.appendChild(themeElement);
|
||||
});*/
|
||||
}
|
||||
|
||||
createThemeElement(theme) {
|
||||
const element = document.createElement('div');
|
||||
element.className = 'custom-theme-item';
|
||||
|
||||
const colors = theme.colors;
|
||||
const previewColors = [
|
||||
colors.background || '#DAE4F7',
|
||||
colors.cardCard || '#EDF3FF',
|
||||
colors.accentAccent || '#3673EE',
|
||||
colors.textPrimary || '#050B15'
|
||||
];
|
||||
|
||||
const translations = window.translations?.settings?.custom_theme || {};
|
||||
|
||||
element.innerHTML = `
|
||||
<div class="custom-theme-info">
|
||||
<div class="custom-theme-preview-mini">
|
||||
${previewColors.map(color => `<div class="color-strip" style="background: ${color}"></div>`).join('')}
|
||||
</div>
|
||||
<span class="custom-theme-name">${theme.name}</span>
|
||||
</div>
|
||||
<div class="custom-theme-actions">
|
||||
<button class="action-btn apply" data-theme-id="${theme.id}" title="${translations.apply || 'Alkalmaz'}">
|
||||
<span class="material-icons-round">check</span>
|
||||
</button>
|
||||
<button class="action-btn edit" data-theme-id="${theme.id}" title="${translations.edit || 'Szerkeszt'}">
|
||||
<span class="material-icons-round">edit</span>
|
||||
</button>
|
||||
<button class="action-btn export" data-theme-id="${theme.id}" title="${translations.export || 'Export'}">
|
||||
<span class="material-icons-round">file_upload</span>
|
||||
</button>
|
||||
<button class="action-btn delete" data-theme-id="${theme.id}" title="${translations.delete || 'Töröl'}">
|
||||
<span class="material-icons-round">delete</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
element.querySelector('.apply').addEventListener('click', () => {
|
||||
this.applyTheme(theme.id);
|
||||
});
|
||||
|
||||
element.querySelector('.edit').addEventListener('click', () => {
|
||||
this.editTheme(theme.id);
|
||||
});
|
||||
|
||||
element.querySelector('.export').addEventListener('click', () => {
|
||||
this.showExportModal(theme.id);
|
||||
});
|
||||
|
||||
element.querySelector('.delete').addEventListener('click', () => {
|
||||
const confirmMessage = window.translations?.settings?.custom_theme?.delete_confirm || `Biztosan törölni szeretnéd a "${theme.name}" témát?`;
|
||||
if (confirm(confirmMessage.replace('{name}', theme.name))) {
|
||||
this.deleteTheme(theme.id);
|
||||
this.renderCustomThemes();
|
||||
}
|
||||
});
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
editTheme(themeId) {
|
||||
const theme = this.customThemes.find(t => t.id === themeId);
|
||||
if (!theme) return;
|
||||
|
||||
this.currentEditingTheme = theme;
|
||||
this.openThemeEditor(theme);
|
||||
}
|
||||
|
||||
openThemeEditor(theme = null) {
|
||||
const modal = document.getElementById('themeEditorModal');
|
||||
const nameInput = document.getElementById('themeName');
|
||||
|
||||
if (theme) {
|
||||
nameInput.value = theme.name;
|
||||
this.loadThemeColorsToEditor(theme.colors);
|
||||
} else {
|
||||
nameInput.value = '';
|
||||
this.loadDefaultColorsToEditor();
|
||||
}
|
||||
|
||||
this.updatePreview();
|
||||
modal.style.display = 'flex';
|
||||
}
|
||||
|
||||
loadThemeColorsToEditor(colors) {
|
||||
Object.entries(colors).forEach(([key, value]) => {
|
||||
const input = document.getElementById(key);
|
||||
if (input) {
|
||||
input.value = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
loadDefaultColorsToEditor() {
|
||||
const defaults = {
|
||||
background: '#DAE4F7',
|
||||
cardCard: '#EDF3FF',
|
||||
textPrimary: '#050B15',
|
||||
textSecondary: '#050B15',
|
||||
accentAccent: '#3673EE',
|
||||
accentSecondary: '#1C469A'
|
||||
};
|
||||
this.loadThemeColorsToEditor(defaults);
|
||||
}
|
||||
|
||||
updatePreview() {
|
||||
const preview = document.getElementById('customThemePreview');
|
||||
const colors = this.getColorsFromEditor();
|
||||
|
||||
preview.style.setProperty('--preview-background', colors.background);
|
||||
preview.style.setProperty('--preview-card', colors.cardCard);
|
||||
preview.style.setProperty('--preview-text-primary', colors.textPrimary);
|
||||
preview.style.setProperty('--preview-text-secondary', colors.textSecondary);
|
||||
preview.style.setProperty('--preview-accent', colors.accentAccent);
|
||||
}
|
||||
|
||||
getColorsFromEditor() {
|
||||
return {
|
||||
background: document.getElementById('background').value,
|
||||
cardCard: document.getElementById('cardCard').value,
|
||||
textPrimary: document.getElementById('textPrimary').value,
|
||||
textSecondary: document.getElementById('textSecondary').value,
|
||||
accentAccent: document.getElementById('accentAccent').value,
|
||||
accentSecondary: document.getElementById('accentSecondary').value
|
||||
};
|
||||
}
|
||||
|
||||
saveThemeFromEditor() {
|
||||
const name = document.getElementById('themeName').value.trim();
|
||||
if (!name) {
|
||||
alert('Add meg a téma nevét!');
|
||||
return;
|
||||
}
|
||||
|
||||
const colors = this.getColorsFromEditor();
|
||||
|
||||
if (this.currentEditingTheme) {
|
||||
this.updateTheme(this.currentEditingTheme.id, name, colors);
|
||||
} else {
|
||||
this.createTheme(name, colors);
|
||||
}
|
||||
|
||||
this.closeThemeEditor();
|
||||
this.renderCustomThemes();
|
||||
}
|
||||
|
||||
closeThemeEditor() {
|
||||
document.getElementById('themeEditorModal').style.display = 'none';
|
||||
this.currentEditingTheme = null;
|
||||
}
|
||||
|
||||
showExportModal(themeId) {
|
||||
const exportString = this.exportTheme(themeId);
|
||||
if (exportString) {
|
||||
const theme = this.customThemes.find(t => t.id === themeId);
|
||||
prompt(`${theme.name} téma export azonosítója (másold ki):`, exportString);
|
||||
}
|
||||
}
|
||||
|
||||
showImportModal() {
|
||||
document.getElementById('importModal').style.display = 'flex';
|
||||
}
|
||||
|
||||
closeImportModal() {
|
||||
document.getElementById('importModal').style.display = 'none';
|
||||
document.getElementById('themeImportString').value = '';
|
||||
}
|
||||
|
||||
importThemeFromModal() {
|
||||
const importString = document.getElementById('themeImportString').value.trim();
|
||||
if (!importString) {
|
||||
alert('Add meg az azonosítót!');
|
||||
return;
|
||||
}
|
||||
|
||||
const importedTheme = this.importTheme(importString);
|
||||
if (importedTheme) {
|
||||
alert(`"${importedTheme.name}" téma sikeresen importálva!`);
|
||||
this.closeImportModal();
|
||||
} else {
|
||||
alert('Hiba történt az importálás során. Ellenőrizd az azonosítót!');
|
||||
}
|
||||
}
|
||||
|
||||
initializeEventListeners() {
|
||||
/*document.getElementById('createCustomTheme').addEventListener('click', () => {
|
||||
this.openThemeEditor();
|
||||
});
|
||||
|
||||
document.getElementById('importTheme').addEventListener('click', () => {
|
||||
this.showImportModal();
|
||||
});
|
||||
|
||||
document.getElementById('closeThemeEditor').addEventListener('click', () => {
|
||||
this.closeThemeEditor();
|
||||
});
|
||||
|
||||
document.getElementById('cancelThemeEdit').addEventListener('click', () => {
|
||||
this.closeThemeEditor();
|
||||
});
|
||||
|
||||
document.getElementById('saveTheme').addEventListener('click', () => {
|
||||
this.saveThemeFromEditor();
|
||||
});
|
||||
|
||||
document.getElementById('closeImportModal').addEventListener('click', () => {
|
||||
this.closeImportModal();
|
||||
});
|
||||
|
||||
document.getElementById('cancelImport').addEventListener('click', () => {
|
||||
this.closeImportModal();
|
||||
});
|
||||
|
||||
document.getElementById('confirmImport').addEventListener('click', () => {
|
||||
this.importThemeFromModal();
|
||||
});
|
||||
|
||||
const colorInputs = ['background', 'cardCard', 'textPrimary', 'textSecondary', 'accentAccent', 'accentSecondary'];
|
||||
colorInputs.forEach(inputId => {
|
||||
document.getElementById(inputId).addEventListener('input', () => {
|
||||
this.updatePreview();
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('themeEditorModal').addEventListener('click', (e) => {
|
||||
if (e.target.id === 'themeEditorModal') {
|
||||
this.closeThemeEditor();
|
||||
}
|
||||
});
|
||||
|
||||
document.getElementById('importModal').addEventListener('click', (e) => {
|
||||
if (e.target.id === 'importModal') {
|
||||
this.closeImportModal();
|
||||
}
|
||||
});*/
|
||||
}
|
||||
}
|
||||
|
||||
const customThemeManager = new CustomThemeManager();
|
||||
const originalGetCurrentTheme = getCurrentTheme;
|
||||
getCurrentTheme = function() {
|
||||
const theme = originalGetCurrentTheme();
|
||||
if (theme && theme.startsWith('custom-')) {
|
||||
return theme;
|
||||
}
|
||||
return theme;
|
||||
};
|
||||
const originalUpdateThemeButtons = updateThemeButtons;
|
||||
updateThemeButtons = function(currentTheme) {
|
||||
originalUpdateThemeButtons(currentTheme);
|
||||
document.querySelectorAll('.custom-theme-item').forEach(item => {
|
||||
const applyBtn = item.querySelector('.apply');
|
||||
const themeId = applyBtn.dataset.themeId;
|
||||
item.classList.toggle('active', themeId === currentTheme);
|
||||
});
|
||||
};
|
||||
const currentTheme = getCurrentTheme();
|
||||
if (currentTheme && currentTheme.startsWith('custom-')) {
|
||||
customThemeManager.applyTheme(currentTheme);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -107,7 +107,7 @@ body {
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
.user-dropdown-btn:hover {
|
||||
background:var(--card-card);
|
||||
background:var(--hover);
|
||||
}
|
||||
.user-info {
|
||||
text-align:right;
|
||||
@@ -119,7 +119,7 @@ body {
|
||||
margin-top:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
box-shadow:0 4px 6px -1px var(--accent-shadow);
|
||||
box-shadow:0 4px 6px -1px rgba(0,0,0,0.1);
|
||||
width:200px;
|
||||
display:none;
|
||||
z-index:1000;
|
||||
@@ -138,7 +138,10 @@ body {
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
.dropdown-item:hover {
|
||||
background:var(--button-secondaryFill);
|
||||
background:var(--hover);
|
||||
color:var(--accent-accent);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
.kreta-main {
|
||||
flex:1;
|
||||
@@ -359,9 +362,10 @@ body {
|
||||
justify-content:center;
|
||||
margin:16px auto;
|
||||
background:var(--card-card);
|
||||
border-radius:24px;
|
||||
border-radius:12px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
max-width:800px;
|
||||
padding:20px;
|
||||
padding:16px;
|
||||
}
|
||||
.week-selector-container {
|
||||
width:100%;
|
||||
@@ -393,7 +397,7 @@ body {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
gap:12px;
|
||||
gap:clamp(8px,2vw,12px);
|
||||
max-width:100%;
|
||||
}
|
||||
.week-nav-btn {
|
||||
@@ -783,9 +787,46 @@ body {
|
||||
border-radius:8px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
.modal-header-buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.modal-add-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-add-btn:hover {
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
background:var(--background);
|
||||
color:var(--text-primary);
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.modal-body {
|
||||
padding:1.5rem;
|
||||
@@ -828,6 +869,352 @@ body {
|
||||
.test-section h4 {
|
||||
color:var(--warning-accent);
|
||||
}
|
||||
|
||||
.custom-homework-section h4,
|
||||
.custom-tests-section h4 {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.custom-homework-list,
|
||||
.custom-tests-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.custom-homework-item,
|
||||
.custom-test-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.75rem;
|
||||
background: var(--background);
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--background-0);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-homework-item.completed,
|
||||
.custom-test-item.completed {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.custom-homework-item.completed .homework-text,
|
||||
.custom-test-item.completed .test-text {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.homework-text,
|
||||
.test-text {
|
||||
flex: 1;
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.homework-actions,
|
||||
.test-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.homework-complete-btn,
|
||||
.test-complete-btn,
|
||||
.homework-delete-btn,
|
||||
.test-delete-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.homework-complete-btn:hover,
|
||||
.test-complete-btn:hover {
|
||||
background: var(--accent-accent-20);
|
||||
}
|
||||
|
||||
.homework-delete-btn:hover,
|
||||
.test-delete-btn:hover {
|
||||
background: var(--error-20);
|
||||
}
|
||||
|
||||
.empty-message {
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.add-item-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
z-index: 10001;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.add-item-modal.show {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.add-modal-content {
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 12px;
|
||||
width: 90%;
|
||||
max-width: 400px;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
transform: translateY(20px);
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.add-item-modal.show .add-modal-content {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.add-modal-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 1.5rem;
|
||||
border-bottom: 1px solid var(--background-0);
|
||||
}
|
||||
|
||||
.add-modal-header h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.add-modal-close {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.add-modal-close:hover {
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.add-modal-body {
|
||||
padding: 1.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.type-selection,
|
||||
.text-input {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.type-selection label,
|
||||
.text-input label {
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.type-select {
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--background-0);
|
||||
border-radius: 8px;
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.type-select:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.item-text {
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--background-0);
|
||||
border-radius: 8px;
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-family: inherit;
|
||||
resize: vertical;
|
||||
min-height: 80px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.item-text:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.item-text::placeholder {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.add-modal-actions {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
justify-content: flex-end;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
.cancel-btn,
|
||||
.save-btn {
|
||||
padding: 0.75rem 1.5rem;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
background: var(--background);
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid var(--background-0);
|
||||
}
|
||||
|
||||
.cancel-btn:hover {
|
||||
background: var(--background-0);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.save-btn:hover {
|
||||
background: var(--accent-accent-80);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.lesson-modal {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.add-item-modal {
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
width: 95%;
|
||||
max-width: none;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.add-modal-content {
|
||||
width: 95%;
|
||||
max-width: none;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
.modal-header,
|
||||
.add-modal-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.modal-body,
|
||||
.add-modal-body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.modal-header-buttons {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.modal-add-btn,
|
||||
.modal-close,
|
||||
.add-modal-close {
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
.modal-add-btn img,
|
||||
.modal-close img,
|
||||
.add-modal-close img {
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
}
|
||||
|
||||
.custom-homework-item,
|
||||
.custom-test-item {
|
||||
padding: 0.5rem;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.homework-actions,
|
||||
.test-actions {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.homework-text,
|
||||
.test-text {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.add-modal-actions {
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.cancel-btn,
|
||||
.save-btn {
|
||||
width: 100%;
|
||||
padding: 0.875rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 769px) {
|
||||
.lesson-modal {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.add-item-modal {
|
||||
z-index: 10001;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.add-modal-content {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
.tema-section h4 {
|
||||
color:var(--primary-accent);
|
||||
}
|
||||
@@ -837,6 +1224,43 @@ body {
|
||||
border-radius:8px;
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
.homework-attachments {
|
||||
margin-top: 1rem;
|
||||
padding-top: 1rem;
|
||||
border-top: 1px solid var(--background-0);
|
||||
}
|
||||
|
||||
.attachments-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.75rem;
|
||||
background-color: var(--accent-15);
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--background-0);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.attachment-item:hover {
|
||||
background-color: var(--background-0);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.attachment-item:active {
|
||||
transform: translateY(0);
|
||||
background-color: var(--accent-accent);
|
||||
opacity: 0.8;
|
||||
}
|
||||
.test-details-loading {
|
||||
color:var(--text-secondary);
|
||||
font-style:italic;
|
||||
@@ -1110,4 +1534,4 @@ to {
|
||||
padding-top:16px;
|
||||
transition:gap 0.2s ease;
|
||||
font-size:clamp(0.875rem,1.5vw,1rem);
|
||||
}
|
||||
}
|
||||
|
||||
106
tools/background.js
Normal file
@@ -0,0 +1,106 @@
|
||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
(async () => {
|
||||
try {
|
||||
switch (request.action) {
|
||||
case 'storage_set':
|
||||
await handleStorageSet(request.key, request.value);
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
case 'storage_get':
|
||||
const value = await handleStorageGet(request.key, request.defaultValue);
|
||||
sendResponse({ success: true, value: value });
|
||||
break;
|
||||
|
||||
case 'storage_remove':
|
||||
await handleStorageRemove(request.key);
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
case 'storage_clear':
|
||||
await handleStorageClear();
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('[Background] Unknown action:', request.action);
|
||||
sendResponse({ success: false, error: 'Unknown action' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Error handling message:', error);
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
})();
|
||||
return true;
|
||||
});
|
||||
|
||||
async function handleStorageSet(key, value) {
|
||||
try {
|
||||
await chrome.storage.sync.set({ [key]: value });
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to save ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageGet(key, defaultValue = null) {
|
||||
try {
|
||||
const result = await chrome.storage.sync.get(key);
|
||||
const value = result[key];
|
||||
return value !== undefined ? value : defaultValue;
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to get ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageRemove(key) {
|
||||
try {
|
||||
await chrome.storage.sync.remove(key);
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to remove ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageClear() {
|
||||
try {
|
||||
const allData = await chrome.storage.sync.get(null);
|
||||
const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
|
||||
|
||||
if (firkaKeys.length > 0) {
|
||||
await chrome.storage.sync.remove(firkaKeys);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Failed to clear storage:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||
if (namespace === 'sync') {
|
||||
const firkaChanges = Object.keys(changes).filter(key => key.startsWith('firka_'));
|
||||
if (firkaChanges.length > 0) {
|
||||
notifyContentScriptsOfChanges(changes);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function notifyContentScriptsOfChanges(changes) {
|
||||
try {
|
||||
const tabs = await chrome.tabs.query({ url: 'https://*.e-kreta.hu/*' });
|
||||
|
||||
for (const tab of tabs) {
|
||||
try {
|
||||
await chrome.tabs.sendMessage(tab.id, {
|
||||
action: 'storage_changed',
|
||||
changes: changes
|
||||
});
|
||||
} catch (error) {
|
||||
console.debug(`[Background] Could not notify tab ${tab.id}:`, error.message);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Failed to notify content scripts:', error);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
const cookieManager = {
|
||||
get(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(";");
|
||||
|
||||
for (let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === " ") {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
set(name, value, days = 365) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
},
|
||||
};
|
||||
@@ -1,19 +1,20 @@
|
||||
const createTemplate = {
|
||||
header() {
|
||||
async header() {
|
||||
const data = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get("schoolName") || "Iskola",
|
||||
id: cookieManager.get("schoolCode") || "",
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get("userName") || "Felhasználó",
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
email: cookieManager.get("userEmail") || "",
|
||||
},
|
||||
};
|
||||
|
||||
const schoolSubdomain = await storageManager.get("schoolSubdomain", "");
|
||||
const baseUrl = schoolSubdomain ? `https://${schoolSubdomain}.e-kreta.hu` : "";
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = helper.shortenSchoolName(schoolNameFull);
|
||||
|
||||
@@ -36,25 +37,25 @@ const createTemplate = {
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item ${location.pathname == "/Intezmeny/Faliujsag" ? "active" : ""}">
|
||||
<a href="${baseUrl}/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item ${location.pathname == "/Intezmeny/Faliujsag" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/dashboard-" + (location.pathname == "/Intezmeny/Faliujsag" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.dashboard")}">
|
||||
${LanguageManager.t("navigation.dashboard")}
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item ${location.pathname == "/TanuloErtekeles/Osztalyzatok" ? "active" : ""}">
|
||||
<a href="${baseUrl}/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item ${location.pathname == "/TanuloErtekeles/Osztalyzatok" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/grades-" + (location.pathname == "/TanuloErtekeles/Osztalyzatok" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.grades")}">
|
||||
${LanguageManager.t("navigation.grades")}
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item ${location.pathname == "/Orarend/InformaciokOrarend" ? "active" : ""}">
|
||||
<a href="${baseUrl}/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item ${location.pathname == "/Orarend/InformaciokOrarend" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/timetable-" + (location.pathname == "/Orarend/InformaciokOrarend" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.timetable")}">
|
||||
${LanguageManager.t("navigation.timetable")}
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item ${location.pathname == "/Hianyzas/Hianyzasok" ? "active" : ""}">
|
||||
<a href="${baseUrl}/Hianyzas/Hianyzasok" data-page="absences" class="nav-item ${location.pathname == "/Hianyzas/Hianyzasok" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/absences-" + (location.pathname == "/Hianyzas/Hianyzasok" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.absences")}">
|
||||
${LanguageManager.t("navigation.absences")}
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item ${location.pathname == "/Tanulo/TanuloHaziFeladat" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/others.svg")}" alt="${LanguageManager.t("navigation.other")}">
|
||||
${LanguageManager.t("navigation.other")}
|
||||
<a href="https://eugyintezes.e-kreta.hu/api/bff/login" data-page="messages" class="nav-item ${location.pathname == "/" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/messages-" + (location.pathname == "/uzenetek" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.messages")}">
|
||||
${LanguageManager.t("navigation.messages")}
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -67,11 +68,7 @@ const createTemplate = {
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="https://bmszc-puskas.e-kreta.hu/Home/Uzenetek" data-page="messages" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL("icons/messages.svg")}" alt="${LanguageManager.t("navigation.messages")}">
|
||||
${LanguageManager.t("navigation.messages")}
|
||||
</a>
|
||||
<a href="/Adminisztracio/Profil" data-page="profile" class="dropdown-item">
|
||||
<a href="${baseUrl}/Adminisztracio/Profil" data-page="profile" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL("icons/profile.svg")}" alt="${LanguageManager.t("navigation.profile")}">
|
||||
${LanguageManager.t("navigation.profile")}
|
||||
</a>
|
||||
@@ -79,7 +76,7 @@ const createTemplate = {
|
||||
<img src="${chrome.runtime.getURL("icons/settings.svg")}" alt="${LanguageManager.t("navigation.settings")}">
|
||||
${LanguageManager.t("navigation.settings")}
|
||||
</a>
|
||||
<a href="/Home/Logout" data-page="logout" class="dropdown-item">
|
||||
<a href="${baseUrl}/Home/Logout" data-page="logout" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL("icons/logout.svg")}" alt="${LanguageManager.t("navigation.logout")}">
|
||||
${LanguageManager.t("navigation.logout")}
|
||||
</a>
|
||||
|
||||
@@ -65,7 +65,13 @@ window.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
}
|
||||
|
||||
if (urls.some((url) => url.includes(location.pathname))) {
|
||||
const currentUrl = location.href;
|
||||
const shouldShowLoading = urls.some((urlPattern) => {
|
||||
const regex = new RegExp(urlPattern.replace(/\*/g, '.*'));
|
||||
return regex.test(currentUrl);
|
||||
});
|
||||
|
||||
if (shouldShowLoading) {
|
||||
loadingScreen.show();
|
||||
}
|
||||
});
|
||||
|
||||
144
tools/storageManager.js
Normal file
@@ -0,0 +1,144 @@
|
||||
const storageManager = {
|
||||
isExtensionContext() {
|
||||
return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.id;
|
||||
},
|
||||
|
||||
isContentScript() {
|
||||
return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.sendMessage;
|
||||
},
|
||||
|
||||
async set(key, value) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
await chrome.storage.sync.set({ [prefixedKey]: value });
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_set',
|
||||
key: prefixedKey,
|
||||
value: value
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to save via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
localStorage.setItem(prefixedKey, JSON.stringify(value));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Storage failed for ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
async get(key, defaultValue = null) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
const result = await chrome.storage.sync.get(prefixedKey);
|
||||
const value = result[prefixedKey];
|
||||
return value !== undefined ? value : defaultValue;
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_get',
|
||||
key: prefixedKey,
|
||||
defaultValue: defaultValue
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.hasOwnProperty('value')) {
|
||||
resolve(response.value);
|
||||
} else {
|
||||
reject(new Error('Failed to get via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const value = localStorage.getItem(prefixedKey);
|
||||
if (value !== null) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Storage failed for ${key}:`, error);
|
||||
return defaultValue;
|
||||
}
|
||||
},
|
||||
|
||||
async remove(key) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
await chrome.storage.sync.remove(prefixedKey);
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_remove',
|
||||
key: prefixedKey
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to remove via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
localStorage.removeItem(prefixedKey);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Failed to remove ${key}:`, error);
|
||||
}
|
||||
},
|
||||
|
||||
async clear() {
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
const allData = await chrome.storage.sync.get(null);
|
||||
const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
|
||||
if (firkaKeys.length > 0) {
|
||||
await chrome.storage.sync.remove(firkaKeys);
|
||||
}
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_clear'
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to clear via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const keysToRemove = [];
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key && key.startsWith('firka_')) {
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
}
|
||||
keysToRemove.forEach(key => localStorage.removeItem(key));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[StorageManager] Failed to clear storage:', error);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||