Compare commits
69 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 | ||
|
|
9fd0190ab8 | ||
|
|
94fbc472f6 | ||
|
|
96be6471f0 | ||
|
|
10cabc3889 | ||
|
|
6cddce142c | ||
|
|
f81d821c56 | ||
|
|
0a5439acfd | ||
|
|
dac927cf7d | ||
|
|
b4a270a8d2 | ||
|
|
110ba0d4fb | ||
|
|
1ba976e06e | ||
|
|
df8adf65de | ||
|
|
e96c9e1c83 | ||
|
|
a3631d749f | ||
|
|
fa7c773393 | ||
|
|
a39295ae68 | ||
|
|
d722740bdf | ||
|
|
1218d3b905 | ||
|
|
bbe8a4b2b3 | ||
|
|
ec99a3b5c8 | ||
|
|
02ffa23e1a | ||
|
|
d7ea449a1b | ||
|
|
e7ec225e18 | ||
|
|
5a9837e655 | ||
|
|
1a340a1950 | ||
|
|
eef39c28d2 | ||
|
|
89266bc3c9 | ||
|
|
5408a1e08a | ||
|
|
6a52c51ece | ||
|
|
107e20f5c1 | ||
|
|
cb54d51b8c | ||
|
|
8eb7256f5b | ||
|
|
3510288181 |
41
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>
|
||||
@@ -19,10 +19,19 @@
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://chromewebstore.google.com/detail/firxa/emafoaifbfppcccgfmpcoheonhjnpldj?hl=hu">
|
||||
<img src="https://github.com/QwIT-Development/firka-extension/blob/main/images/chrome.png?raw=true" alt="Elérhető a Chrome Web Store-on" width="200">
|
||||
</a>
|
||||
<a href="https://addons.mozilla.org/hu/firefox/addon/firxa/">
|
||||
<img src="https://github.com/QwIT-Development/firka-extension/blob/main/images/firefox.png?raw=true" alt="Elérhető a Firefox add-ons oldalon" width="200">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## 📱 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ó
|
||||
@@ -30,30 +39,16 @@
|
||||
- Fejlett hiányzás kezelés
|
||||
- Egyszerűsített szerepkör választó
|
||||
- Új kezdőlap elrendezés
|
||||
- Továbbfejlesztett profilkezelő
|
||||
|
||||
## 🚀 Telepítés
|
||||
|
||||
1. Töltsd le a legfrissebb verziót a [Releases](https://github.com/QwIT-Development/firka-extension/releases/) vagy [Chrome Webstore](https://chromewebstore.google.com/detail/firxa/emafoaifbfppcccgfmpcoheonhjnpldj?hl=hu) oldalról
|
||||
### Chromium alapú böngészők esetén
|
||||
2. Navigálj a `chrome://extensions` oldalra
|
||||
3. Kapcsold be a "Fejlesztői mód"-ot a jobb felső sarokban
|
||||
4. Keresd meg a letöltött zip fájlt
|
||||
5. Húzd a letöltött zip fájlt a böngészőbe
|
||||
### Firefox alapú böngészők esetén
|
||||
2. Navigálj az `about:addons` oldalra
|
||||
3. Kattints rá a fogaskerék ikonra (⚙️) a jobb felső sarokban
|
||||
4. Ebben a menüben válaszd a(z) "Kiegészítő telepítése fájlból..."/"Install Add-on From File..."
|
||||
5. Válaszd ki a `.zip` fájlt amit letöltöttél
|
||||
### Kész!
|
||||
6. A bővítmény automatikusan működésbe lép, amikor megnyitod az e-KRÉTA oldalt
|
||||
1. Töltsd le a legfrissebb verziót a fenti gombok segítségével a böngésződnek megfelelően.
|
||||
|
||||
## ⚙️ 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
|
||||
|
||||
@@ -62,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
|
||||
|
||||
@@ -1,436 +1,485 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 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;
|
||||
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) {
|
||||
@media (max-width:768px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}.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;
|
||||
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) {
|
||||
@media (max-width:1200px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: minmax(250px, 350px) 1fr minmax(180px, 250px);
|
||||
}
|
||||
grid-template-columns:minmax(250px,350px) 1fr minmax(180px,250px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
}@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
padding:1rem;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
margin: 0;
|
||||
}.school-info {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
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;
|
||||
}.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) {
|
||||
@media (max-width:768px) {
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
margin:0;
|
||||
font-size:20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.5rem;
|
||||
}.logo {
|
||||
width:24px;
|
||||
border-radius:8px;
|
||||
margin-right:0.5rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.school-details span {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
display:block;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
max-width:300px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.school-details span {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
}
|
||||
max-width:200px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
.school-details {
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
}.user-profile {
|
||||
position:relative;
|
||||
justify-self:flex-end;
|
||||
}
|
||||
@media (max-width:768px) {
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
grid-area:user;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
}.user-dropdown-btn {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--card-card);
|
||||
background:var(--card-card);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.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;
|
||||
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;
|
||||
display:block;
|
||||
animation:dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.75rem;
|
||||
padding:0.75rem 1rem;
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
background:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
flex:1;
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
max-width:1200px;
|
||||
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);
|
||||
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;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.filter-header h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
font-size:18px;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--card-card);
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
display:grid;
|
||||
grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
|
||||
gap:16px;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.filter-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.filter-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;
|
||||
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-input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px var(--accent-accent);
|
||||
outline:none;
|
||||
box-shadow:0 0 0 2px var(--accent-accent);
|
||||
}
|
||||
.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 {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
|
||||
.absences-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
background:var(--card-card);
|
||||
border-radius:16px;
|
||||
overflow:hidden;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.absence-group {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 0.3s ease;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
.absences-table {
|
||||
width:100%;
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
.absence-date {
|
||||
padding: 16px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
.table-header {
|
||||
background:var(--accent-15);
|
||||
border-bottom:1px solid var(--accent-30);
|
||||
}
|
||||
|
||||
.absence-count {
|
||||
margin-left: auto;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
.table-header th {
|
||||
padding:16px;
|
||||
text-align:left;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
font-size:14px;
|
||||
text-transform:uppercase;
|
||||
letter-spacing:0.5px;
|
||||
}
|
||||
|
||||
.absence-list {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
.table-row {
|
||||
border-bottom:1px solid var(--accent-15);
|
||||
transition:background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.absence-item {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 12px;
|
||||
background: var(--accent-15);
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
.table-row:hover {
|
||||
background:var(--accent-10);
|
||||
}
|
||||
|
||||
.absence-item:hover {
|
||||
transform: translateX(4px);
|
||||
.table-row:last-child {
|
||||
border-bottom:none;
|
||||
}
|
||||
|
||||
.absence-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
.table-cell {
|
||||
padding:16px;
|
||||
color:var(--text-primary);
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.absence-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
.date-cell {
|
||||
font-weight:600;
|
||||
color:var(--accent-accent);
|
||||
}
|
||||
.lesson-cell {
|
||||
text-align:center;
|
||||
font-weight:500;
|
||||
}
|
||||
.subject-cell {
|
||||
font-weight:600;
|
||||
}
|
||||
.topic-cell {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
max-width:200px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.status-cell {
|
||||
text-align:center;
|
||||
}
|
||||
.status-badge {
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:4px;
|
||||
padding:6px 12px;
|
||||
border-radius:20px;
|
||||
font-size:12px;
|
||||
font-weight:600;
|
||||
text-transform:uppercase;
|
||||
letter-spacing:0.5px;
|
||||
}
|
||||
.status-badge.justified {
|
||||
background:var(--grades-4-bg);
|
||||
color:var(--grades-4);
|
||||
}
|
||||
.status-badge.unjustified {
|
||||
background:var(--grades-1-bg);
|
||||
color:var(--grades-1);
|
||||
}
|
||||
.status-badge.pending {
|
||||
background:var(--grades-3-bg);
|
||||
color:var(--grades-3);
|
||||
}
|
||||
@media (max-width:768px) {
|
||||
.absences-table {
|
||||
font-size:14px;
|
||||
}
|
||||
.table-header th,.table-cell {
|
||||
padding:12px 8px;
|
||||
}
|
||||
.topic-cell {
|
||||
max-width:120px;
|
||||
}
|
||||
.stats-overview {
|
||||
grid-template-columns:repeat(2,1fr);
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.absences-table,.table-header,.table-row {
|
||||
display:block;
|
||||
}
|
||||
.table-header {
|
||||
display:none;
|
||||
}
|
||||
.date-group {
|
||||
margin-bottom:24px;
|
||||
}
|
||||
.date-group-header {
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
padding:12px 16px;
|
||||
border-radius:12px 12px 0 0;
|
||||
font-weight:600;
|
||||
font-size:16px;
|
||||
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 {
|
||||
width:100%;
|
||||
margin-bottom:0;
|
||||
border:none;
|
||||
border-bottom:1px solid var(--accent-15);
|
||||
border-radius:0;
|
||||
padding:16px;
|
||||
background:transparent;
|
||||
}
|
||||
.table-row:last-child {
|
||||
border-bottom:none;
|
||||
}
|
||||
.table-cell {
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:flex-start;
|
||||
padding:6px 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;
|
||||
}
|
||||
.topic-cell {
|
||||
max-width:none;
|
||||
white-space:normal;
|
||||
text-overflow:initial;
|
||||
overflow:visible;
|
||||
text-align:right;
|
||||
flex:1;
|
||||
}
|
||||
.stats-overview {
|
||||
grid-template-columns:1fr;
|
||||
}
|
||||
}.absence-details {
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:4px;
|
||||
}
|
||||
|
||||
.absence-subject {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
.absence-topic {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.absence-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:4px;
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
.absence-status.justified {
|
||||
color: var(--grades-4);
|
||||
color:var(--grades-4);
|
||||
}
|
||||
|
||||
.absence-status.unjustified {
|
||||
color: var(--grades-1);
|
||||
color:var(--grades-1);
|
||||
}
|
||||
|
||||
.absence-status.pending {
|
||||
color: var(--grades-3);
|
||||
color:var(--grades-3);
|
||||
}
|
||||
|
||||
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:var(--background);
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
z-index:9999;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 2rem;
|
||||
border-radius: 24px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
padding:2rem;
|
||||
border-radius:24px;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: var(--Text-Primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--Text-Primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.loading-text2 {
|
||||
align-self: stretch;
|
||||
color: var(--Text-Secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--Text-Secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 8px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
margin-bottom:1rem;
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@keyframes spin {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
|
||||
@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,257 +1,638 @@
|
||||
async function collectAbsencesData() {
|
||||
await helper.waitForElement('#HianyzasGrid');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
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ó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00'
|
||||
}
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
const absences = [];
|
||||
const rows = document.querySelectorAll('#HianyzasGrid .k-grid-content tr');
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length >= 9) {
|
||||
absences.push({
|
||||
date: cells[1]?.textContent?.trim() || '',
|
||||
lesson: cells[2]?.textContent?.trim() || '',
|
||||
subject: cells[3]?.textContent?.trim() || '',
|
||||
topic: cells[4]?.textContent?.trim() || '',
|
||||
type: cells[5]?.textContent?.trim() || '',
|
||||
justified: cells[6]?.textContent?.trim() === 'Igen',
|
||||
justificationStatus: cells[6]?.textContent?.trim() === 'Igen' ? 'justified' :
|
||||
cells[6]?.textContent?.trim() === 'Nem' ? 'unjustified' : 'pending',
|
||||
purposeful: cells[7]?.textContent?.trim() || '',
|
||||
justificationType: cells[8]?.textContent?.trim() || ''
|
||||
try {
|
||||
const currentDomain = window.location.hostname;
|
||||
const response = await fetch(
|
||||
`https://${currentDomain}/api/HianyzasokApi/GetHianyzasGrid?sort=MulasztasDatum-desc&page=1&pageSize=100&group=&filter=&data=%7B%7D&_=${Date.now()}`,
|
||||
{
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json, text/javascript, */*; q=0.01",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const apiData = await response.json();
|
||||
const absences = [];
|
||||
|
||||
if (apiData.Data && Array.isArray(apiData.Data)) {
|
||||
apiData.Data.forEach((item) => {
|
||||
const date = new Date(item.MulasztasDatum);
|
||||
const formattedDate = `${date.getFullYear()}.${(date.getMonth() + 1).toString().padStart(2, "0")}.${date.getDate().toString().padStart(2, "0")}.`;
|
||||
|
||||
let justificationStatus = "pending";
|
||||
if (item.Igazolt_BOOL === true) {
|
||||
justificationStatus = "justified";
|
||||
} else if (item.Igazolt_BOOL === false && item.IgazolasTipus !== null) {
|
||||
justificationStatus = "unjustified";
|
||||
}
|
||||
|
||||
absences.push({
|
||||
date: formattedDate,
|
||||
lesson: item.Oraszam?.toString() || "",
|
||||
subject: item.Targy || "",
|
||||
topic: item.Tema || "",
|
||||
type: item.MulasztasTipus_DNAME || "",
|
||||
justified: item.Igazolt_BOOL === true,
|
||||
justificationStatus: justificationStatus,
|
||||
purposeful: item.TanoraiCeluMulasztas_BNAME || "",
|
||||
justificationType: item.IgazolasTipus_DNAME || "",
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const groupedAbsences = {};
|
||||
absences.forEach(absence => {
|
||||
if (!groupedAbsences[absence.date]) {
|
||||
groupedAbsences[absence.date] = [];
|
||||
}
|
||||
groupedAbsences[absence.date].push(absence);
|
||||
});
|
||||
const groupedAbsences = {};
|
||||
absences.forEach((absence) => {
|
||||
if (!groupedAbsences[absence.date]) {
|
||||
groupedAbsences[absence.date] = [];
|
||||
}
|
||||
groupedAbsences[absence.date].push(absence);
|
||||
});
|
||||
|
||||
return { basicData, absences, groupedAbsences };
|
||||
return { basicData, absences, groupedAbsences };
|
||||
} catch (error) {
|
||||
console.error("Hiba az API hívás során:", error);
|
||||
return { basicData, absences: [], groupedAbsences: {} };
|
||||
}
|
||||
}
|
||||
|
||||
function createFilterCard(absences) {
|
||||
const filterCard = document.createElement('div');
|
||||
filterCard.className = 'filter-card';
|
||||
|
||||
const filterHeader = document.createElement('div');
|
||||
filterHeader.className = 'filter-header';
|
||||
const h2 = document.createElement('h2');
|
||||
h2.textContent = LanguageManager.t('absences.filter_title');
|
||||
filterHeader.appendChild(h2);
|
||||
|
||||
const filterContent = document.createElement('div');
|
||||
filterContent.className = 'filter-content';
|
||||
|
||||
const dateGroup = createFilterGroup(
|
||||
'Calendar.svg',
|
||||
'Dátum',
|
||||
LanguageManager.t('absences.date'),
|
||||
'input',
|
||||
{ type: 'date', id: 'dateFilter', className: 'filter-input' }
|
||||
);
|
||||
filterContent.appendChild(dateGroup);
|
||||
|
||||
const subjectGroup = createSubjectFilterGroup(absences);
|
||||
filterContent.appendChild(subjectGroup);
|
||||
|
||||
const justificationGroup = createJustificationFilterGroup();
|
||||
filterContent.appendChild(justificationGroup);
|
||||
|
||||
filterCard.appendChild(filterHeader);
|
||||
filterCard.appendChild(filterContent);
|
||||
|
||||
return filterCard;
|
||||
}
|
||||
|
||||
function createFilterGroup(iconName, altText, labelText, elementType, attributes) {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL(`icons/${iconName}`);
|
||||
img.alt = altText;
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + labelText));
|
||||
|
||||
const element = document.createElement(elementType);
|
||||
Object.assign(element, attributes);
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(element);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createSubjectFilterGroup(absences) {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/Subject.svg');
|
||||
img.alt = 'Tantárgy';
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.subject')));
|
||||
|
||||
const select = document.createElement('select');
|
||||
select.id = 'subjectFilter';
|
||||
select.className = 'filter-input';
|
||||
|
||||
const defaultOption = document.createElement('option');
|
||||
defaultOption.value = '';
|
||||
defaultOption.textContent = LanguageManager.t('absences.all_subjects');
|
||||
select.appendChild(defaultOption);
|
||||
|
||||
const subjects = [...new Set(absences.map(a => a.subject))].sort();
|
||||
subjects.forEach(subject => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject;
|
||||
option.textContent = subject;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(select);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createJustificationFilterGroup() {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/BadgeCheck.svg');
|
||||
img.alt = 'Igazolás';
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.justification')));
|
||||
|
||||
const select = document.createElement('select');
|
||||
select.id = 'justificationFilter';
|
||||
select.className = 'filter-input';
|
||||
|
||||
const options = [
|
||||
{ value: '', text: LanguageManager.t('absences.all_types') },
|
||||
{ value: 'justified', text: LanguageManager.t('absences.justified') },
|
||||
{ value: 'unjustified', text: LanguageManager.t('absences.unjustified') },
|
||||
{ value: 'pending', text: LanguageManager.t('absences.pending') }
|
||||
];
|
||||
|
||||
options.forEach(optionData => {
|
||||
const option = document.createElement('option');
|
||||
option.value = optionData.value;
|
||||
option.textContent = optionData.text;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(select);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createStatsOverview(absences) {
|
||||
const statsOverview = document.createElement('div');
|
||||
statsOverview.className = 'stats-overview';
|
||||
|
||||
const stats = [
|
||||
{ number: absences.length, label: LanguageManager.t('absences.total_absences') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'justified').length, label: LanguageManager.t('absences.justified') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'unjustified').length, label: LanguageManager.t('absences.unjustified') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'pending').length, label: LanguageManager.t('absences.pending') }
|
||||
];
|
||||
|
||||
stats.forEach(stat => {
|
||||
const statCard = document.createElement('div');
|
||||
statCard.className = 'stat-card';
|
||||
|
||||
const statNumber = document.createElement('div');
|
||||
statNumber.className = 'stat-number';
|
||||
statNumber.textContent = stat.number;
|
||||
|
||||
const statLabel = document.createElement('div');
|
||||
statLabel.className = 'stat-label';
|
||||
statLabel.textContent = stat.label;
|
||||
|
||||
statCard.appendChild(statNumber);
|
||||
statCard.appendChild(statLabel);
|
||||
statsOverview.appendChild(statCard);
|
||||
});
|
||||
|
||||
return statsOverview;
|
||||
}
|
||||
|
||||
function createAbsencesContainer(absences) {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'absences-container';
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.className = 'absences-table';
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
thead.className = 'table-header';
|
||||
|
||||
const headerRow = document.createElement('tr');
|
||||
const headers = [
|
||||
LanguageManager.t('absences.date'),
|
||||
LanguageManager.t('absences.lesson'),
|
||||
LanguageManager.t('absences.subject'),
|
||||
LanguageManager.t('absences.topic'),
|
||||
LanguageManager.t('absences.status')
|
||||
];
|
||||
|
||||
headers.forEach(headerText => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = headerText;
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
||||
thead.appendChild(headerRow);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
generateAbsencesRows(absences, tbody);
|
||||
|
||||
table.appendChild(thead);
|
||||
table.appendChild(tbody);
|
||||
container.appendChild(table);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
async function transformAbsencesPage() {
|
||||
const { basicData, absences, groupedAbsences } = await collectAbsencesData();
|
||||
document.body.textContent = '';
|
||||
const container = document.createElement('div');
|
||||
container.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
headerDiv.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
container.appendChild(headerDiv);
|
||||
const main = document.createElement('main');
|
||||
main.className = 'kreta-main';
|
||||
const filterCard = createFilterCard(absences);
|
||||
main.appendChild(filterCard);
|
||||
const statsOverview = createStatsOverview(absences);
|
||||
main.appendChild(statsOverview);
|
||||
const absencesContainer = createAbsencesContainer(absences);
|
||||
main.appendChild(absencesContainer);
|
||||
|
||||
container.appendChild(main);
|
||||
document.body.appendChild(container);
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>Szűrés</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">date_range</span>
|
||||
Dátum
|
||||
</label>
|
||||
<input type="date" id="dateFilter" class="filter-input" disabled>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">school</span>
|
||||
Tantárgy
|
||||
</label>
|
||||
<select id="subjectFilter" class="filter-input">
|
||||
<option value="">Minden tantárgy</option>
|
||||
${[...new Set(absences.map(a => a.subject))].sort().map(subject =>
|
||||
`<option value="${subject}">${subject}</option>`
|
||||
).join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">check_circle</span>
|
||||
Igazolás
|
||||
</label>
|
||||
<select id="justificationFilter" class="filter-input">
|
||||
<option value="">Mindegy</option>
|
||||
<option value="justified">Igazolt</option>
|
||||
<option value="unjustified">Igazolatlan</option>
|
||||
<option value="pending">Igazolásra vár</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absences-container">
|
||||
${Object.entries(groupedAbsences).map(([date, dayAbsences]) => `
|
||||
<div class="absence-group" data-date="${date}">
|
||||
<div class="absence-date">
|
||||
<span class="material-icons-round">event</span>
|
||||
${date}
|
||||
<span class="absence-count">${dayAbsences.length} óra</span>
|
||||
</div>
|
||||
<div class="absence-list">
|
||||
${dayAbsences.map(absence => `
|
||||
<div class="absence-item"
|
||||
data-subject="${absence.subject}"
|
||||
data-justified="${absence.justified}">
|
||||
<div class="absence-time">
|
||||
<span class="material-icons-round">schedule</span>
|
||||
${absence.lesson}. óra
|
||||
</div>
|
||||
<div class="absence-details">
|
||||
<div class="absence-subject">${absence.subject}</div>
|
||||
<div class="absence-topic">${absence.topic}</div>
|
||||
</div>
|
||||
<div class="absence-status ${absence.justificationStatus}">
|
||||
${absence.justificationStatus === 'justified' ?
|
||||
`Igazolt <span class="material-icons-round">check_circle</span>` :
|
||||
absence.justificationStatus === 'unjustified' ?
|
||||
`Igazolatlan <span class="material-icons-round">cancel</span>` :
|
||||
`Igazolásra vár <span class="material-icons-round">pending</span>`}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
|
||||
setupEventListeners();
|
||||
setupFilters();
|
||||
|
||||
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function generateAbsencesRows(absences, tbody) {
|
||||
const groupedByDate = absences.reduce((groups, absence) => {
|
||||
const date = absence.date;
|
||||
if (!groups[date]) {
|
||||
groups[date] = [];
|
||||
}
|
||||
groups[date].push(absence);
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
const sortedDates = Object.keys(groupedByDate).sort(
|
||||
(a, b) => new Date(b) - new Date(a),
|
||||
);
|
||||
|
||||
sortedDates.forEach((date) => {
|
||||
const dateAbsences = groupedByDate[date];
|
||||
const divider = document.createElement('tr');
|
||||
divider.className = 'date-group-divider';
|
||||
divider.style.display = 'none';
|
||||
tbody.appendChild(divider);
|
||||
|
||||
dateAbsences.forEach((absence) => {
|
||||
const row = document.createElement('tr');
|
||||
row.className = 'table-row';
|
||||
row.dataset.subject = absence.subject;
|
||||
row.dataset.justified = absence.justified;
|
||||
row.dataset.date = absence.date;
|
||||
row.dataset.dateGroup = date;
|
||||
|
||||
const dateCell = document.createElement('td');
|
||||
dateCell.className = 'table-cell date-cell';
|
||||
dateCell.dataset.label = LanguageManager.t('absences.date');
|
||||
dateCell.textContent = absence.date;
|
||||
row.appendChild(dateCell);
|
||||
|
||||
const lessonCell = document.createElement('td');
|
||||
lessonCell.className = 'table-cell lesson-cell';
|
||||
lessonCell.dataset.label = LanguageManager.t('absences.lesson');
|
||||
lessonCell.textContent = absence.lesson + '.';
|
||||
row.appendChild(lessonCell);
|
||||
|
||||
const subjectCell = document.createElement('td');
|
||||
subjectCell.className = 'table-cell subject-cell';
|
||||
subjectCell.dataset.label = LanguageManager.t('absences.subject');
|
||||
subjectCell.textContent = absence.subject;
|
||||
row.appendChild(subjectCell);
|
||||
|
||||
const topicCell = document.createElement('td');
|
||||
topicCell.className = 'table-cell topic-cell';
|
||||
topicCell.dataset.label = LanguageManager.t('absences.topic');
|
||||
topicCell.title = absence.topic;
|
||||
topicCell.textContent = absence.topic;
|
||||
row.appendChild(topicCell);
|
||||
|
||||
const statusCell = document.createElement('td');
|
||||
statusCell.className = 'table-cell status-cell';
|
||||
statusCell.dataset.label = LanguageManager.t('absences.status');
|
||||
|
||||
const statusBadge = document.createElement('span');
|
||||
statusBadge.className = `status-badge ${absence.justificationStatus}`;
|
||||
|
||||
if (absence.justificationStatus === 'justified') {
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/BadgeCheck.svg');
|
||||
img.alt = 'Igazolt';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
statusBadge.appendChild(img);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.justified')));
|
||||
} else if (absence.justificationStatus === 'unjustified') {
|
||||
const span = document.createElement('span');
|
||||
span.className = 'material-icons-round';
|
||||
span.textContent = 'cancel';
|
||||
statusBadge.appendChild(span);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.unjustified')));
|
||||
} else {
|
||||
const span = document.createElement('span');
|
||||
span.className = 'material-icons-round';
|
||||
span.textContent = 'pending';
|
||||
statusBadge.appendChild(span);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.pending')));
|
||||
}
|
||||
|
||||
statusCell.appendChild(statusBadge);
|
||||
row.appendChild(statusCell);
|
||||
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
function setupMobileGrouping() {
|
||||
if (window.innerWidth <= 480) {
|
||||
createMobileGroups();
|
||||
} else {
|
||||
removeMobileGroups();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", setupMobileGrouping);
|
||||
|
||||
setupMobileGrouping();
|
||||
}
|
||||
|
||||
function createMobileGroups() {
|
||||
const tbody = document.querySelector(".absences-table tbody");
|
||||
if (!tbody) return;
|
||||
|
||||
removeMobileGroups();
|
||||
|
||||
const rows = Array.from(tbody.querySelectorAll(".table-row"));
|
||||
const groupedRows = {};
|
||||
|
||||
rows.forEach((row) => {
|
||||
const date = row.dataset.date;
|
||||
if (!groupedRows[date]) {
|
||||
groupedRows[date] = [];
|
||||
}
|
||||
groupedRows[date].push(row);
|
||||
});
|
||||
|
||||
const sortedDates = Object.keys(groupedRows).sort(
|
||||
(a, b) => new Date(b) - new Date(a),
|
||||
);
|
||||
|
||||
while (tbody.firstChild) {
|
||||
tbody.removeChild(tbody.firstChild);
|
||||
}
|
||||
|
||||
sortedDates.forEach((date) => {
|
||||
const dateRows = groupedRows[date];
|
||||
|
||||
const dateGroup = document.createElement("div");
|
||||
dateGroup.className = "date-group";
|
||||
|
||||
const dateHeader = document.createElement("div");
|
||||
dateHeader.className = "date-group-header";
|
||||
dateHeader.textContent = date;
|
||||
|
||||
const dateContent = document.createElement("div");
|
||||
dateContent.className = "date-group-content";
|
||||
|
||||
dateRows.forEach((row) => {
|
||||
dateContent.appendChild(row);
|
||||
});
|
||||
|
||||
dateGroup.appendChild(dateHeader);
|
||||
dateGroup.appendChild(dateContent);
|
||||
tbody.appendChild(dateGroup);
|
||||
});
|
||||
}
|
||||
|
||||
function removeMobileGroups() {
|
||||
const tbody = document.querySelector(".absences-table tbody");
|
||||
if (!tbody) return;
|
||||
|
||||
const dateGroups = tbody.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));
|
||||
});
|
||||
|
||||
while (tbody.firstChild) {
|
||||
tbody.removeChild(tbody.firstChild);
|
||||
}
|
||||
allRows.forEach((row) => tbody.appendChild(row));
|
||||
}
|
||||
|
||||
function updateDateGroupsVisibility() {
|
||||
if (window.innerWidth > 480) return;
|
||||
|
||||
const dateGroups = document.querySelectorAll(".date-group");
|
||||
|
||||
dateGroups.forEach((group) => {
|
||||
const visibleRows = group.querySelectorAll(
|
||||
'.table-row[style=""], .table-row:not([style])',
|
||||
);
|
||||
|
||||
if (visibleRows.length > 0) {
|
||||
group.style.display = "";
|
||||
} else {
|
||||
group.style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setupFilters() {
|
||||
try {
|
||||
const filters = {
|
||||
dateFilter: document.getElementById('dateFilter'),
|
||||
subject: document.getElementById('subjectFilter'),
|
||||
justified: document.getElementById('justificationFilter')
|
||||
dateFilter: document.getElementById("dateFilter"),
|
||||
subject: document.getElementById("subjectFilter"),
|
||||
justified: document.getElementById("justificationFilter"),
|
||||
};
|
||||
|
||||
|
||||
if (!filters.dateFilter || !filters.subject || !filters.justified) {
|
||||
console.warn('Some filter elements were not found in the DOM');
|
||||
console.warn("Some filter elements were not found in the DOM");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (filters.dateFilter) {
|
||||
filters.dateFilter.disabled = true;
|
||||
}
|
||||
|
||||
const filterAbsences = () => {
|
||||
try {
|
||||
|
||||
const dateFilterValue = filters.dateFilter.value;
|
||||
const subject = filters.subject.value;
|
||||
const justified = filters.justified.value;
|
||||
|
||||
|
||||
const selectedDate = dateFilterValue ? new Date(dateFilterValue) : null;
|
||||
|
||||
document.querySelectorAll('.absence-group').forEach(group => {
|
||||
const dateStr = group.dataset.date;
|
||||
const dateParts = dateStr.split('.');
|
||||
|
||||
|
||||
document.querySelectorAll(".table-row").forEach((row) => {
|
||||
const dateStr = row.dataset.date;
|
||||
const dateParts = dateStr.split(".");
|
||||
|
||||
if (dateParts.length < 3) {
|
||||
console.error(`Invalid date format: ${dateStr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const parsedDay = parseInt(dateParts[0].trim(), 10);
|
||||
|
||||
const parsedYear = parseInt(dateParts[0].trim(), 10);
|
||||
const parsedMonth = parseInt(dateParts[1].trim(), 10) - 1;
|
||||
const parsedYear = parseInt(dateParts[2].trim(), 10);
|
||||
|
||||
|
||||
const parsedDay = parseInt(dateParts[2].trim(), 10);
|
||||
|
||||
if (isNaN(parsedDay) || isNaN(parsedMonth) || isNaN(parsedYear)) {
|
||||
console.error(`Invalid date components: ${dateStr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const groupDate = new Date(parsedYear, parsedMonth, parsedDay);
|
||||
|
||||
let showGroup = true;
|
||||
|
||||
const absenceItems = group.querySelectorAll('.absence-item');
|
||||
let visibleItems = 0;
|
||||
const rowDate = new Date(parsedYear, parsedMonth, parsedDay);
|
||||
|
||||
absenceItems.forEach(item => {
|
||||
let showItem = true;
|
||||
if (subject && item.dataset.subject !== subject) showItem = false;
|
||||
|
||||
if (justified) {
|
||||
const statusElement = item.querySelector('.absence-status');
|
||||
const hasStatus = statusElement.classList.contains(justified);
|
||||
if (!hasStatus) showItem = false;
|
||||
let showRow = true;
|
||||
|
||||
if (selectedDate) {
|
||||
if (
|
||||
rowDate.getFullYear() !== selectedDate.getFullYear() ||
|
||||
rowDate.getMonth() !== selectedDate.getMonth() ||
|
||||
rowDate.getDate() !== selectedDate.getDate()
|
||||
) {
|
||||
showRow = false;
|
||||
}
|
||||
}
|
||||
|
||||
item.style.display = showItem ? '' : 'none';
|
||||
if (showItem) visibleItems++;
|
||||
});
|
||||
if (subject && row.dataset.subject !== subject) {
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
group.style.display = (showGroup && visibleItems > 0) ? '' : 'none';
|
||||
if (justified) {
|
||||
const statusElement = row.querySelector(".status-badge");
|
||||
const hasStatus = statusElement.classList.contains(justified);
|
||||
if (!hasStatus) showRow = false;
|
||||
}
|
||||
|
||||
row.style.display = showRow ? "" : "none";
|
||||
});
|
||||
|
||||
updateDateGroupsVisibility();
|
||||
updateStatistics();
|
||||
} catch (err) {
|
||||
|
||||
console.error('Error during filtering absences:', err);
|
||||
console.error("Error during filtering absences:", err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Object.values(filters).forEach(filter => {
|
||||
|
||||
Object.values(filters).forEach((filter) => {
|
||||
try {
|
||||
if (filter && filter !== filters.dateFilter) {
|
||||
filter.addEventListener('change', filterAbsences);
|
||||
if (filter) {
|
||||
filter.addEventListener("change", filterAbsences);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message && err.message.includes('Extension context invalidated')) {
|
||||
console.warn('Extension context invalidated during event listener setup');
|
||||
if (
|
||||
err.message &&
|
||||
err.message.includes("Extension context invalidated")
|
||||
) {
|
||||
console.warn(
|
||||
"Extension context invalidated during event listener setup",
|
||||
);
|
||||
} else {
|
||||
console.error('Error setting up filter event listener:', err);
|
||||
console.error("Error setting up filter event listener:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
filterAbsences();
|
||||
} catch (err) {
|
||||
|
||||
if (err.message && err.message.includes('Extension context invalidated')) {
|
||||
console.warn('Extension context invalidated during filter setup');
|
||||
if (err.message && err.message.includes("Extension context invalidated")) {
|
||||
console.warn("Extension context invalidated during filter setup");
|
||||
} else {
|
||||
console.error('Error setting up filters:', err);
|
||||
console.error("Error setting up filters:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatistics() {
|
||||
try {
|
||||
const visibleRows = document.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
const totalVisible = visibleRows.length;
|
||||
const justifiedVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.justified"),
|
||||
).length;
|
||||
const unjustifiedVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.unjustified"),
|
||||
).length;
|
||||
const pendingVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.pending"),
|
||||
).length;
|
||||
|
||||
if (window.location.href.includes('/Hianyzas/Hianyzasok')) {
|
||||
transformAbsencesPage().catch(error => {
|
||||
console.error('Hiba történt az oldal átalakítása során:', error);
|
||||
const statCards = document.querySelectorAll(".stat-card");
|
||||
if (statCards[0])
|
||||
statCards[0].querySelector(".stat-number").textContent = totalVisible;
|
||||
if (statCards[1])
|
||||
statCards[1].querySelector(".stat-number").textContent = justifiedVisible;
|
||||
if (statCards[2])
|
||||
statCards[2].querySelector(".stat-number").textContent =
|
||||
unjustifiedVisible;
|
||||
if (statCards[3])
|
||||
statCards[3].querySelector(".stat-number").textContent = pendingVisible;
|
||||
} catch (err) {
|
||||
console.error("Error updating statistics:", err);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.location.href.includes("/Hianyzas/Hianyzasok")) {
|
||||
transformAbsencesPage().catch((error) => {
|
||||
console.error(LanguageManager.t("absences.page_transform_error"), error);
|
||||
});
|
||||
}
|
||||
@@ -14,6 +14,10 @@ body {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: #00000000 !important;
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
@@ -35,42 +39,239 @@ body {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
|
||||
.card {
|
||||
.widget-card {
|
||||
background: var(--card-card);
|
||||
padding: 20px;
|
||||
padding-top: 5px !important;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 0.5s ease forwards;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
border: none;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.widget-header {
|
||||
padding: 20px 20px 0 20px;
|
||||
background: var(--card-card) !important;
|
||||
}
|
||||
|
||||
.widget-card-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.widget-content {
|
||||
flex: 1;
|
||||
padding: 0 20px;
|
||||
background: var(--card-card);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.widget-footer {
|
||||
padding: 0px 20px 20px 20px;
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.widget-link {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
margin: 0;
|
||||
padding: 20px 0 16px 0;
|
||||
}
|
||||
|
||||
.card:last-child {
|
||||
grid-column: 1 / -1;
|
||||
}
|
||||
|
||||
|
||||
.grade-item, .absence-item, .note-item, .exam-item, .news-item {
|
||||
border-radius: 6px;
|
||||
.widget-item {
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
border: 1px solid var(--card-card);
|
||||
border: none;
|
||||
background: var(--card-card);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 12px;
|
||||
padding: 12px;
|
||||
padding: 8px;
|
||||
position: relative;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
.widget-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
gap: 12px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.widget-row.grade-row {
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.widget-details {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.widget-details.grade-details {
|
||||
flex: 1;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.widget-title {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 1.3;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.widget-subtitle {
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 1.2;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.widget-content {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.widget-date {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.grade-type-with-date {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.grade-type-with-date .grade-type {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.note-author {
|
||||
color: var(--text-tertiary);
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
margin-top: 4px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.grade-date {
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
white-space: nowrap;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.widget-author {
|
||||
color: var(--text-tertiary);
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.news-author {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
text-align: right;
|
||||
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 {
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.grade {
|
||||
width: 32px;
|
||||
@@ -84,16 +285,32 @@ body {
|
||||
color: var(--text-primary);
|
||||
font-size: 22px;
|
||||
}
|
||||
.subject-name, .absence-type, .note-title, .exam-subject {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
|
||||
.news-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.grade-type, .absence-date, .note-date, .exam-date {
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
|
||||
.news-content {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.exam-type {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
display: inline-flex;
|
||||
@@ -174,21 +391,24 @@ body {
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--accent-15);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dropdown-item svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
.subject-name, .absence-type, .note-title, .exam-subject {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
|
||||
.news-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.grade-type, .absence-date, .note-date, .exam-date {
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
|
||||
.news-content {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
@@ -212,22 +432,12 @@ body {
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
|
||||
.grade-row {
|
||||
.exam-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.grade-details {
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.grade-date, .exam-date {
|
||||
gap: 8px;
|
||||
margin-top: 4px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.exam-info {
|
||||
|
||||
@@ -1,325 +1,588 @@
|
||||
const utils = {
|
||||
const DashboardUtils = {
|
||||
formatGradeValue(value) {
|
||||
const trimmedValue = value?.trim() || '';
|
||||
if (trimmedValue.toLowerCase() === 'szöveges') {
|
||||
return 'Sz';
|
||||
const trimmedValue = value?.trim() || "";
|
||||
if (trimmedValue.toLowerCase() === "szöveges") {
|
||||
return "Sz";
|
||||
}
|
||||
return trimmedValue;
|
||||
},
|
||||
|
||||
parseDate(dateStr) {
|
||||
return dateStr?.trim() || '';
|
||||
return dateStr?.trim() || "";
|
||||
},
|
||||
|
||||
|
||||
formatHungarianDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
|
||||
const dateParts = dateStr.trim().split('.');
|
||||
if (!dateStr) return "";
|
||||
|
||||
const dateParts = dateStr.trim().split(".");
|
||||
if (dateParts.length < 3) return dateStr;
|
||||
|
||||
|
||||
const month = parseInt(dateParts[1], 10);
|
||||
const day = parseInt(dateParts[2], 10);
|
||||
|
||||
|
||||
if (isNaN(month) || month < 1 || month > 12) return dateStr;
|
||||
|
||||
const hungarianMonths = [
|
||||
'január', 'február', 'március', 'április', 'május', 'június',
|
||||
'július', 'augusztus', 'szeptember', 'október', 'november', 'december'
|
||||
|
||||
if (typeof window.LanguageManager !== "undefined") {
|
||||
const monthKeys = [
|
||||
"months.january",
|
||||
"months.february",
|
||||
"months.march",
|
||||
"months.april",
|
||||
"months.may",
|
||||
"months.june",
|
||||
"months.july",
|
||||
"months.august",
|
||||
"months.september",
|
||||
"months.october",
|
||||
"months.november",
|
||||
"months.december",
|
||||
];
|
||||
const monthName = window.LanguageManager.t(monthKeys[month - 1]);
|
||||
return `${monthName} ${day}.`;
|
||||
}
|
||||
|
||||
const monthKeys = [
|
||||
"months.january",
|
||||
"months.february",
|
||||
"months.march",
|
||||
"months.april",
|
||||
"months.may",
|
||||
"months.june",
|
||||
"months.july",
|
||||
"months.august",
|
||||
"months.september",
|
||||
"months.october",
|
||||
"months.november",
|
||||
"months.december",
|
||||
];
|
||||
|
||||
return `${hungarianMonths[month - 1]} ${day}.`;
|
||||
}
|
||||
|
||||
return `${LanguageManager.t(monthKeys[month - 1])} ${day}.`;
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
class DashboardDataExtractor {
|
||||
class DashboardDataManager {
|
||||
constructor() {
|
||||
this.data = {
|
||||
this.dashboardData = {
|
||||
grades: [],
|
||||
absences: [],
|
||||
notes: [],
|
||||
upcomingExams: [],
|
||||
news: []
|
||||
news: [],
|
||||
};
|
||||
}
|
||||
|
||||
extractGrades() {
|
||||
const gradeRows = document.querySelectorAll('#legutobbiErtekelesek tr:not(:first-child)');
|
||||
|
||||
this.data.grades = Array.from(gradeRows).map(row => {
|
||||
const gradeValue = row.querySelector('span[style*="font-size: 200%"]')?.textContent;
|
||||
const gradeInfo = row.querySelector('span[style*="float: right"]')?.textContent;
|
||||
|
||||
if (!gradeValue || !gradeInfo) return null;
|
||||
extractGradeData() {
|
||||
const gradeRows = document.querySelectorAll(
|
||||
"#legutobbiErtekelesek tr:not(:first-child)",
|
||||
);
|
||||
|
||||
const [fullSubject, date] = gradeInfo.split('\n').map(str => str.trim());
|
||||
const { subject, type } = this.parseSubjectInfo(fullSubject);
|
||||
this.dashboardData.grades = Array.from(gradeRows)
|
||||
.map((row) => {
|
||||
const gradeValue = row.querySelector(
|
||||
'span[style*="font-size: 200%"]',
|
||||
)?.textContent;
|
||||
const gradeInfo = row.querySelector(
|
||||
'span[style*="float: right"]',
|
||||
)?.textContent;
|
||||
|
||||
if (!gradeValue || !gradeInfo) return null;
|
||||
|
||||
const [fullSubject, date] = gradeInfo
|
||||
.split("\n")
|
||||
.map((str) => str.trim());
|
||||
const { subject, type, dateInSubject } =
|
||||
this.parseSubjectInformation(fullSubject);
|
||||
|
||||
return {
|
||||
value: DashboardUtils.formatGradeValue(gradeValue),
|
||||
subject,
|
||||
date: DashboardUtils.parseDate(date),
|
||||
type: type || LanguageManager.t("dashboard.evaluation"),
|
||||
dateInSubject: dateInSubject || null,
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
parseSubjectInformation(fullSubject) {
|
||||
const hungarianMonths = [
|
||||
"január",
|
||||
"február",
|
||||
"március",
|
||||
"április",
|
||||
"május",
|
||||
"június",
|
||||
"július",
|
||||
"augusztus",
|
||||
"szeptember",
|
||||
"október",
|
||||
"november",
|
||||
"december",
|
||||
];
|
||||
const monthPattern = hungarianMonths.join("|");
|
||||
const datePattern = new RegExp(`(${monthPattern})\\s+(\\d{1,2})\\.?$`, "i");
|
||||
const dateMatch = fullSubject.match(datePattern);
|
||||
|
||||
if (dateMatch) {
|
||||
const subjectPart = fullSubject.substring(0, dateMatch.index).trim();
|
||||
const datePart = dateMatch[0].trim();
|
||||
return {
|
||||
value: utils.formatGradeValue(gradeValue),
|
||||
subject,
|
||||
date: utils.parseDate(date),
|
||||
type: type || 'Értékelés'
|
||||
subject: subjectPart,
|
||||
type: "",
|
||||
dateInSubject: datePart,
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}
|
||||
}
|
||||
|
||||
parseSubjectInfo(fullSubject) {
|
||||
const months = ['január', 'február', 'március', 'április', 'május', 'június',
|
||||
'július', 'augusztus', 'szeptember', 'október', 'november', 'december'];
|
||||
const monthPattern = new RegExp(months.join('|'), 'i');
|
||||
const monthMatch = fullSubject.match(monthPattern);
|
||||
|
||||
if (!monthMatch) return { subject: fullSubject, type: '' };
|
||||
|
||||
const monthIndex = fullSubject.lastIndexOf(monthMatch[0]);
|
||||
return {
|
||||
subject: fullSubject.substring(0, monthIndex).trim(),
|
||||
type: fullSubject.substring(monthIndex).trim()
|
||||
};
|
||||
}
|
||||
|
||||
extractAbsences() {
|
||||
const absenceRows = document.querySelectorAll('#legutobbiMulasztasok tr:not(:first-child)');
|
||||
|
||||
this.data.absences = Array.from(absenceRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 4) return null;
|
||||
const months = [
|
||||
LanguageManager.t("months.january"),
|
||||
LanguageManager.t("months.february"),
|
||||
LanguageManager.t("months.march"),
|
||||
LanguageManager.t("months.april"),
|
||||
LanguageManager.t("months.may"),
|
||||
LanguageManager.t("months.june"),
|
||||
LanguageManager.t("months.july"),
|
||||
LanguageManager.t("months.august"),
|
||||
LanguageManager.t("months.september"),
|
||||
LanguageManager.t("months.october"),
|
||||
LanguageManager.t("months.november"),
|
||||
LanguageManager.t("months.december"),
|
||||
];
|
||||
const fallbackMonthPattern = new RegExp(months.join("|"), "i");
|
||||
const monthMatch = fullSubject.match(fallbackMonthPattern);
|
||||
|
||||
if (monthMatch) {
|
||||
const monthIndex = fullSubject.lastIndexOf(monthMatch[0]);
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || '',
|
||||
day: spans[2]?.textContent?.trim() || '',
|
||||
type: spans[1]?.textContent?.trim() || '',
|
||||
count: spans[3]?.textContent?.trim() || ''
|
||||
subject: fullSubject.substring(0, monthIndex).trim(),
|
||||
type: fullSubject.substring(monthIndex).trim(),
|
||||
};
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
return { subject: fullSubject, type: "" };
|
||||
}
|
||||
|
||||
extractNotes() {
|
||||
const noteRows = document.querySelectorAll('#legutobbiFeljegyzesek tr:not(:first-child)');
|
||||
|
||||
this.data.notes = Array.from(noteRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 3) return null;
|
||||
extractAbsenceData() {
|
||||
const absenceRows = document.querySelectorAll(
|
||||
"#legutobbiMulasztasok tr:not(:first-child)",
|
||||
);
|
||||
|
||||
return {
|
||||
title: spans[0]?.textContent?.trim() || '',
|
||||
author: spans[1]?.textContent?.trim() || '',
|
||||
date: spans[2]?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(Boolean);
|
||||
this.dashboardData.absences = Array.from(absenceRows)
|
||||
.map((row) => {
|
||||
const spans = row.querySelectorAll("span");
|
||||
if (spans.length < 4) return null;
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || "",
|
||||
day: spans[2]?.textContent?.trim() || "",
|
||||
type: spans[1]?.textContent?.trim() || "",
|
||||
count: spans[3]?.textContent?.trim() || "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
extractExams() {
|
||||
const examRows = document.querySelectorAll('#legutobbiBejelentettSzamonkeres tr:not(:first-child)');
|
||||
|
||||
this.data.upcomingExams = Array.from(examRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 4) return null;
|
||||
extractNoteData() {
|
||||
const noteRows = document.querySelectorAll(
|
||||
"#legutobbiFeljegyzesek tr:not(:first-child)",
|
||||
);
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || '',
|
||||
subject: spans[1]?.textContent?.trim() || '',
|
||||
day: spans[2]?.textContent?.trim() || '',
|
||||
type: spans[3]?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(Boolean);
|
||||
this.dashboardData.notes = Array.from(noteRows)
|
||||
.map((row) => {
|
||||
const spans = row.querySelectorAll("span");
|
||||
if (spans.length < 3) return null;
|
||||
|
||||
return {
|
||||
title: spans[0]?.textContent?.trim() || "",
|
||||
author: spans[1]?.textContent?.trim() || "",
|
||||
date: spans[2]?.textContent?.trim() || "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
extractNews() {
|
||||
const newsContainer = document.querySelector('.faliujsag-lista, #faliujsagLista');
|
||||
if (!newsContainer) return;
|
||||
|
||||
const newsItems = newsContainer.querySelectorAll('.nb-item, .news-item');
|
||||
|
||||
this.data.news = Array.from(newsItems).map(item => {
|
||||
const titleElement = item.querySelector('.subject h4, .news-title');
|
||||
const contentElement = item.querySelector('.content, .news-content');
|
||||
|
||||
|
||||
const dateElement = item.querySelector('.nb-date, .news-date');
|
||||
let dateStr = '';
|
||||
|
||||
if (dateElement) {
|
||||
const yearElement = dateElement.querySelector('.year');
|
||||
const monthElement = dateElement.querySelector('.month');
|
||||
const dayElement = dateElement.querySelector('.day');
|
||||
|
||||
if (yearElement && monthElement && dayElement) {
|
||||
dateStr = `${yearElement.textContent} ${monthElement.textContent} ${dayElement.textContent}`;
|
||||
} else {
|
||||
dateStr = dateElement.textContent;
|
||||
}
|
||||
extractExamData() {
|
||||
const examRows = document.querySelectorAll(
|
||||
"#legutobbiBejelentettSzamonkeres tr:not(:first-child)",
|
||||
);
|
||||
|
||||
this.dashboardData.upcomingExams = Array.from(examRows)
|
||||
.map((row) => {
|
||||
const spans = row.querySelectorAll("span");
|
||||
if (spans.length < 4) return null;
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || "",
|
||||
subject: spans[1]?.textContent?.trim() || "",
|
||||
day: spans[2]?.textContent?.trim() || "",
|
||||
type: spans[3]?.textContent?.trim() || "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
async extractNewsData() {
|
||||
try {
|
||||
const timestamp = Date.now();
|
||||
const apiUrl = `https://${window.location.hostname}/Intezmeny/Faliujsag/GetMoreEntries?startindex=0&range=10&_=${timestamp}`;
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json, text/javascript, */*; q=0.01",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API request failed with status: ${response.status}`);
|
||||
}
|
||||
|
||||
|
||||
const authorElement = item.querySelector('.auth-name span, .news-author');
|
||||
|
||||
return {
|
||||
title: titleElement?.textContent?.trim() || '',
|
||||
date: dateStr.trim(),
|
||||
content: contentElement?.textContent?.trim() || '',
|
||||
author: authorElement?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(news => news.title || news.content);
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.FaliujsagElemek || !Array.isArray(data.FaliujsagElemek)) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.FaliujsagElemek.forEach((item, index) => {
|
||||
let formattedDate = "";
|
||||
if (item.DatumNap && item.DatumHonap && item.DatumEv) {
|
||||
formattedDate = `${item.DatumEv}. ${item.DatumHonap} ${item.DatumNap}.`;
|
||||
} else if (item.Idopont) {
|
||||
const match = item.Idopont.match(/\/Date\((\d+)\)\//);
|
||||
if (match) {
|
||||
const timestamp = parseInt(match[1]);
|
||||
const date = new Date(timestamp);
|
||||
formattedDate = date.toLocaleDateString("hu-HU");
|
||||
}
|
||||
}
|
||||
|
||||
if (!formattedDate) {
|
||||
formattedDate = new Date().toLocaleDateString("hu-HU");
|
||||
}
|
||||
|
||||
let cleanContent = item.EsemenySzovege || "";
|
||||
cleanContent = cleanContent.replace(/<[^>]*>/g, "");
|
||||
cleanContent = cleanContent.replace(/\r\n/g, " ");
|
||||
cleanContent = cleanContent.replace(/\s+/g, " ").trim();
|
||||
|
||||
const newsItem = {
|
||||
title: item.EsemenyCime || `Hír ${index + 1}`,
|
||||
content: cleanContent || "Nincs elérhető tartalom",
|
||||
date: formattedDate,
|
||||
author: `${item.Nev || "Ismeretlen"} (${item.Munkakor || "Ismeretlen"})`,
|
||||
};
|
||||
|
||||
this.dashboardData.news.push(newsItem);
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("❌ Error fetching news from API:", error);
|
||||
}
|
||||
}
|
||||
|
||||
extractAll() {
|
||||
this.extractGrades();
|
||||
this.extractAbsences();
|
||||
this.extractNotes();
|
||||
this.extractExams();
|
||||
this.extractNews();
|
||||
return this.data;
|
||||
async extractAllData() {
|
||||
this.extractGradeData();
|
||||
this.extractAbsenceData();
|
||||
this.extractNoteData();
|
||||
this.extractExamData();
|
||||
await this.extractNewsData();
|
||||
return this.dashboardData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DashboardUI {
|
||||
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) || ''
|
||||
name:
|
||||
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,
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
||||
}
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
|
||||
this.shortenedSchoolName = helper.shortenSchoolName(this.schoolNameFull);
|
||||
}
|
||||
|
||||
generateMainContentHTML() {
|
||||
generateMainContent() {
|
||||
return `
|
||||
<main class="kreta-main">
|
||||
<div class="grid-container">
|
||||
${this.generateGradeCard()}
|
||||
${this.generateAbsenceCard()}
|
||||
${this.generateNoteCard()}
|
||||
${this.generateExamCard()}
|
||||
${this.generateNewsCard()}
|
||||
${this.createGradeCard()}
|
||||
${this.createAbsenceCard()}
|
||||
${this.createNoteCard()}
|
||||
${this.createExamCard()}
|
||||
${this.createNewsCard()}
|
||||
</div>
|
||||
</main>
|
||||
`;
|
||||
}
|
||||
generateNewsCard() {
|
||||
const newsItems = this.data.news.map(news => `
|
||||
<div class="news-item">
|
||||
<div class="news-header">
|
||||
<div class="news-date">${news.date}</div>
|
||||
${news.author ? `<div class="news-author">${news.author}</div>` : ''}
|
||||
</div>
|
||||
<div class="news-details">
|
||||
<h3 class="news-title">${news.title}</h3>
|
||||
<div class="news-content">${news.content}</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
|
||||
return this.generateCard('Hírek', newsItems || 'Jelenleg ez egy nem támogatott funkció', '/Intezmeny/Faliujsag', 'Összes hír');
|
||||
}
|
||||
generateGradeCard() {
|
||||
const gradeItems = this.data.grades.map(grade => `
|
||||
<div class="grade-item">
|
||||
<div class="grade-row">
|
||||
<div class="grade grade-${grade.value}">${grade.value}</div>
|
||||
<div class="grade-details">
|
||||
<div class="subject-name">${grade.subject}</div>
|
||||
<div class="grade-type">${grade.type}</div>
|
||||
createNewsCard() {
|
||||
const newsItems = this.data.news
|
||||
.map(
|
||||
(news) => `
|
||||
<div class="widget-item news-item">
|
||||
<div class="widget-row">
|
||||
<div class="widget-details news-details">
|
||||
<div class="widget-title news-title">${news.title}</div>
|
||||
<div class="widget-content news-content">${news.content}</div>
|
||||
</div>
|
||||
<div class="widget-meta">
|
||||
${news.date ? `<div class="widget-date news-date">${news.date}</div>` : ""}
|
||||
${news.author ? `<div class="widget-author news-author">${news.author}</div>` : ""}
|
||||
</div>
|
||||
${grade.date ? `<div class="grade-date">${grade.date}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.generateCard('Értékeléseid', gradeItems, '/TanuloErtekeles/Osztalyzatok', 'Összes jegyed');
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.news"),
|
||||
newsItems || LanguageManager.t("dashboard.not_supported"),
|
||||
"/Intezmeny/Faliujsag",
|
||||
LanguageManager.t("dashboard.all_news"),
|
||||
);
|
||||
}
|
||||
generateAbsenceCard() {
|
||||
const absenceItems = this.data.absences.map(absence => `
|
||||
<div class="absence-item">
|
||||
<div class="absence-details">
|
||||
<div class="absence-type">${absence.type}</div>
|
||||
<div class="absence-date">${absence.date}</div>
|
||||
|
||||
createGradeCard() {
|
||||
const gradeItems = this.data.grades
|
||||
.map(
|
||||
(grade) => `
|
||||
<div class="widget-item grade-item">
|
||||
<div class="widget-row grade-row">
|
||||
<div class="grade grade-${grade.value}">${grade.value}</div>
|
||||
<div class="widget-details grade-details">
|
||||
<div class="widget-title subject-name">${grade.subject}</div>
|
||||
<div class="grade-type-with-date">
|
||||
<div class="widget-subtitle grade-type">${grade.type}</div>
|
||||
${grade.dateInSubject || grade.date ? `<div class="widget-subtitle grade-date">${grade.dateInSubject || grade.date}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.generateCard('Mulasztások', absenceItems, '/Hianyzas/Hianyzasok', 'Összes mulasztás');
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.grades"),
|
||||
gradeItems,
|
||||
"/TanuloErtekeles/Osztalyzatok",
|
||||
LanguageManager.t("dashboard.all_grades"),
|
||||
);
|
||||
}
|
||||
generateNoteCard() {
|
||||
const noteItems = this.data.notes.map(note => `
|
||||
<div class="note-item">
|
||||
<div class="note-details">
|
||||
<div class="note-title">${note.title}</div>
|
||||
<div class="note-date">${note.date}</div>
|
||||
|
||||
createAbsenceCard() {
|
||||
const absenceItems = this.data.absences
|
||||
.map(
|
||||
(absence) => `
|
||||
<div class="widget-item absence-item">
|
||||
<div class="widget-row">
|
||||
<div class="widget-details absence-details">
|
||||
<div class="widget-title absence-type">${absence.type}</div>
|
||||
<div class="widget-subtitle absence-date">${absence.date}</div>
|
||||
</div>
|
||||
${absence.day ? `<div class="widget-date">${absence.day}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.generateCard('Feljegyzések', noteItems, '/TanuloErtekeles/InformaciokFeljegyzesek', 'Összes üzeneted');
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.absences"),
|
||||
absenceItems,
|
||||
"/Hianyzas/Hianyzasok",
|
||||
LanguageManager.t("dashboard.all_absences"),
|
||||
);
|
||||
}
|
||||
generateExamCard() {
|
||||
const examItems = this.data.upcomingExams.map(exam => `
|
||||
<div class="exam-item">
|
||||
<div class="exam-details">
|
||||
<div class="exam-subject">${exam.subject}</div>
|
||||
<div class="exam-date">${utils.formatHungarianDate(exam.date)}</div>
|
||||
|
||||
createNoteCard() {
|
||||
const noteItems = this.data.notes
|
||||
.map(
|
||||
(note) => `
|
||||
<div class="widget-item note-item">
|
||||
<div class="widget-row">
|
||||
<div class="widget-details note-details">
|
||||
<div class="widget-title note-title">${note.title}</div>
|
||||
<div class="widget-subtitle note-date">${note.date}</div>
|
||||
</div>
|
||||
${note.author ? `<div class="widget-author note-author">${note.author}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.generateCard('Bejelentett dolgozatok', examItems, '/Tanulo/TanuloBejelentettSzamonkeresek', 'Összes dolgozat');
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.notes"),
|
||||
noteItems,
|
||||
"/TanuloErtekeles/InformaciokFeljegyzesek",
|
||||
LanguageManager.t("dashboard.all_messages"),
|
||||
);
|
||||
}
|
||||
generateCard(title, content, linkHref, linkText) {
|
||||
|
||||
createExamCard() {
|
||||
const examItems = this.data.upcomingExams
|
||||
.map(
|
||||
(exam) => `
|
||||
<div class="widget-item exam-item">
|
||||
<div class="widget-row">
|
||||
<div class="widget-details exam-details">
|
||||
<div class="widget-title exam-subject">${exam.subject}</div>
|
||||
<div class="widget-subtitle exam-type">${exam.type || ""}</div>
|
||||
</div>
|
||||
<div class="widget-date exam-date">${DashboardUtils.formatHungarianDate(exam.date)}</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.exams"),
|
||||
examItems,
|
||||
"/Tanulo/TanuloBejelentettSzamonkeresek",
|
||||
LanguageManager.t("dashboard.all_exams"),
|
||||
);
|
||||
}
|
||||
|
||||
createCard(title, content, linkHref, linkText) {
|
||||
return `
|
||||
<div class="card">
|
||||
<h2>${title}</h2>
|
||||
<div class="card-content">
|
||||
${content || `Jelenleg ez egy nem támogatott funkció`}
|
||||
<a href="${linkHref}" class="more-link">
|
||||
<div class="widget-card card">
|
||||
<div class="widget-header">
|
||||
<h2 class="widget-card-title">${title}</h2>
|
||||
</div>
|
||||
<div class="widget-content card-content">
|
||||
${content || `<div class="widget-empty">${LanguageManager.t("dashboard.not_supported")}</div>`}
|
||||
</div>
|
||||
<div class="widget-footer">
|
||||
<a href="${linkHref}" class="widget-link more-link">
|
||||
${linkText}
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
|
||||
<path d="M11.2997 5.19947L5.64282 5.19947M11.2997 5.19947L11.2997 10.8563M11.2997 5.19947L4.70001 11.7991" stroke="var(--accent-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
${this.generateMainContentHTML()}
|
||||
</div>
|
||||
`;
|
||||
|
||||
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(await createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(headerDiv);
|
||||
const mainContentDiv = document.createElement('div');
|
||||
const parser2 = new DOMParser();
|
||||
const mainDoc = parser2.parseFromString(this.generateMainContent(), 'text/html');
|
||||
const mainContent = mainDoc.body;
|
||||
while (mainContent.firstChild) {
|
||||
mainContentDiv.appendChild(mainContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(mainContentDiv);
|
||||
|
||||
document.body.appendChild(kretaContainer);
|
||||
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
class DashboardApp {
|
||||
class DashboardApplication {
|
||||
constructor() {
|
||||
this.initialize();
|
||||
this.init();
|
||||
}
|
||||
|
||||
async initialize() {
|
||||
if (!window.location.href.includes('/Intezmeny/Faliujsag')) return;
|
||||
|
||||
async init() {
|
||||
if (!window.location.href.includes("/Intezmeny/Faliujsag")) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (
|
||||
typeof window.LanguageManager === "undefined" ||
|
||||
!window.LanguageManager.t("dashboard.grades") ||
|
||||
window.LanguageManager.t("dashboard.grades") === "dashboard.grades"
|
||||
) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
}
|
||||
|
||||
while (!document.querySelector(".faliujsag-lista, #faliujsagLista")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
let newsItemsFound = false;
|
||||
let attempts = 0;
|
||||
const maxAttempts = 50;
|
||||
|
||||
while (!newsItemsFound && attempts < maxAttempts) {
|
||||
const newsContainer = document.querySelector(
|
||||
".faliujsag-lista, #faliujsagLista",
|
||||
);
|
||||
if (newsContainer) {
|
||||
const possibleSelectors = [
|
||||
".nb-item",
|
||||
".news-item",
|
||||
".faliujsag-item",
|
||||
".list-group-item",
|
||||
"li",
|
||||
'div[class*="item"]',
|
||||
'div[class*="news"]',
|
||||
];
|
||||
|
||||
for (const selector of possibleSelectors) {
|
||||
const items = newsContainer.querySelectorAll(selector);
|
||||
if (items.length > 0) {
|
||||
newsItemsFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!newsItemsFound) {
|
||||
if (
|
||||
newsContainer.children.length > 0 ||
|
||||
newsContainer.textContent.trim().length > 0
|
||||
) {
|
||||
newsItemsFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!newsItemsFound) {
|
||||
attempts++;
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const dataExtractor = new DashboardDataExtractor();
|
||||
const dashboardData = dataExtractor.extractAll();
|
||||
createTemplate.importFonts();
|
||||
const ui = new DashboardUI(dashboardData);
|
||||
ui.render();
|
||||
const dataManager = new DashboardDataManager();
|
||||
const dashboardData = await dataManager.extractAllData();
|
||||
|
||||
const renderer = new DashboardRenderer(dashboardData);
|
||||
await renderer.render();
|
||||
} catch (error) {
|
||||
console.error('Error initializing dashboard:', error);
|
||||
console.error("Error initializing dashboard:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new DashboardApp();
|
||||
new DashboardApplication();
|
||||
|
||||
BIN
fonts/Icons.woff2
Normal file
@@ -1,202 +1,57 @@
|
||||
:root {
|
||||
--primary: #050B15;
|
||||
--secondary: #3F444F;
|
||||
--tertiary: #1C469A;
|
||||
--icon: #0A2456;
|
||||
--accent: #3673EE;
|
||||
--bg: #DAE4F7;
|
||||
--card: #EDF3FF;
|
||||
--cardsec: #FBFCFF;
|
||||
--error: #E32D2D;
|
||||
--error-bg: rgba(227, 45, 45, 0.05);
|
||||
}
|
||||
|
||||
:root[data-theme="dark"] {
|
||||
--primary: #EBF1FD;
|
||||
--secondary: #CFD8E9;
|
||||
--tertiary: #AEC8FC;
|
||||
--icon: #BAD1FF;
|
||||
--accent: #3673ed;
|
||||
--bg: #070A0E;
|
||||
--card: #0F131B;
|
||||
--cardsec: #131822;
|
||||
--error: #FF4444;
|
||||
--error-bg: rgba(255, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--primary);
|
||||
background-color: var(--bg) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.forgot-container {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.forgot-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--icon);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
background: var(--card);
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.forgot-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--primary);
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
color: var(--secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 12px 16px;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
font-family: "Montserrat", serif;
|
||||
background: var(--cardsec);
|
||||
color: var(--primary);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--secondary);
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
.help-link:hover {
|
||||
color: var(--tertiary);
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
padding: 12px 24px;
|
||||
background: var(--accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-family: "Montserrat", serif;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-submit:hover {
|
||||
background: var(--tertiary);
|
||||
}
|
||||
|
||||
.btn-submit:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: var(--error);
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
}
|
||||
|
||||
.g-recaptcha {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.forgot-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
body.maintenance-mode {
|
||||
margin:0;
|
||||
padding:0;
|
||||
height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
background-color:var(--background);
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
body {
|
||||
background-color:var(--background) !important;
|
||||
}
|
||||
.maintenance-container {
|
||||
text-align:center;
|
||||
padding:2rem;
|
||||
border-radius:8px;
|
||||
background-color:var(--card-card);
|
||||
box-shadow:0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width:600px;
|
||||
width:90%;
|
||||
}
|
||||
.maintenance-logo {
|
||||
width:128px;
|
||||
height:128px;
|
||||
margin:0 auto 2rem;
|
||||
}
|
||||
.maintenance-title {
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
margin-bottom:1rem;
|
||||
color:var(--accent-accent);
|
||||
font-family:'Montserrat',sans-serif;
|
||||
}
|
||||
.maintenance-message {
|
||||
font-size:1rem;
|
||||
line-height:1.5;
|
||||
margin-bottom:1.5rem;
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
.maintenance-footer {
|
||||
font-size:0.875rem;
|
||||
color:var(--text-secondary);
|
||||
margin-top:2rem;
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
.maintenance-cactus {
|
||||
position:fixed;
|
||||
bottom:0px;
|
||||
right:20px;
|
||||
width:120px;
|
||||
height:120px;
|
||||
opacity:1;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
@@ -1,147 +1,290 @@
|
||||
(() => {
|
||||
const transformForgotPasswordPage = () => {
|
||||
const isDarkMode = localStorage.getItem('darkMode') === 'true';
|
||||
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
|
||||
|
||||
chrome.runtime.onMessage.addListener((message) => {
|
||||
if (message.action === 'toggleTheme') {
|
||||
document.documentElement.setAttribute('data-theme', message.darkMode ? 'dark' : 'light');
|
||||
localStorage.setItem('darkMode', message.darkMode);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="forgot-container">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet">
|
||||
|
||||
// reCAPTCHA functionality removed for security compliance
|
||||
|
||||
const loadDependencies = async () => {
|
||||
// reCAPTCHA functionality removed for security compliance
|
||||
// Extension now works without external script dependencies
|
||||
};
|
||||
|
||||
const createPageStructure = () => {
|
||||
// Biztonságos DOM létrehozás innerHTML helyett
|
||||
document.body.innerHTML = '';
|
||||
// Biztonságos HTML parsing DOMParser használatával
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(`
|
||||
<div class="forgot-container">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet">
|
||||
<style>
|
||||
.g-recaptcha {
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="forgot-card">
|
||||
<header class="forgot-header">
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
<img src="${chrome.runtime.getURL("images/firka_logo.png")}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="forgot-card">
|
||||
<h1 class="forgot-title">Elfelejtett jelszó</h1>
|
||||
|
||||
<form id="forgotForm" novalidate>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="username">OM azonosítód</label>
|
||||
<input type="text" id="username" name="username" class="form-control"
|
||||
placeholder="Add meg az OM azonosítód" required>
|
||||
<div class="error-message">Kérjük, add meg az OM azonosítód.</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="email">E-mail cím</label>
|
||||
<input type="email" id="email" name="email" class="form-control"
|
||||
placeholder="Add meg az e-mail címed" required>
|
||||
<div class="error-message">Kérjük, add meg az e-mail címed.</div>
|
||||
</div>
|
||||
|
||||
<div class="g-recaptcha" data-sitekey="6LcmPB8dAAAAACJPQBj7WfpBoBsEfyibZeIG5Vbl"></div>
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="/Adminisztracio/Login" class="help-link">
|
||||
Vissza a bejelentkezéshez
|
||||
</a>
|
||||
<button type="submit" class="btn-submit">
|
||||
Jelszó visszaállítása
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<h1 class="forgot-title" data-i18n="forgotpassword.title">Elfelejtett jelszó</h1>
|
||||
|
||||
<form id="forgotForm" novalidate>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="BejelentkezesiNev" data-i18n="forgotpassword.om_id_label">OM azonosító</label>
|
||||
<input type="text" id="BejelentkezesiNev" name="BejelentkezesiNev" class="form-control"
|
||||
data-i18n-attr="placeholder" data-i18n="forgotpassword.om_id_placeholder"
|
||||
placeholder="Adja meg az OM azonosítóját" required>
|
||||
<div class="error-message" data-i18n="forgotpassword.om_id_required">Az OM azonosító megadása kötelező</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="EmailCim" data-i18n="forgotpassword.email_label">E-mail cím</label>
|
||||
<input type="email" id="EmailCim" name="EmailCim" class="form-control"
|
||||
data-i18n-attr="placeholder" data-i18n="forgotpassword.email_placeholder"
|
||||
placeholder="Adja meg az e-mail címét" required>
|
||||
<div class="error-message" data-i18n="forgotpassword.email_required">Az e-mail cím megadása kötelező</div>
|
||||
</div>
|
||||
|
||||
<!-- reCAPTCHA container removed for security compliance -->
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="/Adminisztracio/Login" class="help-link" data-i18n="forgotpassword.back_to_login">
|
||||
Vissza a bejelentkezéshez
|
||||
</a>
|
||||
<button type="submit" class="btn-submit" data-i18n="forgotpassword.reset_button">
|
||||
Jelszó visszaállítása
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`;
|
||||
|
||||
setupFormValidation();
|
||||
};
|
||||
|
||||
const setupFormValidation = () => {
|
||||
const form = document.getElementById('forgotForm');
|
||||
const inputs = form.querySelectorAll('.form-control');
|
||||
|
||||
inputs.forEach(input => {
|
||||
|
||||
input.addEventListener('input', () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', handleSubmit);
|
||||
};
|
||||
|
||||
const validateInput = (input, showError = false) => {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
</div>
|
||||
`, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
|
||||
// Biztonságos DOM hozzáadás
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
const transformForgotPasswordPage = async () => {
|
||||
await loadDependencies();
|
||||
|
||||
const isDarkMode = localStorage.getItem("darkMode") === "true";
|
||||
document.documentElement.setAttribute(
|
||||
"data-theme",
|
||||
isDarkMode ? "dark" : "light",
|
||||
);
|
||||
|
||||
chrome.runtime.onMessage.addListener((message) => {
|
||||
if (message.action === "toggleTheme") {
|
||||
document.documentElement.setAttribute(
|
||||
"data-theme",
|
||||
message.darkMode ? "dark" : "light",
|
||||
);
|
||||
localStorage.setItem("darkMode", message.darkMode);
|
||||
}
|
||||
|
||||
return isValid;
|
||||
});
|
||||
|
||||
createPageStructure();
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 50;
|
||||
|
||||
const waitForLanguageManager = () => {
|
||||
return new Promise((resolve) => {
|
||||
const checkLanguageManager = () => {
|
||||
attempts++;
|
||||
if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
|
||||
setTimeout(resolve, 200);
|
||||
} else if (attempts < maxAttempts) {
|
||||
setTimeout(checkLanguageManager, 100);
|
||||
} else {
|
||||
console.warn("LanguageManager not available, using fallback texts");
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
checkLanguageManager();
|
||||
});
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
let isValid = true;
|
||||
|
||||
inputs.forEach(input => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
|
||||
await waitForLanguageManager();
|
||||
|
||||
if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
|
||||
const elements = document.querySelectorAll("[data-i18n]");
|
||||
elements.forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const translation = LanguageManager.t(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute("data-i18n-attr");
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reCAPTCHA rendering removed for security compliance
|
||||
|
||||
setupFormValidation();
|
||||
};
|
||||
|
||||
const setupFormValidation = () => {
|
||||
const form = document.getElementById("forgotForm");
|
||||
const inputs = form.querySelectorAll(".form-control");
|
||||
|
||||
inputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener("submit", handleSubmit);
|
||||
};
|
||||
|
||||
const validateInput = (input, showError = false) => {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
const showMessage = (message, isError = false) => {
|
||||
const existingMessage = document.querySelector(".message");
|
||||
if (existingMessage) {
|
||||
existingMessage.remove();
|
||||
}
|
||||
|
||||
const messageDiv = document.createElement("div");
|
||||
messageDiv.className = `message ${isError ? "error" : "success"}`;
|
||||
messageDiv.textContent = message;
|
||||
|
||||
const form = document.getElementById("forgotForm");
|
||||
form.insertBefore(messageDiv, form.firstChild);
|
||||
|
||||
setTimeout(() => {
|
||||
if (messageDiv.parentNode) {
|
||||
messageDiv.remove();
|
||||
}
|
||||
|
||||
const submitButton = form.querySelector('.btn-submit');
|
||||
submitButton.disabled = true;
|
||||
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
const response = await fetch('/Adminisztracio/ElfelejtettJelszo/LinkKuldes', {
|
||||
method: 'POST',
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
const validateEmail = (email) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
const emailInput = form.querySelector("#EmailCim");
|
||||
if (emailInput.value && !validateEmail(emailInput.value)) {
|
||||
emailInput.classList.add("error");
|
||||
const errorElement = emailInput.nextElementSibling;
|
||||
if (errorElement) {
|
||||
errorElement.textContent = LanguageManager.t(
|
||||
"forgotpassword.invalid_email",
|
||||
);
|
||||
errorElement.classList.add("show");
|
||||
}
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
// reCAPTCHA validation removed for security compliance
|
||||
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const submitButton = form.querySelector(".btn-submit");
|
||||
const originalText = submitButton.textContent;
|
||||
submitButton.disabled = true;
|
||||
submitButton.textContent = LanguageManager.t("loading.text") || "Küldés...";
|
||||
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
|
||||
// reCAPTCHA data removed for security compliance
|
||||
|
||||
const response = await fetch(
|
||||
"/Adminisztracio/ElfelejtettJelszo/LinkKuldes",
|
||||
{
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.Success) {
|
||||
window.location.href = '/Adminisztracio/Login';
|
||||
} else {
|
||||
|
||||
alert(result.Message || 'Hiba történt a jelszó visszaállítása során. (Kérlek használd az eredeti kréta oldalt erre)');
|
||||
grecaptcha.reset();
|
||||
}
|
||||
} catch (error) {
|
||||
//alert('Hiba történt a jelszó visszaállítása során.');
|
||||
grecaptcha.reset();
|
||||
} finally {
|
||||
submitButton.disabled = false;
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
};
|
||||
|
||||
if (window.location.href.includes('/Adminisztracio/ElfelejtettJelszo')) {
|
||||
transformForgotPasswordPage();
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.Success) {
|
||||
showMessage(LanguageManager.t("forgotpassword.success_message"));
|
||||
|
||||
form.reset();
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = "/Adminisztracio/Login";
|
||||
}, 3000);
|
||||
} else {
|
||||
showMessage(
|
||||
result.Message || LanguageManager.t("forgotpassword.error_message"),
|
||||
true,
|
||||
);
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Password reset error:", error);
|
||||
showMessage(LanguageManager.t("forgotpassword.error_message"), true);
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
} finally {
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = originalText;
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
if (window.location.href.includes("/Adminisztracio/ElfelejtettJelszo")) {
|
||||
transformForgotPasswordPage().catch(console.error);
|
||||
}
|
||||
})();
|
||||
|
||||
189
global/language.js
Normal file
@@ -0,0 +1,189 @@
|
||||
(function () {
|
||||
let currentLanguage = "hu";
|
||||
let translations = {};
|
||||
|
||||
async function setLanguage(language) {
|
||||
try {
|
||||
currentLanguage = language;
|
||||
|
||||
await storageManager.set("languagePreference", language);
|
||||
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
await loadTranslations(language);
|
||||
applyTranslations();
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("languageChanged", {
|
||||
detail: { language: language },
|
||||
}),
|
||||
);
|
||||
|
||||
chrome.runtime
|
||||
.sendMessage({
|
||||
action: "languageChanged",
|
||||
language: language,
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
async function loadTranslations(language) {
|
||||
try {
|
||||
const url = chrome.runtime.getURL(`i18n/${language}.json`);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to load ${language}.json - Status: ${response.status}`,
|
||||
);
|
||||
}
|
||||
translations = await response.json();
|
||||
} catch (error) {
|
||||
if (language !== "hu") {
|
||||
try {
|
||||
const fallbackUrl = chrome.runtime.getURL("i18n/hu.json");
|
||||
const response = await fetch(fallbackUrl);
|
||||
translations = await response.json();
|
||||
} catch (fallbackError) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyTranslations() {
|
||||
const elements = document.querySelectorAll("[data-i18n]");
|
||||
|
||||
elements.forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute("data-i18n-attr");
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getTranslation(keyPath, fallback = "") {
|
||||
const keys = keyPath.split(".");
|
||||
let value = translations;
|
||||
|
||||
for (const key of keys) {
|
||||
if (value && typeof value === "object" && key in value) {
|
||||
value = value[key];
|
||||
} else {
|
||||
return fallback || keyPath;
|
||||
}
|
||||
}
|
||||
|
||||
return typeof value === "string" ? value : fallback || keyPath;
|
||||
}
|
||||
|
||||
async function initializeLanguage() {
|
||||
try {
|
||||
const storageLanguage = await storageManager.get("languagePreference");
|
||||
const localStorageLanguage = localStorage.getItem("languagePreference");
|
||||
const language = storageLanguage || localStorageLanguage || "hu";
|
||||
|
||||
await setLanguage(language);
|
||||
loadTranslationsForPage();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", initializeLanguage);
|
||||
} else {
|
||||
initializeLanguage();
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === "changeLanguage") {
|
||||
setLanguage(message.language);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
if (message.action === "getLanguage") {
|
||||
sendResponse({ language: currentLanguage });
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
function loadTranslationsForPage() {
|
||||
try {
|
||||
applyTranslations();
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'childList') {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const elementsWithI18n = node.querySelectorAll ? node.querySelectorAll('[data-i18n]') : [];
|
||||
elementsWithI18n.forEach((element) => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (node.hasAttribute && node.hasAttribute('data-i18n')) {
|
||||
const key = node.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = node.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
node.setAttribute(attr, translation);
|
||||
} else {
|
||||
node.textContent = translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error loading translations for page:', error);
|
||||
}
|
||||
}
|
||||
|
||||
window.LanguageManager = {
|
||||
getCurrentLanguage: () => currentLanguage,
|
||||
changeLanguage: setLanguage,
|
||||
t: getTranslation,
|
||||
loadTranslationsForPage: loadTranslationsForPage,
|
||||
getAvailableLanguages: () => [
|
||||
{ code: "hu", name: "Magyar" },
|
||||
{ code: "en", name: "English" },
|
||||
],
|
||||
};
|
||||
})();
|
||||
@@ -1,51 +1,57 @@
|
||||
body.maintenance-mode {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-family: 'Inter', sans-serif;
|
||||
margin:0;
|
||||
padding:0;
|
||||
height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
background-color:var(--background);
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background) !important;
|
||||
background-color:var(--background) !important;
|
||||
}
|
||||
|
||||
.maintenance-container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
background-color: var(--card-card);
|
||||
box-shadow: 0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
text-align:center;
|
||||
padding:2rem;
|
||||
border-radius:8px;
|
||||
background-color:var(--card-card);
|
||||
box-shadow:0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width:600px;
|
||||
width:90%;
|
||||
}
|
||||
|
||||
.maintenance-logo {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
margin: 0 auto 2rem;
|
||||
width:128px;
|
||||
height:128px;
|
||||
margin:0 auto 2rem;
|
||||
}
|
||||
|
||||
.maintenance-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--accent-accent);
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
margin-bottom:1rem;
|
||||
color:var(--accent-accent);
|
||||
font-family:'Montserrat',sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-message {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--text-primary);
|
||||
font-size:1rem;
|
||||
line-height:1.5;
|
||||
margin-bottom:1.5rem;
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-footer {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 2rem;
|
||||
}
|
||||
font-size:0.875rem;
|
||||
color:var(--text-secondary);
|
||||
margin-top:2rem;
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
.maintenance-cactus {
|
||||
position:fixed;
|
||||
bottom:0px;
|
||||
right:20px;
|
||||
width:120px;
|
||||
height:120px;
|
||||
opacity:1;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
@@ -1,65 +1,106 @@
|
||||
function loadMaintenanceCSS() {
|
||||
const maintenanceCSS = document.createElement('link');
|
||||
maintenanceCSS.rel = 'stylesheet';
|
||||
maintenanceCSS.href = chrome.runtime.getURL('global/maintenance.css');
|
||||
document.head.appendChild(maintenanceCSS);
|
||||
const maintenanceCSS = document.createElement("link");
|
||||
maintenanceCSS.rel = "stylesheet";
|
||||
maintenanceCSS.href = chrome.runtime.getURL("global/maintenance.css");
|
||||
document.head.appendChild(maintenanceCSS);
|
||||
}
|
||||
|
||||
function checkMaintenancePage() {
|
||||
const maintenanceContent = document.querySelector('.login_content');
|
||||
if (maintenanceContent && maintenanceContent.textContent.includes('frissítés alatt')) {
|
||||
const body = document.body;
|
||||
const mainLogo = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
|
||||
|
||||
const existingStyles = document.querySelectorAll('link[rel="stylesheet"], style');
|
||||
existingStyles.forEach(style => style.remove());
|
||||
|
||||
|
||||
body.innerHTML = '';
|
||||
body.classList.add('maintenance-mode');
|
||||
body.classList.add('theme-enabled');
|
||||
|
||||
|
||||
loadMaintenanceCSS();
|
||||
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.className = 'maintenance-container';
|
||||
|
||||
const logo = document.createElement('img');
|
||||
logo.src = mainLogo;
|
||||
logo.alt = 'Firka Logo';
|
||||
logo.className = 'maintenance-logo';
|
||||
|
||||
const title = document.createElement('h1');
|
||||
title.className = 'maintenance-title';
|
||||
title.textContent = 'Karbantartás';
|
||||
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'maintenance-message';
|
||||
|
||||
const paragraph1 = document.createElement('p');
|
||||
paragraph1.textContent = 'A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.';
|
||||
|
||||
const paragraph2 = document.createElement('p');
|
||||
paragraph2.textContent = 'Köszönjük türelmüket és megértésüket!';
|
||||
|
||||
const footer = document.createElement('div');
|
||||
footer.className = 'maintenance-footer';
|
||||
footer.textContent = 'KRÉTA Csapat';
|
||||
|
||||
|
||||
messageDiv.appendChild(paragraph1);
|
||||
messageDiv.appendChild(paragraph2);
|
||||
|
||||
container.appendChild(logo);
|
||||
container.appendChild(title);
|
||||
container.appendChild(messageDiv);
|
||||
container.appendChild(footer);
|
||||
|
||||
body.appendChild(container);
|
||||
}
|
||||
const maintenanceContent = document.querySelector(".login_content");
|
||||
const bodyText = document.body ? document.body.textContent : "";
|
||||
|
||||
const hasSpecificMessage = bodyText.includes("A KRÉTA rendszer jelenleg frissítés alatt van");
|
||||
|
||||
const hasGeneralMaintenance =
|
||||
maintenanceContent &&
|
||||
(maintenanceContent.textContent.includes("frissítés alatt") ||
|
||||
maintenanceContent.textContent.includes("under maintenance"));
|
||||
|
||||
if (hasSpecificMessage || hasGeneralMaintenance) {
|
||||
const body = document.body;
|
||||
const mainLogo = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
const cactusImage = chrome.runtime.getURL("images/cactus.png");
|
||||
|
||||
const removeLoadingElements = () => {
|
||||
const loadingScreen = document.querySelector(".loading-screen");
|
||||
if (loadingScreen) loadingScreen.remove();
|
||||
|
||||
const kretaProgressBar = document.querySelector("#KretaProgressBar");
|
||||
if (kretaProgressBar) kretaProgressBar.remove();
|
||||
|
||||
const modalBackground = document.querySelector(".modalBckgroundMain");
|
||||
if (modalBackground) modalBackground.remove();
|
||||
|
||||
const overlays = document.querySelectorAll(
|
||||
".modalBckgroundMain, .loading-screen, #KretaProgressBar",
|
||||
);
|
||||
overlays.forEach((overlay) => overlay.remove());
|
||||
};
|
||||
|
||||
removeLoadingElements();
|
||||
setTimeout(removeLoadingElements, 100);
|
||||
|
||||
const existingStyles = document.querySelectorAll(
|
||||
'link[rel="stylesheet"], style',
|
||||
);
|
||||
existingStyles.forEach((style) => style.remove());
|
||||
|
||||
body.innerHTML = "";
|
||||
body.classList.add("maintenance-mode");
|
||||
body.classList.add("theme-enabled");
|
||||
body.classList.add("loaded");
|
||||
|
||||
loadMaintenanceCSS();
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.className = "maintenance-container";
|
||||
|
||||
const logo = document.createElement("img");
|
||||
logo.src = mainLogo;
|
||||
logo.alt = "Firka Logo";
|
||||
logo.className = "maintenance-logo";
|
||||
|
||||
const title = document.createElement("h1");
|
||||
title.className = "maintenance-title";
|
||||
title.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.title")
|
||||
: "Karbantartás";
|
||||
|
||||
const messageDiv = document.createElement("div");
|
||||
messageDiv.className = "maintenance-message";
|
||||
|
||||
const paragraph1 = document.createElement("p");
|
||||
paragraph1.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.message1")
|
||||
: "A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.";
|
||||
|
||||
const paragraph2 = document.createElement("p");
|
||||
paragraph2.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.message2")
|
||||
: "Köszönjük türelmüket és megértésüket!";
|
||||
|
||||
const footer = document.createElement("div");
|
||||
footer.className = "maintenance-footer";
|
||||
footer.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.team")
|
||||
: "KRÉTA Csapat";
|
||||
|
||||
const cactus = document.createElement("img");
|
||||
cactus.src = cactusImage;
|
||||
cactus.alt = "Cactus";
|
||||
cactus.className = "maintenance-cactus";
|
||||
|
||||
messageDiv.appendChild(paragraph1);
|
||||
messageDiv.appendChild(paragraph2);
|
||||
|
||||
container.appendChild(logo);
|
||||
container.appendChild(title);
|
||||
container.appendChild(messageDiv);
|
||||
container.appendChild(footer);
|
||||
|
||||
body.appendChild(container);
|
||||
body.appendChild(cactus);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', checkMaintenancePage);
|
||||
document.addEventListener("DOMContentLoaded", checkMaintenancePage);
|
||||
|
||||
@@ -1,401 +1,334 @@
|
||||
.kreta-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--background);
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
display:grid;
|
||||
grid-template-columns:minmax(300px,400px) 1fr minmax(200px,300px);
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background-color:var(--background);
|
||||
}
|
||||
|
||||
|
||||
.school-info {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin:0;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color:var(--text-primary);
|
||||
font-size:24px;
|
||||
font-weight:600;
|
||||
margin:0 0 0.5rem;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.5rem;
|
||||
width:24px;
|
||||
height:24px;
|
||||
border-radius:8px;
|
||||
margin-right:0.5rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.kreta-nav {
|
||||
padding: 0 clamp(0.5rem, 3vw, 1.5rem);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding:0 clamp(0.5rem,3vw,1.5rem);
|
||||
position:sticky;
|
||||
top:0;
|
||||
z-index:100;
|
||||
display:flex;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
align-items: center;
|
||||
display:flex;
|
||||
gap:clamp(0.5rem,2vw,1rem);
|
||||
padding:0.25rem;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
gap: 0.5rem;
|
||||
text-decoration: none;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
padding:8px 14px 8px 12px;
|
||||
color:var(--text-secondary);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
white-space:nowrap;
|
||||
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;
|
||||
padding: 8px 14px 8px 12px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 20px;
|
||||
background: var(--button-secondaryFill);
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
padding:8px 14px 8px 12px;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
border-radius:20px;
|
||||
background:var(--button-secondaryFill);
|
||||
box-shadow:0px 1px var(--shadow-blur,2px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--hover);
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--accent-15);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
.nav-item.active:hover {
|
||||
color: var(--accent-accent);
|
||||
background-color: var(--accent-hover);
|
||||
text-decoration: none;
|
||||
color:var(--accent-accent);
|
||||
background-color:var(--accent-15);
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.nav-item img,
|
||||
.nav-item svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.nav-item img,.nav-item svg {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
|
||||
.nav-item.active svg path {
|
||||
fill: var(--accent-accent);
|
||||
fill:var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
position:relative;
|
||||
justify-self:flex-end;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--hover);
|
||||
background:var(--hover);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
display:block;
|
||||
color:var(--text-primary);
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
display:block;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.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;
|
||||
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;
|
||||
display:block;
|
||||
animation:dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.75rem;
|
||||
padding:0.75rem 1rem;
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--hover);
|
||||
color: var(--accent-accent);
|
||||
border-radius: 8px;
|
||||
background:var(--hover);
|
||||
color:var(--accent-accent);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@media (max-width:1200px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: minmax(250px, 350px) 1fr minmax(180px, 250px);
|
||||
}
|
||||
grid-template-columns:minmax(250px,350px) 1fr minmax(180px,250px);
|
||||
}
|
||||
|
||||
/* Hamburger menu styles */
|
||||
}/* Hamburger menu styles */
|
||||
.nav-toggle {
|
||||
display: none;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
display:none;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.nav-toggle:hover {
|
||||
background: var(--hover);
|
||||
background:var(--hover);
|
||||
}
|
||||
|
||||
.nav-toggle svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: var(--text-primary);
|
||||
width:24px;
|
||||
height:24px;
|
||||
fill:var(--text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
display: block;
|
||||
grid-area: toggle;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 11px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.kreta-nav.show {
|
||||
display: flex;
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
padding: 0.75rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 11px;
|
||||
}
|
||||
padding:1rem;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.nav-toggle {
|
||||
display:block;
|
||||
grid-area:toggle;
|
||||
}
|
||||
.school-info {
|
||||
grid-area:school;
|
||||
max-width:none;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.5rem;
|
||||
}
|
||||
.logo-text {
|
||||
margin:0;
|
||||
font-size:18px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:11px;
|
||||
max-width:200px;
|
||||
}
|
||||
.kreta-nav {
|
||||
grid-area:nav;
|
||||
padding:0;
|
||||
margin-top:0.5rem;
|
||||
display:none;
|
||||
}
|
||||
.kreta-nav.show {
|
||||
display:flex;
|
||||
animation:slideDown 0.3s ease;
|
||||
}
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
display:none;
|
||||
}
|
||||
.nav-links {
|
||||
flex-direction:column;
|
||||
width:100%;
|
||||
gap:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
padding:1rem;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
.nav-item {
|
||||
width:100%;
|
||||
justify-content:flex-start;
|
||||
padding:0.75rem;
|
||||
font-size:14px;
|
||||
}
|
||||
.user-profile {
|
||||
grid-area:user;
|
||||
}
|
||||
.user-info {
|
||||
text-align:right;
|
||||
max-width:120px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:13px;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:11px;
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 0.75rem;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 10px;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.kreta-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.kreta-nav.show {
|
||||
display: flex;
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
padding: 0.75rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 10px;
|
||||
}
|
||||
padding:0.75rem;
|
||||
gap:0.25rem;
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.kreta-header {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 9px;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
max-width: 80px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 9px;
|
||||
}
|
||||
.school-info {
|
||||
min-width:0;
|
||||
flex:1;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
.logo-text {
|
||||
font-size:16px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:10px;
|
||||
max-width:150px;
|
||||
}
|
||||
.kreta-nav {
|
||||
display:none;
|
||||
}
|
||||
.kreta-nav.show {
|
||||
display:flex;
|
||||
animation:slideDown 0.3s ease;
|
||||
}
|
||||
.nav-links {
|
||||
flex-direction:column;
|
||||
width:100%;
|
||||
gap:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
padding:1rem;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
.nav-item {
|
||||
width:100%;
|
||||
justify-content:flex-start;
|
||||
padding:0.75rem;
|
||||
font-size:14px;
|
||||
}
|
||||
.user-info {
|
||||
max-width:100px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:12px;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:10px;
|
||||
}
|
||||
}@media (max-width:360px) {
|
||||
.kreta-header {
|
||||
padding:0.5rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:14px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:9px;
|
||||
max-width:120px;
|
||||
}
|
||||
.user-info {
|
||||
max-width:80px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:11px;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:9px;
|
||||
}
|
||||
}@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}
|
||||
@@ -1,122 +1,177 @@
|
||||
const COOKIE_KEYS = {
|
||||
SCHOOL_NAME: 'schoolName',
|
||||
SCHOOL_CODE: 'schoolCode',
|
||||
USER_NAME: 'userName',
|
||||
SCHOOL_SUBDOMAIN: 'schoolSubdomain'
|
||||
SCHOOL_NAME: "schoolName",
|
||||
SCHOOL_CODE: "schoolCode",
|
||||
USER_NAME: "userName",
|
||||
SCHOOL_SUBDOMAIN: "schoolSubdomain",
|
||||
};
|
||||
|
||||
const DEFAULT_VALUES = {
|
||||
SCHOOL: 'Iskola',
|
||||
USER: 'Felhasználó',
|
||||
TIMER: '45:00'
|
||||
SCHOOL: LanguageManager.t("navigation.school_default"),
|
||||
USER: LanguageManager.t("navigation.user_default"),
|
||||
TIMER: "45:00",
|
||||
};
|
||||
|
||||
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,
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
||||
};
|
||||
|
||||
if (schoolName) {
|
||||
schoolName.textContent = `${userData.schoolId} - ${userData.schoolName}`;
|
||||
}
|
||||
|
||||
if (userName) {
|
||||
userName.textContent = userData.name;
|
||||
}
|
||||
|
||||
if (logoutTimer) {
|
||||
startLogoutTimer(userData.time);
|
||||
}
|
||||
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:
|
||||
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,
|
||||
};
|
||||
|
||||
if (schoolName) {
|
||||
schoolName.textContent = `${userData.schoolId} - ${userData.schoolName}`;
|
||||
}
|
||||
|
||||
if (userName) {
|
||||
userName.textContent = userData.name;
|
||||
}
|
||||
|
||||
if (logoutTimer) {
|
||||
startLogoutTimer(userData.time);
|
||||
}
|
||||
}
|
||||
|
||||
function startLogoutTimer(timeString) {
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
const timerElement = document.querySelector('.nav-logout-timer');
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
}
|
||||
timeLeft--;
|
||||
};
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
const timerElement = document.querySelector(".nav-logout-timer");
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = "/Home/Logout";
|
||||
}
|
||||
timeLeft--;
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateHeaderInfo();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
});
|
||||
|
||||
function setupUserDropdown() {
|
||||
const userBtn = document.querySelector('.user-dropdown-btn');
|
||||
const userDropdown = document.querySelector('.user-dropdown');
|
||||
|
||||
userBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle('show');
|
||||
});
|
||||
const userBtn = document.querySelector(".user-dropdown-btn");
|
||||
const userDropdown = document.querySelector(".user-dropdown");
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
userDropdown?.classList.remove('show');
|
||||
});
|
||||
userBtn?.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle("show");
|
||||
});
|
||||
|
||||
document.addEventListener("click", () => {
|
||||
userDropdown?.classList.remove("show");
|
||||
});
|
||||
}
|
||||
|
||||
function setupSettingsButton() {
|
||||
document.getElementById('settingsBtn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
document.getElementById("settingsBtn")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL("settings/index.html");
|
||||
window.open(url, "_blank", "width=400,height=600");
|
||||
});
|
||||
}
|
||||
|
||||
function setupMobileNavigation() {
|
||||
setTimeout(() => {
|
||||
const navToggle = document.querySelector('.nav-toggle');
|
||||
const nav = document.querySelector('.kreta-nav');
|
||||
setTimeout(() => {
|
||||
const navToggle = document.querySelector(".nav-toggle");
|
||||
const nav = document.querySelector(".kreta-nav");
|
||||
|
||||
if (!navToggle || !nav) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
||||
|
||||
if (isFirefox) {
|
||||
let isNavOpen = false;
|
||||
|
||||
navToggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (!navToggle || !nav) {
|
||||
return;
|
||||
if (isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
} else {
|
||||
nav.style.display = "flex";
|
||||
nav.classList.add("show");
|
||||
isNavOpen = true;
|
||||
}
|
||||
});
|
||||
|
||||
navToggle.addEventListener("touchend", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
navToggle.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
nav.classList.toggle('show');
|
||||
if (isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
} else {
|
||||
nav.style.display = "flex";
|
||||
nav.classList.add("show");
|
||||
isNavOpen = true;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target) && isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
const navItems = document.querySelectorAll(".nav-item");
|
||||
navItems.forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
navToggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
nav.classList.toggle("show");
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target)) {
|
||||
nav.classList.remove('show');
|
||||
}
|
||||
});
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target)) {
|
||||
nav.classList.remove("show");
|
||||
}
|
||||
});
|
||||
|
||||
const navItems = document.querySelectorAll('.nav-item');
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
nav.classList.remove('show');
|
||||
});
|
||||
const navItems = document.querySelectorAll(".nav-item");
|
||||
navItems.forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
nav.classList.remove("show");
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
});
|
||||
|
||||
267
global/theme.css
@@ -1,160 +1,129 @@
|
||||
:root {
|
||||
--background: #DAE4F7;
|
||||
--background-0: #dae4f700;
|
||||
--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;
|
||||
--warning-accent: var(--grades-2);
|
||||
--warning-text: #8F531B;
|
||||
--warning-15: #ffa04626;
|
||||
--warning-card: #FAEBDC;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #8F1B4F;
|
||||
--error-15: #FF54A126;
|
||||
--error-card: #FADCE9;
|
||||
--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;
|
||||
--background:#FAFFF0;
|
||||
--background-0:#fafff000;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:2px;
|
||||
--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;
|
||||
--warning-card:#FAEBDC;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#8F1B4F;
|
||||
--error-15:#FF54A126;
|
||||
--error-card:#FADCE9;
|
||||
--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="light-green"] {
|
||||
--background: #FAFFF0;
|
||||
--background-0: #fafff000;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 2px;
|
||||
--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;
|
||||
--warning-card: #FAEBDC;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #8F1B4F;
|
||||
--error-15: #FF54A126;
|
||||
--error-card: #FADCE9;
|
||||
--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;
|
||||
--background:#FAFFF0;
|
||||
--background-0:#fafff000;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:2px;
|
||||
--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;
|
||||
--warning-card:#FAEBDC;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#8F1B4F;
|
||||
--error-15:#FF54A126;
|
||||
--error-card:#FADCE9;
|
||||
--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-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;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 0;
|
||||
--text-primary: #EAF7CC;
|
||||
--text-secondary: #EAF7CCCC;
|
||||
--text-teritary: #EAF7CC80;
|
||||
--card-card: #141905;
|
||||
--card-translucent: #14190580;
|
||||
--button-secondaryFill: #20290b;
|
||||
--accent-accent: #A7DC22;
|
||||
--accent-secondary: #CBEE71;
|
||||
--accent-shadow: #0000;
|
||||
--accent-15: #a7dc2226;
|
||||
--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;
|
||||
--background:#0D1202;
|
||||
--background-0:#0E130200;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:0;
|
||||
--text-primary:#EAF7CC;
|
||||
--text-secondary:#EAF7CCCC;
|
||||
--text-teritary:#EAF7CC80;
|
||||
--card-card:#141905;
|
||||
--card-translucent:#14190580;
|
||||
--button-secondaryFill:#20290b;
|
||||
--accent-accent:#A7DC22;
|
||||
--accent-secondary:#CBEE71;
|
||||
--accent-shadow:#0000;
|
||||
--accent-15:#a7dc2226;
|
||||
--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;
|
||||
}
|
||||
|
||||
|
||||
html {
|
||||
background-color: var(--background) !important;
|
||||
color: var(--text-primary) !important;
|
||||
background-color:var(--background) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background) !important;
|
||||
color: var(--text-primary) !important;
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
min-height: 100vh;
|
||||
background-color:var(--background) !important;
|
||||
color:var(--text-primary) !important;
|
||||
transition:background-color 0.2s ease,color 0.2s ease;
|
||||
min-height:100vh;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
transition:background-color 0.2s ease,color 0.2s ease,border-color 0.2s ease;
|
||||
}
|
||||
::-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);
|
||||
}
|
||||
|
||||
307
global/theme.js
@@ -1,132 +1,197 @@
|
||||
(() => {
|
||||
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);
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'themeChanged',
|
||||
theme: actualTheme
|
||||
}).catch(() => {
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error setting theme:', error);
|
||||
}
|
||||
async function setTheme(theme) {
|
||||
try {
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
await storageManager.set("themePreference", theme);
|
||||
chrome.runtime
|
||||
.sendMessage({
|
||||
action: "themeChanged",
|
||||
theme: theme,
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch (error) {
|
||||
console.error("Error setting theme:", error);
|
||||
}
|
||||
|
||||
function setPageTitleAndFavicon() {
|
||||
try {
|
||||
document.title = 'Firka - KRÉTA';
|
||||
}
|
||||
|
||||
const existingFavicons = document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]');
|
||||
existingFavicons.forEach(link => link.remove());
|
||||
|
||||
if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.getURL) {
|
||||
const favicon = document.createElement('link');
|
||||
favicon.rel = 'icon';
|
||||
favicon.type = 'image/png';
|
||||
favicon.href = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
document.head.appendChild(favicon);
|
||||
|
||||
const shortcutIcon = document.createElement('link');
|
||||
shortcutIcon.rel = 'shortcut icon';
|
||||
shortcutIcon.type = 'image/png';
|
||||
shortcutIcon.href = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
document.head.appendChild(shortcutIcon);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error setting page title and favicon:', error);
|
||||
function importFonts() {
|
||||
try {
|
||||
const fontFaces = `
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-Regular.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
}
|
||||
|
||||
function initializeTheme() {
|
||||
const cookieTheme = cookieManager.get('themePreference');
|
||||
const localStorageTheme = localStorage.getItem('themePreference');
|
||||
|
||||
const theme = cookieTheme || localStorageTheme || 'light-green';
|
||||
|
||||
setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
|
||||
if (cookieTheme !== localStorageTheme) {
|
||||
if (cookieTheme) {
|
||||
localStorage.setItem('themePreference', cookieTheme);
|
||||
} else if (localStorageTheme) {
|
||||
cookieManager.set('themePreference', localStorageTheme);
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-Medium.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-SemiBold.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Figtree-Regular.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
`;
|
||||
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = fontFaces;
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
const iconFontFace = `
|
||||
@font-face {
|
||||
font-family: 'Material Icons Round';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Icons.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
`;
|
||||
|
||||
const iconStyleElement = document.createElement('style');
|
||||
iconStyleElement.textContent = iconFontFace;
|
||||
document.head.appendChild(iconStyleElement);
|
||||
} catch (error) {
|
||||
console.error("Error importing fonts:", error);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initializeTheme);
|
||||
} else {
|
||||
initializeTheme();
|
||||
}
|
||||
|
||||
function setPageTitleAndFavicon() {
|
||||
try {
|
||||
document.title = "Firka - KRÉTA";
|
||||
|
||||
const existingFavicons = document.querySelectorAll(
|
||||
'link[rel="icon"], link[rel="shortcut icon"]',
|
||||
);
|
||||
existingFavicons.forEach((link) => link.remove());
|
||||
|
||||
if (
|
||||
typeof chrome !== "undefined" &&
|
||||
chrome.runtime &&
|
||||
chrome.runtime.getURL
|
||||
) {
|
||||
const favicon = document.createElement("link");
|
||||
favicon.rel = "icon";
|
||||
favicon.type = "image/png";
|
||||
favicon.href = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
document.head.appendChild(favicon);
|
||||
|
||||
const shortcutIcon = document.createElement("link");
|
||||
shortcutIcon.rel = "shortcut icon";
|
||||
shortcutIcon.type = "image/png";
|
||||
shortcutIcon.href = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
document.head.appendChild(shortcutIcon);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error setting page title and favicon:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function initializeTheme() {
|
||||
try {
|
||||
const theme = await storageManager.get("themePreference", "light-green");
|
||||
|
||||
await setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
} catch (error) {
|
||||
console.error("Error initializing theme:", error);
|
||||
await setTheme("light-green");
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", initializeTheme);
|
||||
} else {
|
||||
initializeTheme();
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === "changeTheme") {
|
||||
setTheme(message.theme);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'changeTheme') {
|
||||
setTheme(message.theme);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
if (message.action === 'getTheme') {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light-green';
|
||||
sendResponse({ theme: currentTheme });
|
||||
}
|
||||
if (message.action === "getTheme") {
|
||||
const currentTheme =
|
||||
document.documentElement.getAttribute("data-theme") || "light-green";
|
||||
sendResponse({ theme: currentTheme });
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
});
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver(async (mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
|
||||
try {
|
||||
const savedTheme = await storageManager.get("themePreference");
|
||||
|
||||
if (
|
||||
(!currentTheme && savedTheme) ||
|
||||
(currentTheme !== savedTheme && savedTheme)
|
||||
) {
|
||||
await setTheme(savedTheme);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking theme in observer:", error);
|
||||
}
|
||||
|
||||
const titleChanged = mutations.some(
|
||||
(mutation) =>
|
||||
mutation.type === "childList" &&
|
||||
mutation.target === document.head &&
|
||||
Array.from(mutation.addedNodes).some(
|
||||
(node) => node.tagName === "TITLE",
|
||||
),
|
||||
);
|
||||
|
||||
if (titleChanged || document.title !== "Firka - KRÉTA") {
|
||||
clearTimeout(titleCheckTimeout);
|
||||
titleCheckTimeout = setTimeout(() => {
|
||||
if (document.title !== "Firka - KRÉTA") {
|
||||
setPageTitleAndFavicon();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-theme"],
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
});
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
const savedTheme = cookieManager.get('themePreference') || localStorage.getItem('themePreference');
|
||||
|
||||
if ((!currentTheme && savedTheme) || (currentTheme !== savedTheme && savedTheme)) {
|
||||
setTheme(savedTheme);
|
||||
}
|
||||
|
||||
const titleChanged = mutations.some(mutation =>
|
||||
mutation.type === 'childList' &&
|
||||
mutation.target === document.head &&
|
||||
Array.from(mutation.addedNodes).some(node => node.tagName === 'TITLE')
|
||||
);
|
||||
|
||||
if (titleChanged || document.title !== 'Firka - KRÉTA') {
|
||||
clearTimeout(titleCheckTimeout);
|
||||
titleCheckTimeout = setTimeout(() => {
|
||||
if (document.title !== 'Firka - KRÉTA') {
|
||||
setPageTitleAndFavicon();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-theme"],
|
||||
});
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['data-theme']
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['data-theme']
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
})();
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
1291
grades/grades.css
1031
grades/grades.js
@@ -1,417 +0,0 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
* {
|
||||
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: 1.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
box-shadow: 0px 1px 3px 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.filter-header h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.filter-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.filter-group select,
|
||||
.filter-group input {
|
||||
padding: 0.75rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--accent-15);
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.filter-group select:focus,
|
||||
.filter-group input:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent);
|
||||
box-shadow: 0 0 0 2px var(--accent-15);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
|
||||
.homework-list {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.homework-date-group {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.date-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.date-header h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.homework-item {
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
box-shadow: 0px 1px 2px 0px var(--accent-shadow);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.homework-item:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.homework-item.due-tomorrow {
|
||||
border-left: 4px solid var(--accent-accent);
|
||||
background-color: var(--accent-5);
|
||||
}
|
||||
|
||||
.homework-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.homework-subject {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.homework-deadline {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.homework-deadline.urgent {
|
||||
color: var(--accent-accent);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.homework-content {
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.homework-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.homework-teacher {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: var(--text-secondary);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
@@ -1,426 +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 = ['vasárnap', 'hétfő', 'kedd', 'szerda', 'csütörtök', 'péntek', 'szombat'];
|
||||
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 = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>Szűrés</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">subject</span>-->
|
||||
Tantárgy
|
||||
</label>
|
||||
<select id="subjectFilter">
|
||||
<option value="">Összes tantárgy</option>
|
||||
${[...new Set(homeworkItems.map(item => item.subject))]
|
||||
.sort()
|
||||
.map(subject => `<option value="${subject}">${subject}</option>`)
|
||||
.join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">person</span>-->
|
||||
Tanár
|
||||
</label>
|
||||
<select id="teacherFilter">
|
||||
<option value="">Összes tanár</option>
|
||||
${[...new Set(homeworkItems.map(item => item.teacher))]
|
||||
.sort()
|
||||
.map(teacher => `<option value="${teacher}">${teacher}</option>`)
|
||||
.join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">date_range</span>-->
|
||||
Határidő
|
||||
</label>
|
||||
<select id="deadlineFilter">
|
||||
<option value="">Összes határidő</option>
|
||||
<option value="tomorrow">Holnapi határidő</option>
|
||||
<option value="thisWeek">Ezen a héten</option>
|
||||
<option value="nextWeek">Jövő héten</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="homework-list" id="homeworkList">
|
||||
${renderHomeworkList(groupedHomework)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
|
||||
setupFilters(homeworkItems, groupedHomework);
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function renderHomeworkList(groupedHomework) {
|
||||
const sortedDates = Object.keys(groupedHomework).sort((a, b) => {
|
||||
const partsA = a.split('.');
|
||||
const partsB = b.split('.');
|
||||
|
||||
const monthA = parseInt(partsA[0]) - 1;
|
||||
const dayA = parseInt(partsA[1]);
|
||||
const monthB = parseInt(partsB[0]) - 1;
|
||||
const dayB = parseInt(partsB[1]);
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const currentMonth = new Date().getMonth();
|
||||
|
||||
const yearA = monthA < currentMonth ? currentYear + 1 : currentYear;
|
||||
const yearB = monthB < currentMonth ? currentYear + 1 : currentYear;
|
||||
|
||||
const dateA = new Date(yearA, monthA, dayA);
|
||||
const dateB = new Date(yearB, monthB, dayB);
|
||||
|
||||
return dateB - dateA;
|
||||
});
|
||||
|
||||
if (sortedDates.length === 0) {
|
||||
return `
|
||||
<div class="empty-state">
|
||||
<p>Nincs megjeleníthető házi feladat.</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return sortedDates.map(date => {
|
||||
const homeworkItems = groupedHomework[date];
|
||||
return `
|
||||
<div class="homework-date-group" data-date="${date}">
|
||||
<div class="date-header">
|
||||
<h3>${formatDateHeader(date)}</h3>
|
||||
</div>
|
||||
${homeworkItems.map(homework => {
|
||||
const isTomorrowClass = isTomorrow(homework.deadline) ? 'due-tomorrow' : '';
|
||||
const urgentClass = isTomorrow(homework.deadline) ? 'urgent' : '';
|
||||
|
||||
return `
|
||||
<div class="homework-item ${isTomorrowClass}" data-subject="${homework.subject}" data-teacher="${homework.teacher}">
|
||||
<div class="homework-header">
|
||||
<div class="homework-subject">${homework.subject}</div>
|
||||
<div class="homework-deadline ${urgentClass}">${homework.deadline}</div>
|
||||
</div>
|
||||
<div class="homework-content">${formatHomeworkDescription(homework.description)}</div>
|
||||
<div class="homework-footer">
|
||||
<div class="homework-teacher">${homework.teacher}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
`;
|
||||
}).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 'Ma - ' + dateStr;
|
||||
} else if (date.toDateString() === tomorrow.toDateString()) {
|
||||
return 'Holnap - ' + dateStr;
|
||||
}
|
||||
|
||||
const weekdays = ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'];
|
||||
return `${weekdays[date.getDay()]} - ${dateStr}`;
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
function formatHomeworkDescription(description) {
|
||||
if (!description) return '';
|
||||
|
||||
description = description.replace(/\n/g, '<br>');
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
function setupFilters(homeworkItems, groupedHomework) {
|
||||
const subjectFilter = document.getElementById('subjectFilter');
|
||||
const teacherFilter = document.getElementById('teacherFilter');
|
||||
const deadlineFilter = document.getElementById('deadlineFilter');
|
||||
const applyFilterBtn = document.getElementById('applyFilterBtn');
|
||||
const resetFilterBtn = document.getElementById('resetFilterBtn');
|
||||
|
||||
|
||||
const applyFilters = () => {
|
||||
const selectedSubject = subjectFilter.value;
|
||||
const selectedTeacher = teacherFilter.value;
|
||||
const selectedDeadline = deadlineFilter.value;
|
||||
|
||||
|
||||
const homeworkElements = document.querySelectorAll('.homework-item');
|
||||
const dateGroups = document.querySelectorAll('.homework-date-group');
|
||||
|
||||
|
||||
dateGroups.forEach(group => {
|
||||
group.style.display = 'none';
|
||||
});
|
||||
|
||||
|
||||
homeworkElements.forEach(item => {
|
||||
const subject = item.getAttribute('data-subject');
|
||||
const teacher = item.getAttribute('data-teacher');
|
||||
const dateGroup = item.closest('.homework-date-group');
|
||||
const dateStr = dateGroup.getAttribute('data-date');
|
||||
|
||||
let showItem = true;
|
||||
|
||||
|
||||
if (selectedSubject && subject !== selectedSubject) {
|
||||
showItem = false;
|
||||
}
|
||||
|
||||
|
||||
if (selectedTeacher && teacher !== selectedTeacher) {
|
||||
showItem = false;
|
||||
}
|
||||
|
||||
|
||||
if (selectedDeadline) {
|
||||
const parts = dateStr.split('.');
|
||||
if (parts.length >= 3) {
|
||||
const year = parseInt(parts[0].trim());
|
||||
const month = parseInt(parts[1].trim()) - 1;
|
||||
const day = parseInt(parts[2].trim());
|
||||
const date = new Date(year, 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()) {
|
||||
showItem = false;
|
||||
} else if (selectedDeadline === 'thisWeek' && (date < startOfWeek || date > endOfWeek)) {
|
||||
showItem = false;
|
||||
} else if (selectedDeadline === 'nextWeek' && (date < startOfNextWeek || date > endOfNextWeek)) {
|
||||
showItem = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
item.style.display = showItem ? 'block' : 'none';
|
||||
|
||||
|
||||
if (showItem) {
|
||||
dateGroup.style.display = 'block';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const visibleItems = document.querySelectorAll('.homework-item[style="display: block"]');
|
||||
const homeworkList = document.getElementById('homeworkList');
|
||||
|
||||
|
||||
let emptyState = homeworkList.querySelector('.empty-state');
|
||||
if (!emptyState) {
|
||||
emptyState = document.createElement('div');
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = '<p>Nincs a szűrési feltételeknek megfelelő házi feladat.</p>';
|
||||
homeworkList.appendChild(emptyState);
|
||||
}
|
||||
|
||||
|
||||
if (visibleItems.length === 0) {
|
||||
emptyState.style.display = 'block';
|
||||
} else {
|
||||
emptyState.style.display = 'none';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const resetFilters = () => {
|
||||
subjectFilter.value = '';
|
||||
teacherFilter.value = '';
|
||||
deadlineFilter.value = '';
|
||||
|
||||
|
||||
document.querySelectorAll('.homework-item').forEach(item => {
|
||||
item.style.display = 'block';
|
||||
});
|
||||
|
||||
document.querySelectorAll('.homework-date-group').forEach(group => {
|
||||
group.style.display = 'block';
|
||||
});
|
||||
|
||||
|
||||
const homeworkList = document.getElementById('homeworkList');
|
||||
const existingEmptyState = homeworkList.querySelector('.empty-state');
|
||||
if (existingEmptyState) {
|
||||
homeworkList.removeChild(existingEmptyState);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
subjectFilter.addEventListener('change', applyFilters);
|
||||
teacherFilter.addEventListener('change', applyFilters);
|
||||
deadlineFilter.addEventListener('change', applyFilters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (window.location.href.includes('/Tanulo/TanuloHaziFeladat')) {
|
||||
transformHomeworkPage().catch(error => {
|
||||
console.error('Error transforming homework page:', error);
|
||||
});
|
||||
}
|
||||
463
i18n/en.json
Normal file
@@ -0,0 +1,463 @@
|
||||
{
|
||||
"loading": {
|
||||
"text": "Loading...",
|
||||
"subtext": "Please wait!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"themes": {
|
||||
"light_green": "Light Green",
|
||||
"dark_green": "Dark Green",
|
||||
"dark_red": "Dark Red",
|
||||
"dark_purple": "Dark Purple",
|
||||
"dark_orange": "Dark Orange",
|
||||
"dark_pink": "Dark Pink",
|
||||
"dark_yellow": "Dark Yellow",
|
||||
"dark_cyan": "Dark Cyan",
|
||||
"dark_lime": "Dark Lime",
|
||||
"dark_indigo": "Dark Indigo"
|
||||
},
|
||||
"languages": {
|
||||
"hu": "Magyar",
|
||||
"en": "English"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"description": "Firka is an open-source project that creates a custom user interface for the KRÉTA system.",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"support": {
|
||||
"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": {
|
||||
"dashboard": "Home",
|
||||
"timetable": "Timetable",
|
||||
"grades": "Grades",
|
||||
"homework": "Homework",
|
||||
"absences": "Absences",
|
||||
"messages": "Messages",
|
||||
"profile": "Profile",
|
||||
"settings": "Settings",
|
||||
"logout": "Logout",
|
||||
"nav_toggle": "Open navigation"
|
||||
},
|
||||
"dashboard": {
|
||||
"welcome": "Welcome",
|
||||
"recent_grades": "Recent grades",
|
||||
"upcoming_lessons": "Upcoming lessons",
|
||||
"homework_due": "Homework due",
|
||||
"news": "News",
|
||||
"grades": "Your grades",
|
||||
"absences": "Absences",
|
||||
"notes": "Notes",
|
||||
"exams": "Announced tests",
|
||||
"all_news": "All news",
|
||||
"all_grades": "All your grades",
|
||||
"all_absences": "All absences",
|
||||
"all_messages": "All your messages",
|
||||
"all_exams": "All tests",
|
||||
"not_supported": "There is currently no data to show",
|
||||
"evaluation": "Evaluation"
|
||||
},
|
||||
"grades": {
|
||||
"title": "Grades",
|
||||
"subject": "Subject",
|
||||
"grade": "Grade",
|
||||
"date": "Date",
|
||||
"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",
|
||||
"no_grades": "No grades",
|
||||
"september": "September",
|
||||
"october": "October",
|
||||
"november": "November",
|
||||
"december": "December",
|
||||
"january_1": "January I",
|
||||
"january_2": "January II",
|
||||
"february": "February",
|
||||
"march": "March",
|
||||
"april": "April",
|
||||
"may": "May",
|
||||
"june_1": "June I",
|
||||
"june_2": "June II"
|
||||
},
|
||||
"timetable": {
|
||||
"title": "Timetable",
|
||||
"lesson": "Lesson",
|
||||
"time": "Time",
|
||||
"subject": "Subject",
|
||||
"teacher": "Teacher",
|
||||
"classroom": "Classroom",
|
||||
"homework_indicator": "Homework",
|
||||
"test_indicator": "Test",
|
||||
"teacher_label": "Teacher:",
|
||||
"substitute_teacher_label": "Substitute teacher:",
|
||||
"classroom_label": "Classroom:",
|
||||
"time_label": "Time:",
|
||||
"status_label": "Status:",
|
||||
"substitution": "Substitution",
|
||||
"cancelled": "Cancelled",
|
||||
"has_homework": "Has homework",
|
||||
"no_lessons_this_week": "No lessons this week or timeout occurred",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"found_current_week": "Found current week",
|
||||
"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",
|
||||
"due_date": "Due date",
|
||||
"subject": "Subject",
|
||||
"description": "Description",
|
||||
"filter_title": "Filter",
|
||||
"all_subjects": "All subjects",
|
||||
"all_teachers": "All teachers",
|
||||
"all_deadlines": "All deadlines",
|
||||
"tomorrow_deadline": "Tomorrow's deadline",
|
||||
"this_week": "This week",
|
||||
"next_week": "Next week",
|
||||
"no_homework": "No homework to display.",
|
||||
"no_filtered_homework": "No homework matching the filter criteria.",
|
||||
"teacher": "Teacher",
|
||||
"no_matching_homework": "No homework matching the filter criteria.",
|
||||
"items": "items",
|
||||
"status": "Status",
|
||||
"total_homework": "Total homework",
|
||||
"urgent_homework": "Urgent homework",
|
||||
"completed_homework": "Completed homework",
|
||||
"pending_homework": "Pending homework",
|
||||
"completed": "Completed",
|
||||
"urgent": "Urgent",
|
||||
"pending": "Pending"
|
||||
},
|
||||
"absences": {
|
||||
"title": "Absences",
|
||||
"date": "Date",
|
||||
"lesson": "Lesson",
|
||||
"type": "Type",
|
||||
"justified": "Justified",
|
||||
"unjustified": "Unjustified",
|
||||
"filter_title": "Filter",
|
||||
"all_subjects": "All subjects",
|
||||
"all_types": "All types",
|
||||
"pending": "Pending justification",
|
||||
"subject": "Subject",
|
||||
"justification": "Justification",
|
||||
"hours": "hours",
|
||||
"page_transform_error": "An error occurred while transforming the page",
|
||||
"time_period": "Time period",
|
||||
"all_periods": "All periods",
|
||||
"current_month": "Current month",
|
||||
"last_month": "Last month",
|
||||
"current_semester": "Current semester",
|
||||
"last_30_days": "Last 30 days",
|
||||
"total_absences": "Total absences",
|
||||
"topic": "Topic",
|
||||
"status": "Status"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile",
|
||||
"name": "Name",
|
||||
"class": "Class",
|
||||
"school": "School",
|
||||
"student_id": "Student ID",
|
||||
"settings_title": "Profile settings",
|
||||
"tab_settings": "Settings",
|
||||
"tab_password": "Change password",
|
||||
"tab_security": "Security settings",
|
||||
"tab_contacts": "Contact information",
|
||||
"two_factor_description": "To use two-factor authentication, install a time-based one-time password (TOTP) application:",
|
||||
"android": "Android",
|
||||
"iphone": "iPhone",
|
||||
"enable_2fa": "Enable two-factor authentication",
|
||||
"security_key": "Security key:",
|
||||
"verification_code_label": "Verification code",
|
||||
"verification_code_help": "Enter the 6-digit code shown in your authenticator app.",
|
||||
"verification_code_placeholder": "123456",
|
||||
"verify_and_activate": "Verify and activate",
|
||||
"backup_codes_description": "You can use the following backup codes to log in if you don't have access to your authenticator app. Each code can only be used once.",
|
||||
"email_label": "Email address",
|
||||
"email_help": "Email address is required for password recovery.",
|
||||
"phone_label": "Phone number",
|
||||
"phone_help": "Phone number is optional.",
|
||||
"phone_placeholder": "+1 xxx xxx xxxx",
|
||||
"current_password": "Current password",
|
||||
"new_password": "New password",
|
||||
"new_password_help": "Password must be at least 8 characters long.",
|
||||
"confirm_password": "Confirm new password",
|
||||
"change_password": "Change password",
|
||||
"show_tips": "Show tips",
|
||||
"show_tips_help": "Toggle display of tips on/off.",
|
||||
"email_required": "Email address is required!",
|
||||
"email_invalid": "Please enter a valid email address!",
|
||||
"phone_invalid": "Please enter a valid phone number!",
|
||||
"contacts_saved": "Contact information saved successfully!",
|
||||
"contacts_save_error": "An error occurred while saving. Please try again later.",
|
||||
"settings_saved": "Settings saved successfully! Please log in again for changes to take effect.",
|
||||
"settings_save_error": "An error occurred while saving. Please try again later.",
|
||||
"password_fields_required": "Please fill in all fields!",
|
||||
"passwords_not_match": "New passwords do not match!",
|
||||
"password_too_short": "New password must be at least 8 characters long!",
|
||||
"password_changed": "Password changed successfully!",
|
||||
"password_change_error": "An error occurred while changing password. Please try again later."
|
||||
},
|
||||
"login": {
|
||||
"title": "Login",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"login_button": "Login",
|
||||
"forgot_password": "Forgot password",
|
||||
"two_factor_title": "Two-factor authentication",
|
||||
"verification_code": "Verification code",
|
||||
"username_placeholder": "Username",
|
||||
"password_placeholder": "Password",
|
||||
"username_required": "Please enter your username.",
|
||||
"password_required": "Please enter your password.",
|
||||
"help_login": "Can't log in?",
|
||||
"help_link": "Help",
|
||||
"system_message": "System message",
|
||||
"privacy_policy": "Privacy policy",
|
||||
"kreta_id": "KRÉTA ID",
|
||||
"system_notification": "System notification"
|
||||
},
|
||||
"forgot_password": {
|
||||
"title": "Forgot password",
|
||||
"om_id": "OM ID",
|
||||
"email": "Email address",
|
||||
"om_id_placeholder": "Enter your OM ID",
|
||||
"email_placeholder": "Enter your email address",
|
||||
"om_id_required": "Please enter your OM ID.",
|
||||
"email_required": "Please enter your email address."
|
||||
},
|
||||
"two_factor": {
|
||||
"title": "Two-factor authentication",
|
||||
"code_placeholder": "One-time password",
|
||||
"code_required": "Please enter the one-time password.",
|
||||
"verify_button": "Verify code",
|
||||
"verifying": "Verifying...",
|
||||
"trust_device": "Trust this device"
|
||||
},
|
||||
"logout": {
|
||||
"title": "Logout",
|
||||
"message": "Are you sure you want to logout?",
|
||||
"confirm": "Yes",
|
||||
"cancel": "Cancel",
|
||||
"success": "Successfully logged out!",
|
||||
"continue": "Continue"
|
||||
},
|
||||
"common": {
|
||||
"save": "Save",
|
||||
"cancel": "Cancel",
|
||||
"close": "Close",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"warning": "Warning",
|
||||
"info": "Information",
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
"continue": "Continue",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"previous": "Previous",
|
||||
"all": "All",
|
||||
"none": "None",
|
||||
"filter": "Filter",
|
||||
"search": "Search",
|
||||
"select": "Select",
|
||||
"required": "Required",
|
||||
"optional": "Optional",
|
||||
"api_error": "API error",
|
||||
"api_load_error": "API load error",
|
||||
"monday": "Monday",
|
||||
"tuesday": "Tuesday",
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"saturday": "Saturday",
|
||||
"sunday": "Sunday",
|
||||
"today": "Today",
|
||||
"tomorrow": "Tomorrow"
|
||||
},
|
||||
"months": {
|
||||
"january": "January",
|
||||
"february": "February",
|
||||
"march": "March",
|
||||
"april": "April",
|
||||
"may": "May",
|
||||
"june": "June",
|
||||
"july": "July",
|
||||
"august": "August",
|
||||
"september": "September",
|
||||
"october": "October",
|
||||
"november": "November",
|
||||
"december": "December"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Student Book",
|
||||
"student_description": "View grades, absences, timetable and other information.",
|
||||
"dkt_title": "Digital Collaboration Space (DKT)",
|
||||
"dkt_description": "Classroom communication and assignments.",
|
||||
"logout_title": "Logout",
|
||||
"logout_description": "Log out of the system",
|
||||
"role_change_error": "An error occurred while changing roles."
|
||||
},
|
||||
"maintenance": {
|
||||
"title": "Maintenance",
|
||||
"message1": "The KRÉTA system is currently being updated and will be available again soon.",
|
||||
"message2": "Thank you for your patience and understanding!",
|
||||
"team": "KRÉTA Team"
|
||||
},
|
||||
"about": {
|
||||
"title": "About",
|
||||
"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.3.0"
|
||||
},
|
||||
"app": {
|
||||
"title": "Firka - KRÉTA",
|
||||
"settings_title": "Firka - Settings"
|
||||
},
|
||||
"forgotpassword": {
|
||||
"title": "Forgot Password",
|
||||
"om_id_label": "OM ID",
|
||||
"om_id_placeholder": "Enter your OM ID",
|
||||
"om_id_required": "OM ID is required",
|
||||
"email_label": "Email address",
|
||||
"email_placeholder": "Enter your email address",
|
||||
"email_required": "Email address is required",
|
||||
"back_to_login": "Back to login",
|
||||
"reset_button": "Reset password",
|
||||
"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 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
465
i18n/hu.json
Normal file
@@ -0,0 +1,465 @@
|
||||
{
|
||||
"loading": {
|
||||
"text": "Betöltés alatt...",
|
||||
"subtext": "Kis türelmet!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Beállítások",
|
||||
"theme": "Téma",
|
||||
"language": "Nyelv",
|
||||
"themes": {
|
||||
"light_blue": "Világos Kék",
|
||||
"light_green": "Világos Zöld",
|
||||
"dark_blue": "Sötét Kék",
|
||||
"dark_green": "Sötét Zöld",
|
||||
"dark_red": "Sötét Piros",
|
||||
"dark_purple": "Sötét Lila",
|
||||
"dark_orange": "Sötét Narancs",
|
||||
"dark_pink": "Sötét Rózsaszín",
|
||||
"dark_yellow": "Sötét Sárga",
|
||||
"dark_cyan": "Sötét Cián",
|
||||
"dark_lime": "Sötét Lime",
|
||||
"dark_indigo": "Sötét Indigó"
|
||||
},
|
||||
"languages": {
|
||||
"hu": "Magyar",
|
||||
"en": "English"
|
||||
},
|
||||
"about": {
|
||||
"title": "Névjegy",
|
||||
"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.",
|
||||
"github": "GitHub"
|
||||
},
|
||||
"support": {
|
||||
"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": {
|
||||
"dashboard": "Kezdőlap",
|
||||
"timetable": "Órarend",
|
||||
"grades": "Jegyek",
|
||||
"homework": "Házi feladatok",
|
||||
"absences": "Mulasztások",
|
||||
"messages": "Üzenetek",
|
||||
"profile": "Profil",
|
||||
"settings": "Beállítások",
|
||||
"logout": "Kijelentkezés",
|
||||
"nav_toggle": "Navigáció megnyitása"
|
||||
},
|
||||
"dashboard": {
|
||||
"welcome": "Üdvözöljük",
|
||||
"recent_grades": "Legutóbbi jegyek",
|
||||
"upcoming_lessons": "Következő órák",
|
||||
"homework_due": "Esedékes házi feladatok",
|
||||
"news": "Hírek",
|
||||
"grades": "Értékeléseid",
|
||||
"absences": "Mulasztások",
|
||||
"notes": "Feljegyzések",
|
||||
"exams": "Bejelentett dolgozatok",
|
||||
"all_news": "Összes hír",
|
||||
"all_grades": "Összes jegyed",
|
||||
"all_absences": "Összes mulasztás",
|
||||
"all_messages": "Összes üzeneted",
|
||||
"all_exams": "Összes dolgozat",
|
||||
"not_supported": "Jelenleg nincsen adat amivel fel lehetne tölteni",
|
||||
"evaluation": "Értékelés"
|
||||
},
|
||||
"grades": {
|
||||
"title": "Jegyek",
|
||||
"subject": "Tantárgy",
|
||||
"grade": "Jegy",
|
||||
"date": "Dátum",
|
||||
"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",
|
||||
"no_grades": "Nincsenek jegyek",
|
||||
"september": "Szeptember",
|
||||
"october": "Oktober",
|
||||
"november": "November",
|
||||
"december": "December",
|
||||
"january_1": "JanuarI",
|
||||
"january_2": "JanuarII",
|
||||
"february": "Februar",
|
||||
"march": "Marcius",
|
||||
"april": "Aprilis",
|
||||
"may": "Majus",
|
||||
"june_1": "JuniusI",
|
||||
"june_2": "JuniusII"
|
||||
},
|
||||
"timetable": {
|
||||
"title": "Órarend",
|
||||
"lesson": "Óra",
|
||||
"time": "Idő",
|
||||
"subject": "Tantárgy",
|
||||
"teacher": "Tanár",
|
||||
"classroom": "Terem",
|
||||
"homework_indicator": "Házi feladat",
|
||||
"test_indicator": "Számonkérés",
|
||||
"teacher_label": "Tanár:",
|
||||
"substitute_teacher_label": "Helyettesítő tanár:",
|
||||
"classroom_label": "Terem:",
|
||||
"time_label": "Időpont:",
|
||||
"status_label": "Állapot:",
|
||||
"substitution": "Helyettesítés",
|
||||
"cancelled": "Elmarad",
|
||||
"has_homework": "Van házi feladat",
|
||||
"no_lessons_this_week": "Nincsenek órák ezen a héten vagy időtúllépés történt",
|
||||
"monday": "Hétfő",
|
||||
"tuesday": "Kedd",
|
||||
"wednesday": "Szerda",
|
||||
"thursday": "Csütörtök",
|
||||
"friday": "Péntek",
|
||||
"found_current_week": "Megtalált jelenlegi hét",
|
||||
"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",
|
||||
"due_date": "Határidő",
|
||||
"subject": "Tantárgy",
|
||||
"description": "Leírás",
|
||||
"filter_title": "Szűrő",
|
||||
"all_subjects": "Minden tantárgy",
|
||||
"all_teachers": "Minden tanár",
|
||||
"all_deadlines": "Minden határidő",
|
||||
"tomorrow_deadline": "Holnapi határidő",
|
||||
"this_week": "Ezen a héten",
|
||||
"next_week": "Következő héten",
|
||||
"no_homework": "Nincs megjeleníthető házi feladat.",
|
||||
"no_filtered_homework": "Nincs a szűrési feltételeknek megfelelő házi feladat.",
|
||||
"teacher": "Tanár",
|
||||
"no_matching_homework": "Nincs a szűrési feltételeknek megfelelő házi feladat.",
|
||||
"items": "elem",
|
||||
"status": "Állapot",
|
||||
"total_homework": "Összes feladat",
|
||||
"urgent_homework": "Sürgős feladat",
|
||||
"completed_homework": "Befejezett feladat",
|
||||
"pending_homework": "Függőben lévő feladat",
|
||||
"completed": "Befejezve",
|
||||
"urgent": "Sürgős",
|
||||
"pending": "Függőben"
|
||||
},
|
||||
"absences": {
|
||||
"title": "Hiányzások",
|
||||
"date": "Dátum",
|
||||
"lesson": "Óra",
|
||||
"type": "Típus",
|
||||
"justified": "Igazolt",
|
||||
"unjustified": "Igazolatlan",
|
||||
"filter_title": "Szűrés",
|
||||
"all_subjects": "Minden tantárgy",
|
||||
"all_types": "Mindegy",
|
||||
"pending": "Igazolásra vár",
|
||||
"subject": "Tantárgy",
|
||||
"justification": "Igazolás",
|
||||
"hours": "óra",
|
||||
"page_transform_error": "Hiba történt az oldal átalakítása során",
|
||||
"time_period": "Időszak",
|
||||
"all_periods": "Összes időszak",
|
||||
"current_month": "Aktuális hónap",
|
||||
"last_month": "Előző hónap",
|
||||
"current_semester": "Aktuális félév",
|
||||
"last_30_days": "Utolsó 30 nap",
|
||||
"total_absences": "Összes hiányzás",
|
||||
"topic": "Téma",
|
||||
"status": "Állapot"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profil",
|
||||
"name": "Név",
|
||||
"class": "Osztály",
|
||||
"school": "Iskola",
|
||||
"student_id": "Diák azonosító",
|
||||
"settings_title": "Profil beállítások",
|
||||
"tab_settings": "Beállítások",
|
||||
"tab_password": "Jelszó módosítása",
|
||||
"tab_security": "Biztonsági beállítások",
|
||||
"tab_contacts": "Elérhetőségek",
|
||||
"two_factor_description": "A kétfaktoros hitelesítés használatához telepítsen egy időalapú, egyszer használatos jelszó (TOTP) alkalmazást:",
|
||||
"android": "Android",
|
||||
"iphone": "iPhone",
|
||||
"enable_2fa": "Kétfaktoros azonosítás bekapcsolása",
|
||||
"security_key": "Biztonsági kulcs:",
|
||||
"verification_code_label": "Ellenőrző kód",
|
||||
"verification_code_help": "Adja meg a hitelesítő alkalmazásban megjelenő 6 számjegyű kódot.",
|
||||
"verification_code_placeholder": "123456",
|
||||
"verify_and_activate": "Ellenőrzés és aktiválás",
|
||||
"backup_codes_description": "Az alábbi biztonsági kódokat használhatja bejelentkezéshez, ha nem fér hozzá a hitelesítő alkalmazásához. Minden kód csak egyszer használható.",
|
||||
"email_label": "E-mail cím",
|
||||
"email_help": "Az e-mail cím megadása a jelszó emlékeztető miatt szükséges.",
|
||||
"phone_label": "Telefonszám",
|
||||
"phone_help": "A telefonszám megadása nem kötelező.",
|
||||
"phone_placeholder": "+36 xx xxx xxxx",
|
||||
"current_password": "Jelenlegi jelszó",
|
||||
"new_password": "Új jelszó",
|
||||
"new_password_help": "A jelszónak legalább 8 karakter hosszúnak kell lennie.",
|
||||
"confirm_password": "Új jelszó megerősítése",
|
||||
"change_password": "Jelszó módosítása",
|
||||
"show_tips": "Tippek megjelenítése",
|
||||
"show_tips_help": "A tippek megjelenítésének ki/be kapcsolása.",
|
||||
"email_required": "Az e-mail cím megadása kötelező!",
|
||||
"email_invalid": "Kérjük, adjon meg egy érvényes e-mail címet!",
|
||||
"phone_invalid": "Kérjük, adjon meg egy érvényes telefonszámot!",
|
||||
"contacts_saved": "Elérhetőségek sikeresen mentve!",
|
||||
"contacts_save_error": "Hiba történt a mentés során. Kérjük, próbálja újra később.",
|
||||
"settings_saved": "Beállítások sikeresen mentve! A változtatások érvényesítéséhez jelentkezzen be újra.",
|
||||
"settings_save_error": "Hiba történt a mentés során. Kérjük, próbálja újra később.",
|
||||
"password_fields_required": "Kérjük, töltse ki az összes mezőt!",
|
||||
"passwords_not_match": "Az új jelszavak nem egyeznek!",
|
||||
"password_too_short": "Az új jelszónak legalább 8 karakter hosszúnak kell lennie!",
|
||||
"password_changed": "Jelszó sikeresen módosítva!",
|
||||
"password_change_error": "Hiba történt a jelszó módosítása során. Kérjük, próbálja újra később."
|
||||
},
|
||||
"login": {
|
||||
"title": "Bejelentkezés",
|
||||
"username": "Felhasználónév",
|
||||
"password": "Jelszó",
|
||||
"login_button": "Bejelentkezés",
|
||||
"forgot_password": "Elfelejtett jelszó",
|
||||
"two_factor_title": "Kétfaktoros hitelesítés",
|
||||
"verification_code": "Ellenőrző kód",
|
||||
"username_placeholder": "Felhasználónév",
|
||||
"password_placeholder": "Jelszó",
|
||||
"username_required": "Kérjük, add meg a felhasználóneved.",
|
||||
"password_required": "Kérjük, add meg a jelszavad.",
|
||||
"help_login": "Nem tudsz bejelentkezni?",
|
||||
"help_link": "Segítség",
|
||||
"system_message": "Rendszerüzenet",
|
||||
"privacy_policy": "Adatvédelmi szabályzat",
|
||||
"kreta_id": "KRÉTA azonosító",
|
||||
"system_notification": "Rendszerértesítés"
|
||||
},
|
||||
"forgot_password": {
|
||||
"title": "Elfelejtett jelszó",
|
||||
"om_id": "OM azonosítód",
|
||||
"email": "E-mail cím",
|
||||
"om_id_placeholder": "Add meg az OM azonosítód",
|
||||
"email_placeholder": "Add meg az e-mail címed",
|
||||
"om_id_required": "Kérjük, add meg az OM azonosítód.",
|
||||
"email_required": "Kérjük, add meg az e-mail címed."
|
||||
},
|
||||
"two_factor": {
|
||||
"title": "Kétfaktoros azonosítás",
|
||||
"code_placeholder": "Egyszeri jelszó",
|
||||
"code_required": "Kérjük, add meg az egyszeri jelszót.",
|
||||
"verify_button": "Kód ellenőrzése",
|
||||
"verifying": "Ellenőrzés...",
|
||||
"trust_device": "Eszköz megbízhatónak jelölése"
|
||||
},
|
||||
"logout": {
|
||||
"title": "Kijelentkezés",
|
||||
"message": "Biztosan ki szeretne jelentkezni?",
|
||||
"confirm": "Igen",
|
||||
"cancel": "Mégse",
|
||||
"success": "Sikeres kijelentkezés!",
|
||||
"continue": "Tovább"
|
||||
},
|
||||
"common": {
|
||||
"save": "Mentés",
|
||||
"cancel": "Mégse",
|
||||
"close": "Bezárás",
|
||||
"loading": "Betöltés...",
|
||||
"error": "Hiba",
|
||||
"success": "Sikeres",
|
||||
"warning": "Figyelmeztetés",
|
||||
"info": "Információ",
|
||||
"yes": "Igen",
|
||||
"no": "Nem",
|
||||
"continue": "Tovább",
|
||||
"back": "Vissza",
|
||||
"next": "Következő",
|
||||
"previous": "Előző",
|
||||
"all": "Összes",
|
||||
"none": "Nincs",
|
||||
"filter": "Szűrés",
|
||||
"search": "Keresés",
|
||||
"select": "Válassz",
|
||||
"required": "Kötelező",
|
||||
"optional": "Opcionális",
|
||||
"api_error": "API hiba",
|
||||
"api_load_error": "API betöltési hiba",
|
||||
"monday": "hétfő",
|
||||
"tuesday": "kedd",
|
||||
"wednesday": "szerda",
|
||||
"thursday": "csütörtök",
|
||||
"friday": "péntek",
|
||||
"saturday": "szombat",
|
||||
"sunday": "vasárnap",
|
||||
"today": "Ma",
|
||||
"tomorrow": "Holnap"
|
||||
},
|
||||
"months": {
|
||||
"january": "január",
|
||||
"february": "február",
|
||||
"march": "március",
|
||||
"april": "április",
|
||||
"may": "május",
|
||||
"june": "június",
|
||||
"july": "július",
|
||||
"august": "augusztus",
|
||||
"september": "szeptember",
|
||||
"october": "október",
|
||||
"november": "november",
|
||||
"december": "december"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Ellenőrzőkönyv",
|
||||
"student_description": "Jegyek, hiányzások, órarended és egyéb információk megtekintése.",
|
||||
"dkt_title": "Digitális Kollaborációs Tér (DKT)",
|
||||
"dkt_description": "Osztálytermi kommunikáció és feladatok.",
|
||||
"logout_title": "Kijelentkezés",
|
||||
"logout_description": "Kilépés a rendszerből",
|
||||
"role_change_error": "Hiba történt a szerepkör váltása közben."
|
||||
},
|
||||
"maintenance": {
|
||||
"title": "Karbantartás",
|
||||
"message1": "A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.",
|
||||
"message2": "Köszönjük türelmüket és megértésüket!",
|
||||
"team": "KRÉTA Csapat"
|
||||
},
|
||||
"about": {
|
||||
"title": "Névjegy",
|
||||
"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.3.0"
|
||||
},
|
||||
"app": {
|
||||
"title": "Firka - KRÉTA",
|
||||
"settings_title": "Firxa - Beállítások"
|
||||
},
|
||||
"forgotpassword": {
|
||||
"title": "Elfelejtett jelszó",
|
||||
"om_id_label": "OM azonosító",
|
||||
"om_id_placeholder": "Adja meg az OM azonosítóját",
|
||||
"om_id_required": "Az OM azonosító megadása kötelező",
|
||||
"email_label": "E-mail cím",
|
||||
"email_placeholder": "Adja meg az e-mail címét",
|
||||
"email_required": "Az e-mail cím megadása kötelező",
|
||||
"back_to_login": "Vissza a bejelentkezéshez",
|
||||
"reset_button": "Jelszó visszaállítása",
|
||||
"error_message": "Hiba történt a jelszó visszaállítása során",
|
||||
"success_message": "A jelszó visszaállítási link elküldve az e-mail címére",
|
||||
"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/ArrowsExpandFull.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="M15 19h4m0 0v-4m0 4l-4-4M9 5H5m0 0v4m0-4l4 4m6-4h4m0 0v4m0-4l-4 4M9 19H5m0 0v-4m0 4l4-4"/></svg>
|
||||
|
After Width: | Height: | Size: 283 B |
1
icons/BadgeCheck.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="M10.054 2.344a3 3 0 0 1 3.892 0l1.271 1.084a1 1 0 0 0 .57.236l1.665.133a3 3 0 0 1 2.751 2.751l.133 1.666a1 1 0 0 0 .236.569l1.084 1.271a3 3 0 0 1 0 3.892l-1.084 1.271a1 1 0 0 0-.236.57l-.133 1.665a3 3 0 0 1-2.751 2.751l-1.666.133a1 1 0 0 0-.569.236l-1.271 1.084a3 3 0 0 1-3.892 0l-1.271-1.084a1 1 0 0 0-.57-.236l-1.665-.133a3 3 0 0 1-2.751-2.751l-.133-1.666a1 1 0 0 0-.236-.569l-1.084-1.271a3 3 0 0 1 0-3.892l1.084-1.271a1 1 0 0 0 .236-.57l.133-1.665a3 3 0 0 1 2.751-2.751l1.666-.133a1 1 0 0 0 .569-.236l1.271-1.084zm5.653 8.363a1 1 0 0 0-1.414-1.414L11 12.586l-1.293-1.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 799 B |
1
icons/Calendar.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="M4 7v2h16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2"/><path stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 5h2a2 2 0 0 1 2 2v2H4V7a2 2 0 0 1 2-2h2m8 0V3m0 2H8m0-2v2M4 9.5V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9.5"/></g></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
1
icons/ChevronLeftCircle.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="M12 21a9 9 0 1 0 0-18a9 9 0 0 0 0 18m1.707-11.293a1 1 0 0 0-1.414-1.414l-3 3a1 1 0 0 0 0 1.414l3 3a1 1 0 0 0 1.414-1.414L11.414 12z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
icons/ChevronRightCircle.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="M12 21a9 9 0 1 0 0-18a9 9 0 0 0 0 18M10.293 9.707a1 1 0 1 1 1.414-1.414l3 3a1 1 0 0 1 0 1.414l-3 3a1 1 0 0 1-1.414-1.414L12.586 12z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
icons/CloseCircle.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="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12zm8.207-3.207a1 1 0 0 0-1.414 1.414L10.586 12l-1.793 1.793a1 1 0 1 0 1.414 1.414L12 13.414l1.793 1.793a1 1 0 0 0 1.414-1.414L13.414 12l1.793-1.793a1 1 0 0 0-1.414-1.414L12 10.586l-1.793-1.793z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
1
icons/Subject.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.514 3.126a1 1 0 0 1 .972 0l9 5A1 1 0 0 1 22 9v7a1 1 0 1 1-2 0v-5.3l-1 .555v.004l-6.067 3.016a2 2 0 0 1-1.848-.035L2.357 9.479a1 1 0 0 0-.284-.103a1 1 0 0 1 .441-1.25l9-5zM5 13.199V17a1 1 0 0 0 .553.894l6 3a1 1 0 0 0 .894 0l6-3A1 1 0 0 0 19 17v-3.256l-6.083 2.844a2 2 0 0 1-1.805-.056L5 13.2z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
icons/assigment.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 stroke="#FFA046" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 8H9m2 4H9"/><path fill="#FFA046" d="M3 16h8c0 1.333.8 4 4 4a3 3 0 0 0 3-3V4h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1v7a3 3 0 0 1-3 3H5a2 2 0 0 1-2-2z"/><path stroke="#FFA046" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 20c-3.2 0-4-2.667-4-4H3v2a2 2 0 0 0 2 2zm0 0a3 3 0 0 0 3-3v-7m0-6H7a2 2 0 0 0-2 2v9.5M18 4h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1m0-6v6"/></g></svg>
|
||||
|
After Width: | Height: | Size: 578 B |
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/homework.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="M15.586 3a2 2 0 0 1 2.828 0L21 5.586a2 2 0 0 1 0 2.828L19.414 10L14 4.586L15.586 3zm-3 3l-9 9A2 2 0 0 0 3 16.414V19a2 2 0 0 0 2 2h2.586A2 2 0 0 0 9 20.414l9-9L12.586 6z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 345 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
icons/pipa.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="#A7DC22"><path d="M19.707 6.293a1 1 0 0 1 0 1.414l-10 10a1 1 0 0 1-1.414 0l-4-4a1 1 0 1 1 1.414-1.414L9 15.586l9.293-9.293a1 1 0 0 1 1.414 0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 248 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 |
BIN
images/cactus.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
images/chrome.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
images/firefox.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
images/firefoxact.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
529
login/login.css
@@ -1,385 +1,306 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="light-green"] {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--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;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 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", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
margin-bottom:16px;
|
||||
border-radius:24px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0;
|
||||
background: var(--card-card) !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0) !important;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:16px 0;
|
||||
background:var(--card-card) !important;
|
||||
border-bottom:1px solid rgba(0,0,0,0) !important;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
.school-name {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 14px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-15) !important;
|
||||
border: 0px solid var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 14px;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
align-self:stretch;
|
||||
border-radius:12px;
|
||||
background:var(--accent-15) !important;
|
||||
border:0px solid var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
outline:none;
|
||||
border-color:var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
color:var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.password-group {
|
||||
position: relative;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.show-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position:absolute;
|
||||
right:12px;
|
||||
top:50%;
|
||||
transform:translateY(-50%);
|
||||
background:none;
|
||||
border:none;
|
||||
padding:4px;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.icon-eye {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s ease;
|
||||
filter: invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
width:20px;
|
||||
height:20px;
|
||||
opacity:0.6;
|
||||
transition:opacity 0.2s ease;
|
||||
filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
}
|
||||
|
||||
.show-password:hover .icon-eye {
|
||||
opacity: 1;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 24px;
|
||||
margin-top:24px;
|
||||
}
|
||||
|
||||
.help-links {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top:16px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
color:var(--text-primary);
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
text-decoration:none;
|
||||
transition:color 0.2s ease;
|
||||
}
|
||||
|
||||
.help-link:hover {
|
||||
color: var(--text-teritary);
|
||||
color:var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-family: "Montserrat", serif;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
position: relative;
|
||||
width:100%;
|
||||
padding:12px;
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-size:16px;
|
||||
font-weight:600;
|
||||
font-family:"Montserrat",serif;
|
||||
cursor:pointer;
|
||||
transition:background 0.2s ease;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.btn-login:hover {
|
||||
background: var(--text-teritary);
|
||||
background:var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-login:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
opacity:0.7;
|
||||
cursor:not-allowed;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: -0.3px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:18px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
letter-spacing:-0.3px;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
align-self: stretch;
|
||||
border-radius: 24px;
|
||||
background: var(--card-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
padding:20px;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:12px;
|
||||
align-self:stretch;
|
||||
border-radius:24px;
|
||||
background:var(--card-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.system-message h4 {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.system-message p {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
text-decoration: none;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--text-teritary);
|
||||
color:var(--text-teritary);
|
||||
}
|
||||
|
||||
|
||||
.form-control.error {
|
||||
border-color: var(--error-accent) !important;
|
||||
background: var(--error-card) !important;
|
||||
border-color:var(--error-accent) !important;
|
||||
background:var(--error-card) !important;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: var(--error-text);
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
color:var(--error-text);
|
||||
font-size:14px;
|
||||
margin-top:4px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
display:block;
|
||||
animation:fadeIn 0.2s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity:0;
|
||||
transform:translateY(-4px);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: translate(-50%, -50%) rotate(360deg); }
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
}@keyframes spin {
|
||||
to {
|
||||
transform:translate(-50%,-50%) rotate(360deg);
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.login-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.school-name {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
height: 44px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
font-size: 12px;
|
||||
}
|
||||
padding:16px;
|
||||
}
|
||||
.login-card {
|
||||
padding:20px;
|
||||
}
|
||||
.card-header {
|
||||
margin-bottom:20px;
|
||||
padding-bottom:16px;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:20px;
|
||||
}
|
||||
.school-name {
|
||||
font-size:16px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:12px;
|
||||
}
|
||||
.form-control {
|
||||
height:44px;
|
||||
font-size:14px;
|
||||
}
|
||||
.btn-login {
|
||||
padding:10px;
|
||||
font-size:14px;
|
||||
}
|
||||
.help-link {
|
||||
font-size:12px;
|
||||
}
|
||||
}
|
||||
190
login/login.js
@@ -1,50 +1,59 @@
|
||||
async function transformLoginPage() {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) => {
|
||||
window.addEventListener("load", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
const existingForm = document.querySelector('form');
|
||||
|
||||
const existingForm = document.querySelector("form");
|
||||
const formData = {
|
||||
action: existingForm?.getAttribute('action') || '',
|
||||
returnUrl: document.querySelector('#ReturnUrl')?.value || '',
|
||||
instituteCode: document.querySelector('#instituteCode')?.value || '',
|
||||
requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '',
|
||||
userName: document.querySelector('#UserName')?.value || '',
|
||||
password: document.querySelector('#Password')?.value || ''
|
||||
action: existingForm?.getAttribute("action") || "",
|
||||
returnUrl: document.querySelector("#ReturnUrl")?.value || "",
|
||||
instituteCode: document.querySelector("#instituteCode")?.value || "",
|
||||
requestToken:
|
||||
document.querySelector('input[name="__RequestVerificationToken"]')
|
||||
?.value || "",
|
||||
userName: document.querySelector("#UserName")?.value || "",
|
||||
password: document.querySelector("#Password")?.value || "",
|
||||
};
|
||||
|
||||
const titleElement = document.querySelector('.page-title');
|
||||
|
||||
const titleElement = document.querySelector(".page-title");
|
||||
const schoolInfo = {
|
||||
name: titleElement?.querySelector('b')?.textContent?.trim() || '',
|
||||
kretaId: '',
|
||||
omCode: ''
|
||||
name: titleElement?.querySelector("b")?.textContent?.trim() || "",
|
||||
kretaId: "",
|
||||
omCode: "",
|
||||
};
|
||||
|
||||
const spanElement = titleElement?.querySelector('span');
|
||||
|
||||
const spanElement = titleElement?.querySelector("span");
|
||||
if (spanElement) {
|
||||
const lines = spanElement.textContent?.split('\n').map(line => line.trim()) || [];
|
||||
schoolInfo.kretaId = lines[0] || '';
|
||||
schoolInfo.omCode = (lines[1] || '').replace('KRÉTA azonosító: ', '');
|
||||
const lines =
|
||||
spanElement.textContent?.split("\n").map((line) => line.trim()) || [];
|
||||
schoolInfo.kretaId = lines[0] || "";
|
||||
schoolInfo.omCode = (lines[1] || "").replace(
|
||||
`${LanguageManager.t("login.kreta_id")}: `,
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
const rawSystemMessage = document.querySelector('.alert-primary')?.textContent?.trim() || '';
|
||||
const systemMessage = rawSystemMessage.replace('Rendszerértesítés', '').trim();
|
||||
|
||||
|
||||
const rawSystemMessage =
|
||||
document.querySelector(".alert-primary")?.textContent?.trim() || "";
|
||||
const systemMessage = rawSystemMessage
|
||||
.replace("Rendszerértesítés", "")
|
||||
.trim();
|
||||
|
||||
const newHTML = `
|
||||
<div class="login-container">
|
||||
<div class="login-card">
|
||||
<div class="card-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="school-name">${schoolInfo.name}</h1>
|
||||
<div class="school-details">
|
||||
${schoolInfo.kretaId ? `<div>${schoolInfo.kretaId}</div>` : ''}
|
||||
${schoolInfo.omCode ? `<div>KRÉTA azonosító: ${schoolInfo.omCode}</div>` : ''}
|
||||
${schoolInfo.kretaId ? `<div>${schoolInfo.kretaId}</div>` : ""}
|
||||
${schoolInfo.omCode ? `<div>${LanguageManager.t("login.kreta_id")}: ${schoolInfo.omCode}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -57,133 +66,136 @@ async function transformLoginPage() {
|
||||
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" id="UserName" name="UserName"
|
||||
placeholder="Felhasználónév" maxlength="256" autocomplete="username" required value="${formData.userName}">
|
||||
<div class="error-message">Kérjük, add meg a felhasználóneved.</div>
|
||||
placeholder="${LanguageManager.t("login.username_placeholder")}" maxlength="256" autocomplete="username" required value="${formData.userName}">
|
||||
<div class="error-message">${LanguageManager.t("login.username_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group password-group">
|
||||
<input class="form-control" type="password" id="Password" name="Password"
|
||||
placeholder="Jelszó" maxlength="256" autocomplete="current-password" required value="${formData.password}">
|
||||
<button type="button" class="show-password" aria-label="Jelszó mutatása">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-off.svg')}" alt="Show password" class="icon-eye">
|
||||
placeholder="${LanguageManager.t("login.password_placeholder")}" maxlength="256" autocomplete="current-password" required value="${formData.password}">
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t("login.show_password")}">
|
||||
<img src="${chrome.runtime.getURL("icons/eye-off.svg")}" alt="Show password" class="icon-eye">
|
||||
</button>
|
||||
<div class="error-message">Kérjük, add meg a jelszavad.</div>
|
||||
<div class="error-message">${LanguageManager.t("login.password_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn-login">
|
||||
<span class="spinner"></span>
|
||||
<span class="btn-text">Bejelentkezés</span>
|
||||
<span class="btn-text">${LanguageManager.t("login.login_button")}</span>
|
||||
</button>
|
||||
<div class="help-links">
|
||||
<a href="https://${schoolInfo.omCode ? `${schoolInfo.omCode}` : ''}.e-kreta.hu/Adminisztracio/ElfelejtettJelszo" class="help-link">Elfelejtettem a jelszavam</a>
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=2425086" target="_blank" class="help-link">Nem tudsz bejelentkezni?</a>
|
||||
<a href="https://${schoolInfo.omCode ? `${schoolInfo.omCode}` : ""}.e-kreta.hu/Adminisztracio/ElfelejtettJelszo" class="help-link">${LanguageManager.t("login.forgot_password")}</a>
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=2425086" target="_blank" class="help-link">${LanguageManager.t("login.help_link")}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
${systemMessage ? `
|
||||
${
|
||||
systemMessage
|
||||
? `
|
||||
<div class="system-message">
|
||||
<h4>Rendszerértesítés</h4>
|
||||
<h4>${LanguageManager.t("login.system_message")}</h4>
|
||||
<p>${systemMessage}</p>
|
||||
</div>
|
||||
` : ''}
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
<footer class="login-footer">
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">Adatkezelési tájékoztató</a>
|
||||
target="_blank" class="privacy-link">${LanguageManager.t("login.privacy_policy")}</a>
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
setupEventListeners();
|
||||
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
setupEventListeners();
|
||||
} catch (error) {
|
||||
console.error('Error transforming page:', error);
|
||||
console.error("Error transforming page:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
const loginForm = document.getElementById('loginForm');
|
||||
const passwordInput = document.getElementById('Password');
|
||||
const togglePasswordBtn = document.querySelector('.show-password');
|
||||
const formInputs = document.querySelectorAll('.form-control');
|
||||
|
||||
if (togglePasswordBtn && passwordInput) {
|
||||
togglePasswordBtn.addEventListener('click', () => {
|
||||
const isPassword = passwordInput.type === 'password';
|
||||
passwordInput.type = isPassword ? 'text' : 'password';
|
||||
const icon = togglePasswordBtn.querySelector('.icon-eye');
|
||||
icon.src = chrome.runtime.getURL(`icons/${isPassword ? 'eye-on' : 'eye-off'}.svg`);
|
||||
});
|
||||
}
|
||||
const loginForm = document.getElementById("loginForm");
|
||||
const passwordInput = document.getElementById("Password");
|
||||
const togglePasswordBtn = document.querySelector(".show-password");
|
||||
const formInputs = document.querySelectorAll(".form-control");
|
||||
|
||||
|
||||
formInputs.forEach(input => {
|
||||
|
||||
input.addEventListener('input', () => {
|
||||
if (togglePasswordBtn && passwordInput) {
|
||||
togglePasswordBtn.addEventListener("click", () => {
|
||||
const isPassword = passwordInput.type === "password";
|
||||
passwordInput.type = isPassword ? "text" : "password";
|
||||
const icon = togglePasswordBtn.querySelector(".icon-eye");
|
||||
icon.src = chrome.runtime.getURL(
|
||||
`icons/${isPassword ? "eye-on" : "eye-off"}.svg`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
formInputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if (loginForm) {
|
||||
loginForm.addEventListener('submit', handleSubmit);
|
||||
loginForm.addEventListener("submit", handleSubmit);
|
||||
}
|
||||
}
|
||||
|
||||
function validateInput(input, showError = false) {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
|
||||
|
||||
inputs.forEach(input => {
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
const submitButton = form.querySelector('.btn-login');
|
||||
const spinner = submitButton.querySelector('.spinner');
|
||||
const buttonText = submitButton.querySelector('.btn-text');
|
||||
|
||||
const submitButton = form.querySelector(".btn-login");
|
||||
const spinner = submitButton.querySelector(".spinner");
|
||||
const buttonText = submitButton.querySelector(".btn-text");
|
||||
|
||||
submitButton.disabled = true;
|
||||
spinner.style.display = 'inline-block';
|
||||
buttonText.style.opacity = '0';
|
||||
spinner.style.display = "inline-block";
|
||||
buttonText.style.opacity = "0";
|
||||
|
||||
|
||||
form.submit();
|
||||
}
|
||||
|
||||
|
||||
if (window.location.href.includes('idp.e-kreta.hu/Account/Login')) {
|
||||
transformLoginPage().catch(error => {
|
||||
console.error('Error:', error);
|
||||
if (window.location.href.includes("idp.e-kreta.hu/Account/Login")) {
|
||||
transformLoginPage().catch((error) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,326 +1,254 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
:root {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
:root[data-theme="light-green"] {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--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;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 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", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
margin-bottom:16px;
|
||||
border-radius:24px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0;
|
||||
background: var(--card-card) !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0) !important;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:16px 0;
|
||||
background:var(--card-card) !important;
|
||||
border-bottom:1px solid rgba(0,0,0,0) !important;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
.twofactor-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 130%;
|
||||
margin-bottom: 16px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:24px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:130%;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.twofactor-form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 14px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-15) !important;
|
||||
border: 0px solid var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 14px;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
align-self:stretch;
|
||||
border-radius:12px;
|
||||
background:var(--accent-15) !important;
|
||||
border:0px solid var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
outline:none;
|
||||
border-color:var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
color:var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.password-group {
|
||||
position: relative;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.show-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position:absolute;
|
||||
right:12px;
|
||||
top:50%;
|
||||
transform:translateY(-50%);
|
||||
background:none;
|
||||
border:none;
|
||||
padding:4px;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.icon-eye {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s ease;
|
||||
filter: invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
width:20px;
|
||||
height:20px;
|
||||
opacity:0.6;
|
||||
transition:opacity 0.2s ease;
|
||||
filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
}
|
||||
|
||||
.show-password:hover .icon-eye {
|
||||
opacity: 1;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
margin-top:16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
border-radius: 6px;
|
||||
border: 2px solid var(--accent-accent);
|
||||
background-color: var(--card-card);
|
||||
cursor: pointer;
|
||||
width:20px;
|
||||
height:20px;
|
||||
margin-right:8px;
|
||||
border-radius:6px;
|
||||
border:2px solid var(--accent-accent);
|
||||
background-color:var(--card-card);
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.form-check-input:checked {
|
||||
background-color: var(--accent-accent);
|
||||
border-color: var(--accent-accent);
|
||||
background-color:var(--accent-accent);
|
||||
border-color:var(--accent-accent);
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
color: var(--text-primary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
cursor: pointer;
|
||||
color:var(--text-primary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.btn-kreta {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 24px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
font-family: Montserrat;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 24px;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
border-radius:12px;
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
font-family:Montserrat;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:normal;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
transition:background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
background-color: var(--accent-secondary);
|
||||
background-color:var(--accent-secondary);
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--accent-accent);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
background:none;
|
||||
border:none;
|
||||
color:var(--accent-accent);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-decoration:underline;
|
||||
cursor:pointer;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: var(--accent-secondary);
|
||||
color:var(--accent-secondary);
|
||||
}
|
||||
|
||||
.subtext {
|
||||
color: var(--text-primary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
color:var(--text-primary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
margin-top:24px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-decoration: none;
|
||||
color:var(--text-secondary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
text-decoration: underline;
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
display: none;
|
||||
color: var(--error-text);
|
||||
font-family: Figtree;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
margin-top: 4px;
|
||||
display:none;
|
||||
color:var(--error-text);
|
||||
font-family:Figtree;
|
||||
font-size:12px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
margin-top:4px;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
border: 1px solid var(--error-accent) !important;
|
||||
border:1px solid var(--error-accent) !important;
|
||||
}
|
||||
|
||||
/* Hide original elements */
|
||||
header, main > .container-fluid, footer {
|
||||
display: none !important;
|
||||
header,main > .container-fluid,footer {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
@media (max-width:576px) {
|
||||
.login-container {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 16px;
|
||||
}
|
||||
width:100%;
|
||||
padding:16px;
|
||||
}
|
||||
.login-card {
|
||||
padding:16px;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,40 @@
|
||||
async function transformTwoFactorPage() {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) => {
|
||||
window.addEventListener("load", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.show();
|
||||
}
|
||||
|
||||
const existingForm = document.querySelector('form');
|
||||
const existingForm = document.querySelector("form");
|
||||
const formData = {
|
||||
action: existingForm?.getAttribute('action') || '',
|
||||
clientId: document.querySelector('#ClientId')?.value || '',
|
||||
rememberLogin: document.querySelector('#RememberLogin')?.value || 'False',
|
||||
returnUrl: document.querySelector('#ReturnUrl')?.value || '',
|
||||
isRecoveryCode: document.querySelector('#IsRecoveryCode')?.value || 'False',
|
||||
requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '',
|
||||
trustDeviceValue: document.querySelector('input[name="TrustDevice"][type="hidden"]')?.value || 'false'
|
||||
action: existingForm?.getAttribute("action") || "",
|
||||
clientId: document.querySelector("#ClientId")?.value || "",
|
||||
rememberLogin: document.querySelector("#RememberLogin")?.value || "False",
|
||||
returnUrl: document.querySelector("#ReturnUrl")?.value || "",
|
||||
isRecoveryCode:
|
||||
document.querySelector("#IsRecoveryCode")?.value || "False",
|
||||
requestToken:
|
||||
document.querySelector('input[name="__RequestVerificationToken"]')
|
||||
?.value || "",
|
||||
trustDeviceValue:
|
||||
document.querySelector('input[name="TrustDevice"][type="hidden"]')
|
||||
?.value || "false",
|
||||
};
|
||||
|
||||
|
||||
const newHTML = `
|
||||
<div class="login-container">
|
||||
<div class="login-card">
|
||||
<div class="card-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="twofactor-title">Kétfaktoros azonosítás</h1>
|
||||
<h1 class="twofactor-title">${LanguageManager.t("twofactor.title")}</h1>
|
||||
</div>
|
||||
|
||||
<form class="twofactor-form" action="${formData.action}" method="post" id="twoFactorForm">
|
||||
@@ -41,30 +46,30 @@ async function transformTwoFactorPage() {
|
||||
|
||||
<div class="form-group password-group">
|
||||
<input class="form-control" type="password" id="VerificationCode" name="VerificationCode"
|
||||
placeholder="Egyszeri jelszó" maxlength="256" autocomplete="off" required autofocus>
|
||||
<button type="button" class="show-password" aria-label="Jelszó mutatása">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-off.svg')}" alt="Show password" class="icon-eye">
|
||||
placeholder="${LanguageManager.t("twofactor.code_placeholder")}" maxlength="256" autocomplete="off" required autofocus>
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t("twofactor.show_code")}">
|
||||
<img src="${chrome.runtime.getURL("icons/eye-off.svg")}" alt="Show password" class="icon-eye">
|
||||
</button>
|
||||
<div class="error-message">Kérjük, add meg az egyszeri jelszót.</div>
|
||||
<div class="error-message">${LanguageManager.t("twofactor.code_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="trustDevice" name="TrustDevice" value="true">
|
||||
<label class="form-check-label" for="trustDevice">
|
||||
Eszköz megjelölése biztonságosként
|
||||
${LanguageManager.t("twofactor.trust_device")}
|
||||
</label>
|
||||
<input name="TrustDevice" type="hidden" value="false">
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mb-3 mt-4">
|
||||
<button type="submit" class="btn-kreta">Kód ellenőrzése</button>
|
||||
<button type="submit" class="btn-kreta">${LanguageManager.t("twofactor.verify_button")}</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mt-3">
|
||||
<span class="subtext">
|
||||
Nem fér hozzá eszközéhez? Lépjen be
|
||||
${LanguageManager.t("twofactor.no_access")}
|
||||
<button type="submit" class="btn-link" formaction="/account/loginwithrecoverycode">
|
||||
helyreállító kóddal.
|
||||
${LanguageManager.t("twofactor.recovery_code")}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
@@ -73,21 +78,25 @@ async function transformTwoFactorPage() {
|
||||
|
||||
<footer class="login-footer">
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">Adatkezelési tájékoztató</a>
|
||||
target="_blank" class="privacy-link">${LanguageManager.t("login.privacy_policy")}</a>
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
applyTheme();
|
||||
setupEventListeners();
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error transforming two-factor page:', error);
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}
|
||||
@@ -95,77 +104,83 @@ 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) {
|
||||
console.error('Error applying theme:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
const twoFactorForm = document.getElementById('twoFactorForm');
|
||||
const verificationInput = document.getElementById('VerificationCode');
|
||||
const togglePasswordBtn = document.querySelector('.show-password');
|
||||
const formInputs = document.querySelectorAll('.form-control');
|
||||
const twoFactorForm = document.getElementById("twoFactorForm");
|
||||
const verificationInput = document.getElementById("VerificationCode");
|
||||
const togglePasswordBtn = document.querySelector(".show-password");
|
||||
const formInputs = document.querySelectorAll(".form-control");
|
||||
|
||||
if (togglePasswordBtn && verificationInput) {
|
||||
togglePasswordBtn.addEventListener('click', () => {
|
||||
const isPassword = verificationInput.type === 'password';
|
||||
verificationInput.type = isPassword ? 'text' : 'password';
|
||||
const icon = togglePasswordBtn.querySelector('.icon-eye');
|
||||
icon.src = chrome.runtime.getURL(`icons/${isPassword ? 'eye-on' : 'eye-off'}.svg`);
|
||||
togglePasswordBtn.addEventListener("click", () => {
|
||||
const isPassword = verificationInput.type === "password";
|
||||
verificationInput.type = isPassword ? "text" : "password";
|
||||
const icon = togglePasswordBtn.querySelector(".icon-eye");
|
||||
icon.src = chrome.runtime.getURL(
|
||||
`icons/${isPassword ? "eye-on" : "eye-off"}.svg`,
|
||||
);
|
||||
});
|
||||
}
|
||||
formInputs.forEach(input => {
|
||||
input.addEventListener('input', () => {
|
||||
formInputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
if (twoFactorForm) {
|
||||
twoFactorForm.addEventListener('submit', handleSubmit);
|
||||
twoFactorForm.addEventListener("submit", handleSubmit);
|
||||
}
|
||||
}
|
||||
|
||||
function validateInput(input, showError = false) {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling?.nextElementSibling;
|
||||
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
inputs.forEach(input => {
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
if (isValid) {
|
||||
const submitButton = form.querySelector('.btn-kreta');
|
||||
const submitButton = form.querySelector(".btn-kreta");
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
submitButton.innerHTML = '<span class="spinner"></span><span class="btn-text">Ellenőrzés...</span>';
|
||||
submitButton.innerHTML = '';
|
||||
const spinnerSpan = document.createElement('span');
|
||||
spinnerSpan.className = 'spinner';
|
||||
const textSpan = document.createElement('span');
|
||||
textSpan.className = 'btn-text';
|
||||
textSpan.textContent = LanguageManager.t('twofactor.verifying');
|
||||
submitButton.appendChild(spinnerSpan);
|
||||
submitButton.appendChild(textSpan);
|
||||
}
|
||||
|
||||
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
transformTwoFactorPage();
|
||||
transformTwoFactorPage();
|
||||
|
||||
@@ -1,138 +1,117 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 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;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.logout-container {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:100%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.logout-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
text-align:center;
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color:var(--text-primary);
|
||||
font-size:24px;
|
||||
font-weight:600;
|
||||
margin:16px 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
width:24px;
|
||||
border-radius:8px;
|
||||
margin-right:8px;
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
border-radius:24px;
|
||||
text-align:center;
|
||||
margin-bottom:16px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-message {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.logout-message strong {
|
||||
font-size: 18px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
font-size:18px;
|
||||
color:var(--text-primary);
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.redirect-timer {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
color: var(--accent-accent);
|
||||
margin-bottom: 24px;
|
||||
font-size:48px;
|
||||
font-weight:700;
|
||||
color:var(--accent-accent);
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.btn-continue {
|
||||
display: inline-block;
|
||||
padding: 12px 24px;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
text-decoration: none;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
display:inline-block;
|
||||
padding:12px 24px;
|
||||
background:var(--accent-accent);
|
||||
color:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
transition:background 0.2s ease,color 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-continue:hover {
|
||||
background: var(--accent-secondary) !important;
|
||||
color: var(--button-secondaryFill) !important;
|
||||
background:var(--accent-secondary) !important;
|
||||
color:var(--button-secondaryFill) !important;
|
||||
}
|
||||
|
||||
.logout-footer {
|
||||
text-align: center;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
margin-bottom: 8px;
|
||||
transition: color 0.2s ease;
|
||||
color:var(--text-secondary);
|
||||
text-decoration:none;
|
||||
font-size:14px;
|
||||
display:inline-block;
|
||||
margin-bottom:8px;
|
||||
transition:color 0.2s ease;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--text-primary);
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width:600px) {
|
||||
.logout-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.redirect-timer {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
}
|
||||
padding:16px;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
.logout-card {
|
||||
padding:20px;
|
||||
}
|
||||
.redirect-timer {
|
||||
font-size:36px;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:20px;
|
||||
}
|
||||
.logo {
|
||||
width:20px;
|
||||
}
|
||||
}@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,17 @@
|
||||
(() => {
|
||||
function loadFonts() {
|
||||
// Create a new style element
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/icon?family=Material+Icons+Round');
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
function transformLogoutPage() {
|
||||
// Get current theme and school ID from cookies
|
||||
const theme = cookieManager.get('themePreference') || localStorage.getItem('themePreference') || 'light-green';
|
||||
const instituteCode = cookieManager.get('schoolSubdomain');
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
// Create new HTML structure
|
||||
async function transformLogoutPage() {
|
||||
const theme =
|
||||
await storageManager.get("themePreference", null) ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
const instituteCode = await storageManager.get("schoolSubdomain", null);
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
const newHTML = `
|
||||
<div class="logout-container">
|
||||
<header class="logout-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
</header>
|
||||
@@ -42,39 +34,49 @@
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Replace body content
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
// Start countdown timer
|
||||
const timerElement = document.getElementById('automaticRedirectTimer');
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
const timerElement = document.getElementById("automaticRedirectTimer");
|
||||
let remainingTime = 5;
|
||||
|
||||
|
||||
const countdownInterval = setInterval(() => {
|
||||
remainingTime--;
|
||||
if (timerElement) {
|
||||
timerElement.textContent = remainingTime;
|
||||
}
|
||||
|
||||
|
||||
if (remainingTime <= 0) {
|
||||
clearInterval(countdownInterval);
|
||||
window.location.href = `https://${instituteCode}.e-kreta.hu`;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Handle manual redirect click
|
||||
document.querySelector('.btn-continue')?.addEventListener('click', (e) => {
|
||||
|
||||
document.querySelector(".btn-continue")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
clearInterval(countdownInterval);
|
||||
window.location.href = `https://${instituteCode}.e-kreta.hu`;
|
||||
});
|
||||
}
|
||||
// Load fonts immediately
|
||||
loadFonts();
|
||||
// Run the transformation
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', transformLogoutPage);
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setTimeout(() => {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}, 100);
|
||||
transformLogoutPage();
|
||||
});
|
||||
} else {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
transformLogoutPage();
|
||||
}
|
||||
})();
|
||||
205
manifest.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.2.1",
|
||||
"version": "1.3.5",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -12,122 +12,219 @@
|
||||
"128": "images/firka_logo_128.png"
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [{
|
||||
"resources": [
|
||||
"settings/*",
|
||||
"images/*",
|
||||
"fonts/*.woff2",
|
||||
"icons/*.svg",
|
||||
"grades/chart.js"
|
||||
],
|
||||
"matches": ["https://*.e-kreta.hu/*", "https://idp.e-kreta.hu/*"]
|
||||
}],
|
||||
"permissions": [
|
||||
"storage"
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "tools/background.js"
|
||||
},
|
||||
"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://*.e-kreta.hu/*"
|
||||
"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"
|
||||
],
|
||||
"js": ["tools/cookieManager.js", "tools/helper.js", "tools/loadingScreen.js", "tools/createTemplate.js",
|
||||
"global/maintenance.js", "global/theme.js", "global/navigation.js"],
|
||||
"css": ["tools/loadingScreen.css", "global/theme.css", "global/navigation.css"],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/*"
|
||||
"https://idp.e-kreta.hu/Account/Login*"
|
||||
],
|
||||
"css": ["global/maintenance.css"],
|
||||
"run_at": "document_end"
|
||||
"js": [
|
||||
"login/login.js"
|
||||
],
|
||||
"css": [
|
||||
"login/login.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/Account/Login*"],
|
||||
"js": ["login/login.js"],
|
||||
"css": ["login/login.css"]
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/account/loginwithtwofactor*"],
|
||||
"js": ["login/twofactor.js"],
|
||||
"css": ["login/twofactor.css"]
|
||||
"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"],
|
||||
"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_end"
|
||||
"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_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"
|
||||
"js": [
|
||||
"roleselect/roleselect.js"
|
||||
],
|
||||
"js": ["forgotpassword/forgotpassword.js"],
|
||||
"css": ["forgotpassword/forgotpassword.css"],
|
||||
"run_at": "document_end"
|
||||
"css": [
|
||||
"roleselect/roleselect.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*"
|
||||
],
|
||||
"js": ["dashboard/dashboard.js"],
|
||||
"css": ["dashboard/dashboard.css"],
|
||||
"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"],
|
||||
"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"],
|
||||
"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"],
|
||||
"js": [
|
||||
"profile/profile.js"
|
||||
],
|
||||
"css": [
|
||||
"profile/profile.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*"
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"
|
||||
],
|
||||
"js": [
|
||||
"forgotpassword/forgotpassword.js"
|
||||
],
|
||||
"css": [
|
||||
"forgotpassword/forgotpassword.css"
|
||||
],
|
||||
"js": ["homework/homework.js"],
|
||||
"css": ["homework/homework.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://intezmenykereso.e-kreta.hu/"
|
||||
],
|
||||
"js": ["search/search.js"],
|
||||
"css": ["search/search.css"],
|
||||
"js": [
|
||||
"search/search.js"
|
||||
],
|
||||
"css": [
|
||||
"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();
|
||||
}
|
||||
})();
|
||||
@@ -1,366 +1,325 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@import url('../global/theme.css');
|
||||
|
||||
|
||||
.main-header,
|
||||
.main-menu,
|
||||
.main-sidebar,
|
||||
.content-header,
|
||||
.favoriteIconContainer,
|
||||
#frissitesDatumDiv,
|
||||
#layout_navigationBar,
|
||||
.navbar,
|
||||
.sidebar-container,
|
||||
#sidepanel_tabs,
|
||||
.sidepanel-wrapper {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
color: var(--text-primary) !important;
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
.page-wrapper {
|
||||
background-color: var(--background) !important;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.content-content {
|
||||
background-color: var(--background) !important;
|
||||
min-height: auto !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
|
||||
.kreta-header {
|
||||
.firka-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--background);
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.school-info {
|
||||
.back-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
color: var(--text-primary);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-decoration: none;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
.back-button:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.back-button svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--text-primary);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
|
||||
.k-content {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
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.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
padding: 1.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
|
||||
.profile-tabs {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.tab-headers {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--card-translucent);
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.tab-headers::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
padding: 0.75rem 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
border-bottom: 2px solid transparent;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tab-header.active {
|
||||
color: var(--accent-accent);
|
||||
border-bottom-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
background: var(--accent-15);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.form-text {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
|
||||
.security-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.step-card {
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
.step-card h3 {
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.step-card p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.app-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.app-section h4 {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.app-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.app-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 8px;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.app-link:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
.qr-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.qr-container img {
|
||||
background: white;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.setup-key {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.key-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
padding: 0.75rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.key-display code {
|
||||
font-family: monospace;
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
flex-grow: 1;
|
||||
.k-content h4 {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 28px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 0 0 2rem 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-copy {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.k-tabstrip-wrapper {
|
||||
background: var(--card-card) !important;
|
||||
border-radius: 24px !important;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.btn-copy:hover {
|
||||
color: var(--text-primary);
|
||||
background: var(--button-secondaryFill);
|
||||
.k-tabstrip {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
border-radius: 24px 24px 0 0 !important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
color: var(--text-secondary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
padding: 16px 20px !important;
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
border-radius: 0 !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item.k-state-active .k-link {
|
||||
color: var(--accent-accent) !important;
|
||||
font-weight: 600 !important;
|
||||
border-bottom: 2px solid var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item:hover .k-link {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
|
||||
.btn-save {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
.k-tabstrip .k-content {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
padding: 20px !important;
|
||||
border-radius: 0 0 24px 24px !important;
|
||||
}
|
||||
|
||||
.btn-save:hover {
|
||||
background: var(--accent-secondary);
|
||||
|
||||
form {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.container-fluid.details {
|
||||
background: transparent !important;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.windowInputLabel {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
select,
|
||||
textarea {
|
||||
background: var(--button-secondaryFill) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 16px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
box-shadow: 0 0 0 3px var(--accent-15) !important;
|
||||
}
|
||||
|
||||
.k-checkbox {
|
||||
appearance: none;
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
border: 2px solid var(--accent-15) !important;
|
||||
border-radius: 4px !important;
|
||||
background: var(--button-secondaryFill) !important;
|
||||
cursor: pointer !important;
|
||||
position: relative !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked {
|
||||
background: var(--accent-accent) !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.k-checkbox-label {
|
||||
margin-left: 8px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.k-button,
|
||||
button {
|
||||
background: var(--accent-accent) !important;
|
||||
border: none !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 24px !important;
|
||||
color: white !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 14px !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s ease !important;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow) !important;
|
||||
}
|
||||
|
||||
.k-button:hover,
|
||||
button:hover {
|
||||
background: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow) !important;
|
||||
}
|
||||
|
||||
.k-button:active,
|
||||
button:active {
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.content-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.firka-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.k-content h4 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
padding: 12px 16px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@@ -368,70 +327,159 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.k-tabstrip-wrapper {
|
||||
animation: fadeIn 0.5s ease forwards;
|
||||
}
|
||||
|
||||
|
||||
@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;
|
||||
}
|
||||
.k-widget,
|
||||
.k-header {
|
||||
background: var(--card-card) !important;
|
||||
color: var(--text-primary) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
}
|
||||
.k-state-default {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
|
||||
.app-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
.k-state-active {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
|
||||
.material-icons-round {
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
.k-overlay,
|
||||
.k-window,
|
||||
.k-notification {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
.main-content .content-content {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
align-items: center !important;
|
||||
margin-top: 2rem !important;
|
||||
padding-top: 2rem !important;
|
||||
border-top: 1px solid var(--accent-15) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] label {
|
||||
color: var(--text-secondary) !important;
|
||||
font-size: 12px !important;
|
||||
font-style: italic !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
.hidden-contact-info {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hidden-tab {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#ProfilTab-3 {
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .container-fluid {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 h4 {
|
||||
color: #2c3e50;
|
||||
font-weight: 600;
|
||||
margin-bottom: 25px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 3px solid #3498db;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #3498db;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row:hover {
|
||||
background: #e3f2fd;
|
||||
transform: translateX(5px);
|
||||
box-shadow: 0 2px 10px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .windowInputLabel {
|
||||
color: #34495e;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button {
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 10px 20px;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button:hover {
|
||||
background: linear-gradient(135deg, #2980b9, #1f5f8b);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input {
|
||||
border: 2px solid #e0e6ed;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input:focus {
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert {
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-info {
|
||||
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-success {
|
||||
background: linear-gradient(135deg, #e8f5e8, #c8e6c9);
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-warning {
|
||||
background: linear-gradient(135deg, #fff3e0, #ffcc02);
|
||||
color: #ef6c00;
|
||||
}
|
||||
|
||||
.details .row {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
@@ -1,396 +1,228 @@
|
||||
(() => {
|
||||
function createSecurityTab() {
|
||||
return `
|
||||
<div class="security-content">
|
||||
<div class="setup-steps">
|
||||
<div class="step-card">
|
||||
<h3>1. lépés: Hitelesítési alkalmazás telepítése</h3>
|
||||
<p>A kétfaktoros hitelesítés használatához telepítsen egy időalapú, egyszer használatos jelszó (TOTP) alkalmazást:</p>
|
||||
|
||||
<div class="app-grid">
|
||||
<div class="app-section">
|
||||
<h4>Android</h4>
|
||||
<div class="app-links">
|
||||
<a href="https://play.google.com/store/apps/details?id=hu.innobile.niszauth" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
NISZ Hitelesítő
|
||||
</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.azure.authenticator" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Microsoft Authenticator
|
||||
</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Google Authenticator
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-section">
|
||||
<h4>iPhone</h4>
|
||||
<div class="app-links">
|
||||
<a href="https://apps.apple.com/hu/app/nisz-hiteles%C3%ADt%C5%91/id1603444961" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
NISZ Hitelesítő
|
||||
</a>
|
||||
<a href="https://apps.apple.com/hu/app/microsoft-authenticator/id983156458" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Microsoft Authenticator
|
||||
</a>
|
||||
<a href="https://apps.apple.com/hu/app/google-authenticator/id388497605" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Google Authenticator
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<h3>2. lépés: Kétfaktoros azonosítás beállítása</h3>
|
||||
<div class="setup-form">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="enable2FA">Kétfaktoros azonosítás bekapcsolása</button>
|
||||
</div>
|
||||
|
||||
<div id="qrSetup" style="display: none;">
|
||||
<div class="qr-container">
|
||||
<img id="qrCode" alt="QR kód" style="display: none;">
|
||||
<div class="setup-key">
|
||||
<label class="form-label">Biztonsági kulcs:</label>
|
||||
<div class="key-display">
|
||||
<code id="secretKey"></code>
|
||||
<button type="button" class="btn-copy" id="copyKey">
|
||||
<span class="material-icons-round">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="verificationCode">Ellenőrző kód</label>
|
||||
<input type="text" class="form-control" id="verificationCode" maxlength="6" placeholder="123456">
|
||||
<small class="form-text">Adja meg a hitelesítő alkalmazásban megjelenő 6 számjegyű kódot.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="verify2FA">Ellenőrzés és aktiválás</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-card" id="backupCodes" style="display: none;">
|
||||
<h3>3. lépés: Biztonsági kódok mentése</h3>
|
||||
<p>Az alábbi biztonsági kódokat használhatja bejelentkezéshez, ha nem fér hozzá a hitelesítő alkalmazásához. Minden kód csak egyszer használható.</p>
|
||||
|
||||
<div class="backup-codes">
|
||||
<pre id="backupCodesList"></pre>
|
||||
<button type="button" class="btn-save" id="downloadCodes">
|
||||
<span class="material-icons-round">download</span>
|
||||
Kódok letöltése
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createContactTab() {
|
||||
return `
|
||||
<div class="contact-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="email">E-mail cím</label>
|
||||
<input type="email" class="form-control" id="email" required>
|
||||
<small class="form-text">Az e-mail cím megadása a jelszó emlékeztető miatt szükséges.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="phone">Telefonszám</label>
|
||||
<input type="tel" class="form-control" id="phone" placeholder="+36 xx xxx xxxx">
|
||||
<small class="form-text">A telefonszám megadása nem kötelező.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="saveContacts">Mentés</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createPasswordTab() {
|
||||
return `
|
||||
<div class="password-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="currentPassword">Jelenlegi jelszó</label>
|
||||
<input type="password" class="form-control" id="currentPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="newPassword">Új jelszó</label>
|
||||
<input type="password" class="form-control" id="newPassword" required minlength="8">
|
||||
<small class="form-text">A jelszónak legalább 8 karakter hosszúnak kell lennie.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="confirmPassword">Új jelszó megerősítése</label>
|
||||
<input type="password" class="form-control" id="confirmPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="savePassword">Jelszó módosítása</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createSettingsTab() {
|
||||
return `
|
||||
<div class="settings-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
<input type="checkbox" id="hideTips">
|
||||
Tippek elrejtése
|
||||
</label>
|
||||
<small class="form-text">A tippek megjelenítésének ki/be kapcsolása.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="saveSettings">Mentés</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function setupContactForm() {
|
||||
const form = document.querySelector('.contact-form');
|
||||
if (!form) return;
|
||||
|
||||
const emailInput = form.querySelector('#email');
|
||||
const phoneInput = form.querySelector('#phone');
|
||||
const saveButton = form.querySelector('#saveContacts');
|
||||
|
||||
|
||||
emailInput.value = cookieManager.get('userEmail') || '';
|
||||
phoneInput.value = cookieManager.get('userPhone') || '';
|
||||
|
||||
saveButton?.addEventListener('click', async () => {
|
||||
const email = emailInput.value.trim();
|
||||
const phone = phoneInput.value.trim();
|
||||
|
||||
if (!email) {
|
||||
alert('Az e-mail cím megadása kötelező!');
|
||||
return;
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function hideLoadingScreen() {
|
||||
const loadingElement = document.getElementById('KretaProgressBar');
|
||||
if (loadingElement) {
|
||||
loadingElement.style.display = 'none !important';
|
||||
loadingElement.style.visibility = 'hidden';
|
||||
loadingElement.style.opacity = '0';
|
||||
loadingElement.remove();
|
||||
|
||||
}
|
||||
|
||||
if (email && !isValidEmail(email)) {
|
||||
alert('Kérjük, adjon meg egy érvényes e-mail címet!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (phone && !isValidPhone(phone)) {
|
||||
alert('Kérjük, adjon meg egy érvényes telefonszámot!');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveElerhetosegek', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({ email, phone })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Elérhetőségek sikeresen mentve!');
|
||||
} else {
|
||||
throw new Error('Hiba történt a mentés során.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving contacts:', error);
|
||||
alert('Hiba történt a mentés során. Kérjük, próbálja újra később.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isValidEmail(email) {
|
||||
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
||||
}
|
||||
|
||||
function isValidPhone(phone) {
|
||||
return /^\+?[0-9\s-]{9,}$/.test(phone);
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
|
||||
document.querySelectorAll('.tab-header').forEach(header => {
|
||||
header.addEventListener('click', () => {
|
||||
document.querySelectorAll('.tab-header').forEach(h => h.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
||||
|
||||
header.classList.add('active');
|
||||
const targetId = header.dataset.tab;
|
||||
document.getElementById(`${targetId}-content`).classList.add('active');
|
||||
|
||||
|
||||
const loadingElements = document.querySelectorAll('[class*="loading"], [id*="loading"], [class*="Loading"], [id*="Loading"]');
|
||||
loadingElements.forEach(el => {
|
||||
el.style.display = 'none !important';
|
||||
el.style.visibility = 'hidden';
|
||||
el.style.opacity = '0';
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const userBtn = document.querySelector('.user-dropdown-btn');
|
||||
const userDropdown = document.querySelector('.user-dropdown');
|
||||
|
||||
userBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle('show');
|
||||
});
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
userDropdown?.classList.remove('show');
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('saveSettings')?.addEventListener('click', async () => {
|
||||
const hideTips = document.getElementById('hideTips').checked;
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveTippekBeallitasa', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({ hideTips })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Beállítások sikeresen mentve! A változtatások érvényesítéséhez jelentkezzen be újra.');
|
||||
} else {
|
||||
throw new Error('Hiba történt a mentés során.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving settings:', error);
|
||||
alert('Hiba történt a mentés során. Kérjük, próbálja újra később.');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('savePassword')?.addEventListener('click', async () => {
|
||||
const currentPassword = document.getElementById('currentPassword').value;
|
||||
const newPassword = document.getElementById('newPassword').value;
|
||||
const confirmPassword = document.getElementById('confirmPassword').value;
|
||||
|
||||
if (!currentPassword || !newPassword || !confirmPassword) {
|
||||
alert('Kérjük, töltse ki az összes mezőt!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
alert('Az új jelszavak nem egyeznek!');
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length < 8) {
|
||||
alert('Az új jelszónak legalább 8 karakter hosszúnak kell lennie!');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveJelszoModositas', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({
|
||||
currentPassword,
|
||||
newPassword,
|
||||
confirmPassword
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Jelszó sikeresen módosítva!');
|
||||
document.getElementById('currentPassword').value = '';
|
||||
document.getElementById('newPassword').value = '';
|
||||
document.getElementById('confirmPassword').value = '';
|
||||
} else {
|
||||
throw new Error('Hiba történt a jelszó módosítása során.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error changing password:', error);
|
||||
alert('Hiba történt a jelszó módosítása során. Kérjük, próbálja újra később.');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const timerEl = document.getElementById('logoutTimer');
|
||||
if (timerEl) {
|
||||
const startTime = parseInt(timerEl.textContent?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function createProfileHTML() {
|
||||
return `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="card">
|
||||
<h2>Profil beállítások</h2>
|
||||
<div class="profile-tabs">
|
||||
<div class="tab-headers">
|
||||
<button class="tab-header active" data-tab="settings">Beállítások</button>
|
||||
<button class="tab-header" data-tab="password">Jelszó módosítása</button>
|
||||
<button class="tab-header" data-tab="security">Biztonsági beállítások</button>
|
||||
<button class="tab-header" data-tab="contacts">Elérhetőségek</button>
|
||||
</div>
|
||||
|
||||
<div id="settings-content" class="tab-content active">
|
||||
${createSettingsTab()}
|
||||
</div>
|
||||
|
||||
<div id="password-content" class="tab-content">
|
||||
${createPasswordTab()}
|
||||
</div>
|
||||
|
||||
<div id="security-content" class="tab-content">
|
||||
${createSecurityTab()}
|
||||
</div>
|
||||
|
||||
<div id="contacts-content" class="tab-content">
|
||||
${createContactTab()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
async function init() {
|
||||
if (window.location.pathname.includes('/Adminisztracio/Profil')) {
|
||||
|
||||
|
||||
function addBackButton() {
|
||||
|
||||
if (document.getElementById('firka-back-button')) {
|
||||
return;
|
||||
}
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
document.body.innerHTML = createProfileHTML();
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
setupEventListeners();
|
||||
setupContactForm();
|
||||
}
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.id = 'firka-back-button';
|
||||
backButton.innerHTML = '← Vissza';
|
||||
backButton.style.cssText = `
|
||||
position: static;
|
||||
margin: 20px;
|
||||
z-index: 100;
|
||||
background-color: var(--card-background, #ffffff);
|
||||
color: var(--text-primary, #333333);
|
||||
border: 1px solid var(--border-color, #e0e0e0);
|
||||
border-radius: 8px;
|
||||
padding: 10px 16px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: auto;
|
||||
`;
|
||||
|
||||
|
||||
backButton.addEventListener('mouseenter', function() {
|
||||
this.style.backgroundColor = 'var(--card-hover, #f5f5f5)';
|
||||
this.style.transform = 'translateY(-1px)';
|
||||
this.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
|
||||
});
|
||||
|
||||
backButton.addEventListener('mouseleave', function() {
|
||||
this.style.backgroundColor = 'var(--card-background, #ffffff)';
|
||||
this.style.transform = 'translateY(0)';
|
||||
this.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
|
||||
});
|
||||
|
||||
|
||||
backButton.addEventListener('click', function() {
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
|
||||
document.body.insertBefore(backButton, document.body.firstChild);
|
||||
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
|
||||
function hideMainFooter2() {
|
||||
const footer2 = document.querySelector('.main-footer2');
|
||||
if (footer2) {
|
||||
footer2.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideLakatImg() {
|
||||
const lakatImg = document.querySelector('.lakatimg');
|
||||
if (lakatImg) {
|
||||
lakatImg.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideCustomUserSettingsTab() {
|
||||
|
||||
const firstTab = document.querySelector('#ProfilTab .k-tabstrip-items li[aria-controls="ProfilTab-1"]');
|
||||
if (firstTab) {
|
||||
firstTab.classList.add('hidden-tab');
|
||||
}
|
||||
|
||||
|
||||
const tabLinks = document.querySelectorAll('#ProfilTab .k-tabstrip-items .k-link');
|
||||
tabLinks.forEach(link => {
|
||||
if (link.textContent && link.textContent.includes('Egyedi felhasználó beállítások')) {
|
||||
const parentTab = link.closest('li');
|
||||
if (parentTab) {
|
||||
parentTab.classList.add('hidden-tab');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const contentPanel = document.querySelector('#ProfilTab-1');
|
||||
if (contentPanel) {
|
||||
contentPanel.classList.add('hidden-tab');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideAdditionalContactInfo() {
|
||||
|
||||
function hideElementsWithText(text) {
|
||||
const elements = document.querySelectorAll('h4');
|
||||
elements.forEach(h4 => {
|
||||
if (h4.textContent && h4.textContent.includes(text)) {
|
||||
// Hide the parent row
|
||||
let parent = h4.closest('.row');
|
||||
if (parent) {
|
||||
parent.classList.add('hidden-contact-info');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
hideElementsWithText('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK');
|
||||
hideElementsWithText('TOVÁBBI TELEFONSZÁMOK');
|
||||
|
||||
|
||||
const rows = document.querySelectorAll('.row');
|
||||
rows.forEach(row => {
|
||||
const h4Elements = row.querySelectorAll('h4');
|
||||
h4Elements.forEach(h4 => {
|
||||
if (h4.textContent &&
|
||||
(h4.textContent.includes('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK') ||
|
||||
h4.textContent.includes('TOVÁBBI TELEFONSZÁMOK'))) {
|
||||
row.classList.add('hidden-contact-info');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
hideLoadingScreen();
|
||||
addBackButton();
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('load', init);
|
||||
|
||||
|
||||
setTimeout(hideLoadingScreen, 1000);
|
||||
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 20;
|
||||
const aggressiveHide = setInterval(() => {
|
||||
attempts++;
|
||||
hideLoadingScreen();
|
||||
|
||||
if (attempts >= maxAttempts) {
|
||||
clearInterval(aggressiveHide);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType === 1) {
|
||||
if (node.id === 'KretaProgressBar' ||
|
||||
node.className && (node.className.includes('loading') || node.className.includes('Loading'))) {
|
||||
node.style.display = 'none !important';
|
||||
node.style.visibility = 'hidden';
|
||||
node.style.opacity = '0';
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,380 +1,323 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
|
||||
.kreta-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width:100%;
|
||||
min-height:100vh;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
max-width:1200px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
|
||||
.kreta-header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
margin-bottom: clamp(2rem, 5vw, 3rem);
|
||||
display:grid;
|
||||
grid-template-columns:auto 1fr auto;
|
||||
align-items:center;
|
||||
gap:2rem;
|
||||
margin-bottom:clamp(2rem,5vw,3rem);
|
||||
}
|
||||
|
||||
|
||||
.school-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.75rem;
|
||||
width:32px;
|
||||
height:32px;
|
||||
border-radius:8px;
|
||||
margin-right:0.75rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
padding-left: 2px;
|
||||
color:var(--text-secondary);
|
||||
font-size:1.1rem;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
max-width:300px;
|
||||
padding-left:2px;
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
justify-self: flex-end;
|
||||
text-align: right;
|
||||
justify-self:flex-end;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:flex-end;
|
||||
gap:4px;
|
||||
}
|
||||
|
||||
|
||||
.user-name, .role-text {
|
||||
color: var(--text-primary);
|
||||
font-family: Montserrat;
|
||||
font-weight: 600;
|
||||
.user-name,.role-text {
|
||||
color:var(--text-primary);
|
||||
font-family:Montserrat;
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 16px;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.role-text {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
font-size:20px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.logout-timer, .role-description {
|
||||
color: var(--text-secondary);
|
||||
font-family: Figtree;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
.logout-timer,.role-description {
|
||||
color:var(--text-secondary);
|
||||
font-family:Figtree;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.logout-timer {
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
font-size:14px;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.role-description {
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
font-size:16px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
.role-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.role-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr minmax(300px, 1fr);
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
display:grid;
|
||||
grid-template-columns:1fr minmax(300px,1fr);
|
||||
gap:1.5rem;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: 1.5rem;
|
||||
display:grid;
|
||||
grid-template-rows:1fr auto;
|
||||
gap:1.5rem;
|
||||
}
|
||||
|
||||
|
||||
.role-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.5rem;
|
||||
padding: 2rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 1rem;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
border: none;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition: all 0.2s ease;
|
||||
width:100%;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
gap:1.5rem;
|
||||
padding:2rem;
|
||||
background:var(--card-card);
|
||||
border-radius:1rem;
|
||||
cursor:pointer;
|
||||
text-align:center;
|
||||
border:none;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.role-card[data-role="Ellenorzo"] {
|
||||
height: 480px;
|
||||
background: var(--card-card);
|
||||
height:480px;
|
||||
background:var(--card-card);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"] {
|
||||
height: 280px;
|
||||
background: var(--card-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
height:280px;
|
||||
background:var(--card-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
height: 180px;
|
||||
background: var(--error-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
height:180px;
|
||||
background:var(--error-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
.role-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
background: var(--accent-15);
|
||||
width:48px;
|
||||
height:48px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
border-radius:12px;
|
||||
transition:transform 0.2s ease;
|
||||
background:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
transition: transform 0.2s ease;
|
||||
width:32px;
|
||||
height:32px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"] .role-icon {
|
||||
background: var(--warning-15);
|
||||
background:var(--warning-15);
|
||||
}
|
||||
|
||||
.logout-card .role-icon {
|
||||
background: var(--error-15);
|
||||
background:var(--error-15);
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
transition: transform 0.2s ease;
|
||||
width:32px;
|
||||
height:32px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.role-card:hover {
|
||||
transform: translateY(-2px);
|
||||
transform:translateY(-2px);
|
||||
}
|
||||
|
||||
.role-card:hover .role-icon img {
|
||||
transform: scale(1.2);
|
||||
transform:scale(1.2);
|
||||
}
|
||||
|
||||
.role-card:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transform:translateY(1px);
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
.role-card[data-role="Ellenorzo"]:hover {
|
||||
background-color: var(--accent-15);
|
||||
background-color:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"]:hover {
|
||||
background-color: var(--accent-15);
|
||||
background-color:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"]:active {
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-card:hover {
|
||||
background-color: var(--error-15);
|
||||
background-color:var(--error-15);
|
||||
}
|
||||
|
||||
.logout-card:active {
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--error-shadow);
|
||||
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 {
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
width:8px;
|
||||
height:8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
background:var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
background:var(--text-secondary);
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
background:var(--text-primary);
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@media (max-width:1200px) {
|
||||
.role-grid {
|
||||
grid-template-columns: 1fr 280px;
|
||||
}
|
||||
grid-template-columns:1fr 280px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
}@media (max-width:900px) {
|
||||
.role-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: none;
|
||||
}
|
||||
|
||||
.role-card[data-role="Ellenorzo"],
|
||||
.role-card[data-role="DKT"],
|
||||
.logout-card {
|
||||
height: 300px;
|
||||
}
|
||||
grid-template-columns:1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.side-roles {
|
||||
grid-template-columns:1fr 1fr;
|
||||
grid-template-rows:none;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:300px;
|
||||
}
|
||||
}@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
max-width: 200px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
grid-template-columns:1fr auto;
|
||||
gap:1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.school-info {
|
||||
max-width:60%;
|
||||
}
|
||||
.school-details {
|
||||
max-width:200px;
|
||||
font-size:1rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:1.2rem;
|
||||
}
|
||||
.logo {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
}@media (max-width:640px) {
|
||||
.kreta-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.role-card {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.role-text {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.role-description {
|
||||
font-size: 1rem;
|
||||
}
|
||||
padding:1rem;
|
||||
}
|
||||
.side-roles {
|
||||
grid-template-columns:1fr;
|
||||
gap:0.75rem;
|
||||
}
|
||||
.role-card {
|
||||
padding:1rem;
|
||||
gap:1rem;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:200px;
|
||||
}
|
||||
.role-icon {
|
||||
width:40px;
|
||||
height:40px;
|
||||
}
|
||||
.role-icon img {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
.role-text {
|
||||
font-size:1.5rem;
|
||||
}
|
||||
.role-description {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
(() => {
|
||||
const startLogoutTimer = () => {
|
||||
let timeLeft = 45 * 60;
|
||||
const timerElement = document.getElementById('logoutTimer');
|
||||
|
||||
const timerElement = document.getElementById("logoutTimer");
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
|
||||
|
||||
if (timerElement) {
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
timeLeft <= 0 ? window.location.href = '/Home/Logout' : timeLeft--;
|
||||
|
||||
timeLeft <= 0 ? (window.location.href = "/Home/Logout") : timeLeft--;
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
@@ -20,21 +20,24 @@
|
||||
|
||||
const handleRoleChange = async (role) => {
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/SzerepkorValaszto/ChangeRole', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ Role: role })
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
"/Adminisztracio/SzerepkorValaszto/ChangeRole",
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ Role: role }),
|
||||
},
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
if (data.Success) {
|
||||
window.location.assign(data.Url);
|
||||
} else {
|
||||
throw new Error('Role change failed');
|
||||
throw new Error("Role change failed");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error changing role:', error);
|
||||
alert('Hiba történt a szerepkör váltása közben.');
|
||||
console.error("Error changing role:", error);
|
||||
alert(LanguageManager.t("roleselect.role_change_error"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,11 +46,11 @@
|
||||
<header class="kreta-header">
|
||||
<div class="school-info">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details">
|
||||
<span>${schoolCode || ''} - ${fullSchoolName || 'Iskola'}</span>
|
||||
<span>${schoolCode || ""} - ${fullSchoolName || "Iskola"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-profile">
|
||||
@@ -63,11 +66,11 @@
|
||||
<div class="main-role">
|
||||
<div class="role-card" data-role="Ellenorzo">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/naplo.svg')}" alt="Napló ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/naplo.svg")}" alt="Napló ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
Ellenőrzőkönyv
|
||||
<div class="role-description">Jegyek, hiányzások, órarended és egyéb információk megtekintése.</div>
|
||||
${LanguageManager.t("roleselect.student_book")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.student_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,21 +78,21 @@
|
||||
<div class="side-roles">
|
||||
<div class="role-card" data-role="DKT">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/dkt.svg')}" alt="DKT ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/dkt.svg")}" alt="DKT ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
Digitális Kollaborációs Tér (DKT)
|
||||
<div class="role-description">Osztálytermi kommunikáció és feladatok.</div>
|
||||
${LanguageManager.t("roleselect.dkt_title")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.dkt_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="role-card logout-card">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/logout.svg')}" alt="Kijelentkezés ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/logout.svg")}" alt="Kijelentkezés ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
Kijelentkezés
|
||||
<div class="role-description">Kilépés a rendszerből</div>
|
||||
${LanguageManager.t("roleselect.logout_title")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.logout_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,65 +103,77 @@
|
||||
|
||||
const transformRoleSelectPage = async () => {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => window.addEventListener('load', resolve));
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) =>
|
||||
window.addEventListener("load", resolve),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const schoolNameEl = document.querySelector('.IntezmenyNev');
|
||||
const schoolName = schoolNameEl?.textContent.trim() || 'Iskola neve';
|
||||
const [schoolCode, fullSchoolName] = schoolName.split(' - ');
|
||||
const schoolNameEl = document.querySelector(".IntezmenyNev");
|
||||
const schoolName = schoolNameEl?.textContent.trim() || "Iskola neve";
|
||||
const [schoolCode, fullSchoolName] = schoolName.split(" - ");
|
||||
|
||||
|
||||
const schoolSubdomain = window.location.hostname.split('.')[0];
|
||||
const schoolSubdomain = window.location.hostname.split(".")[0];
|
||||
|
||||
const userNameEl = document.querySelector('.UserName');
|
||||
const userName = userNameEl?.textContent.trim() || 'Felhasználónév';
|
||||
const userNameEl = document.querySelector(".UserName");
|
||||
const userName =
|
||||
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();
|
||||
const doc = parser.parseFromString(createHTML(
|
||||
schoolCode,
|
||||
fullSchoolName,
|
||||
userName,
|
||||
), 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
|
||||
document.body.innerHTML = createHTML(schoolCode, fullSchoolName, userName);
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
const timerInterval = startLogoutTimer();
|
||||
|
||||
|
||||
document.querySelector('.role-card[data-role="Ellenorzo"]')?.addEventListener('click', () => {
|
||||
handleRoleChange('Ellenorzo');
|
||||
});
|
||||
document
|
||||
.querySelector('.role-card[data-role="Ellenorzo"]')
|
||||
?.addEventListener("click", () => {
|
||||
handleRoleChange("Ellenorzo");
|
||||
});
|
||||
|
||||
document.querySelector('.role-card[data-role="DKT"]')?.addEventListener('click', () => {
|
||||
window.location.href = '/Adminisztracio/BelepesKezelo/DKTTanuloOrGondviselo';
|
||||
});
|
||||
|
||||
document.querySelector('.logout-card')?.addEventListener('click', async () => {
|
||||
try {
|
||||
clearInterval(timerInterval);
|
||||
await fetch('/Home/LogOut', { method: 'POST' });
|
||||
} catch {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
} finally {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
}
|
||||
});
|
||||
document
|
||||
.querySelector('.role-card[data-role="DKT"]')
|
||||
?.addEventListener("click", () => {
|
||||
window.location.href =
|
||||
"/Adminisztracio/BelepesKezelo/DKTTanuloOrGondviselo";
|
||||
});
|
||||
|
||||
document
|
||||
.querySelector(".logout-card")
|
||||
?.addEventListener("click", async () => {
|
||||
try {
|
||||
clearInterval(timerInterval);
|
||||
await fetch("/Home/LogOut", { method: "POST" });
|
||||
} catch {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
} finally {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error transforming page:', error);
|
||||
console.error("Error transforming page:", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (window.location.href.includes('/Adminisztracio/BelepesKezelo')) {
|
||||
if (window.location.href.includes("/Adminisztracio/BelepesKezelo")) {
|
||||
transformRoleSelectPage();
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -1,247 +1,196 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
header,footer,.page-title,.card-kreta {
|
||||
display:none !important;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Hide original elements */
|
||||
header, footer, .page-title, .card-kreta {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 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", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
/* Firka search page styling */
|
||||
.firka-search-wrapper {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:0;
|
||||
margin:0 auto;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform:translate(-50%,-50%);
|
||||
}
|
||||
|
||||
/* Firka header styling */
|
||||
.firka-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
background: var(--card-card) !important;
|
||||
padding: 24px;
|
||||
border-radius: 24px 24px 0 0;
|
||||
width: 100%;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:0;
|
||||
background:var(--card-card) !important;
|
||||
padding:24px;
|
||||
border-radius:24px 24px 0 0;
|
||||
width:100%;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width:32px;
|
||||
height:32px;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
margin: 8px 0;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:24px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:normal;
|
||||
margin:8px 0;
|
||||
}
|
||||
|
||||
/* Form container styling */
|
||||
.firka-form-container {
|
||||
background: var(--card-card);
|
||||
padding: 0 24px 24px 24px;
|
||||
border-radius: 0 0 24px 24px;
|
||||
width: 100%;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:0 24px 24px 24px;
|
||||
border-radius:0 0 24px 24px;
|
||||
width:100%;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
/* Form styling */
|
||||
form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: var(--button-secondaryFill) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
color: var(--text-primary) !important;
|
||||
padding: 12px 16px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 400 !important;
|
||||
height: auto !important;
|
||||
transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||
background-color:var(--button-secondaryFill) !important;
|
||||
border:1px solid var(--accent-15) !important;
|
||||
border-radius:12px !important;
|
||||
color:var(--text-primary) !important;
|
||||
padding:12px 16px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:16px !important;
|
||||
font-weight:400 !important;
|
||||
height:auto !important;
|
||||
transition:border-color 0.2s ease-in-out,box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--accent-accent) !important;
|
||||
box-shadow: 0 0 0 2px var(--accent-15) !important;
|
||||
outline: none !important;
|
||||
border-color:var(--accent-accent) !important;
|
||||
box-shadow:0 0 0 2px var(--accent-15) !important;
|
||||
outline:none !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-teritary) !important;
|
||||
color:var(--text-teritary) !important;
|
||||
}
|
||||
|
||||
/* Autocomplete dropdown styling */
|
||||
.dropdown-menu {
|
||||
background-color: var(--card-card) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important;
|
||||
padding: 8px !important;
|
||||
max-height: 300px !important;
|
||||
overflow-y: auto !important;
|
||||
width: 100% !important;
|
||||
background-color:var(--card-card) !important;
|
||||
border:1px solid var(--accent-15) !important;
|
||||
border-radius:12px !important;
|
||||
box-shadow:0 4px 8px rgba(0,0,0,0.1) !important;
|
||||
padding:8px !important;
|
||||
max-height:300px !important;
|
||||
overflow-y:auto !important;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: var(--text-primary) !important;
|
||||
padding: 10px 16px !important;
|
||||
border-radius: 8px !important;
|
||||
margin-bottom: 4px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 14px !important;
|
||||
transition: background-color 0.2s ease-in-out !important;
|
||||
color:var(--text-primary) !important;
|
||||
padding:10px 16px !important;
|
||||
border-radius:8px !important;
|
||||
margin-bottom:4px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:14px !important;
|
||||
transition:background-color 0.2s ease-in-out !important;
|
||||
}
|
||||
|
||||
li.dropdown-item:hover, li.dropdown-item:focus {
|
||||
background-color: var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
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;
|
||||
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;
|
||||
color: white !important;
|
||||
background-color:var(--accent-accent) !important;
|
||||
color:white !important;
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
.btn-kreta {
|
||||
background-color: var(--accent-accent) !important;
|
||||
color: white !important;
|
||||
border: none !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 24px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
cursor: pointer !important;
|
||||
transition: background-color 0.2s ease-in-out, transform 0.1s ease-in-out !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
background-color:var(--accent-accent) !important;
|
||||
color:white !important;
|
||||
border:none !important;
|
||||
border-radius:12px !important;
|
||||
padding:12px 24px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:16px !important;
|
||||
font-weight:600 !important;
|
||||
cursor:pointer !important;
|
||||
transition:background-color 0.2s ease-in-out,transform 0.1s ease-in-out !important;
|
||||
display:inline-flex !important;
|
||||
align-items:center !important;
|
||||
justify-content:center !important;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
background-color: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
background-color:var(--accent-secondary) !important;
|
||||
transform:translateY(-1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:active {
|
||||
transform: translateY(1px) !important;
|
||||
transform:translateY(1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:disabled {
|
||||
background-color: var(--text-teritary) !important;
|
||||
cursor: not-allowed !important;
|
||||
transform: none !important;
|
||||
background-color:var(--text-teritary) !important;
|
||||
cursor:not-allowed !important;
|
||||
transform:none !important;
|
||||
}
|
||||
|
||||
/* Footer styling */
|
||||
.firka-footer {
|
||||
margin-top: 16px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-top:16px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
font-family: Montserrat;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease-in-out;
|
||||
color:var(--text-secondary);
|
||||
font-family:Montserrat;
|
||||
font-size:14px;
|
||||
text-decoration:none;
|
||||
transition:color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--accent-accent);
|
||||
text-decoration: underline;
|
||||
color:var(--accent-accent);
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
@media (max-width:576px) {
|
||||
.firka-search-wrapper {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.btn-kreta {
|
||||
padding: 10px 20px !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
width:95%;
|
||||
}
|
||||
.search-title {
|
||||
font-size:20px;
|
||||
}
|
||||
.btn-kreta {
|
||||
padding:10px 20px !important;
|
||||
font-size:14px !important;
|
||||
}
|
||||
}
|
||||
122
search/search.js
@@ -1,7 +1,7 @@
|
||||
function initializeTransformation() {
|
||||
const form = document.querySelector('form');
|
||||
const autocomplete = document.querySelector('.autocomplete');
|
||||
|
||||
const form = document.querySelector("form");
|
||||
const autocomplete = document.querySelector(".autocomplete");
|
||||
|
||||
if (form && autocomplete) {
|
||||
applyFirkaStyling();
|
||||
} else {
|
||||
@@ -9,46 +9,67 @@ function initializeTransformation() {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
});
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
if (
|
||||
document.readyState === "complete" ||
|
||||
document.readyState === "interactive"
|
||||
) {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
}
|
||||
|
||||
function applyFirkaStyling() {
|
||||
async function applyFirkaStyling() {
|
||||
try {
|
||||
const theme = cookieManager.get('themePreference') || localStorage.getItem('themePreference') || 'light-green';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
const theme =
|
||||
await storageManager.get("themePreference") ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
const originalForm = document.querySelector('form');
|
||||
const instituteInput = document.querySelector('.autocomplete');
|
||||
const redirectButton = document.getElementById('redirectToInstitute');
|
||||
const instituteCodeInput = document.querySelector('.autocomplete-value');
|
||||
const requestToken = document.querySelector('input[name="__RequestVerificationToken"]');
|
||||
const searchWrapper = document.createElement('div');
|
||||
searchWrapper.className = 'firka-search-wrapper';
|
||||
const firkaHeader = document.createElement('div');
|
||||
firkaHeader.className = 'firka-header';
|
||||
firkaHeader.innerHTML = `
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="search-title">Válassz iskolát</h1>
|
||||
`;
|
||||
const formContainer = document.createElement('div');
|
||||
formContainer.className = 'firka-form-container';
|
||||
const firkaFooter = document.createElement('div');
|
||||
firkaFooter.className = 'firka-footer';
|
||||
firkaFooter.innerHTML = `
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">Adatkezelési tájékoztató</a>
|
||||
`;
|
||||
const existingWrapper = document.querySelector('.firka-search-wrapper');
|
||||
const originalForm = document.querySelector("form");
|
||||
const instituteInput = document.querySelector(".autocomplete");
|
||||
const redirectButton = document.getElementById("redirectToInstitute");
|
||||
const instituteCodeInput = document.querySelector(".autocomplete-value");
|
||||
const requestToken = document.querySelector(
|
||||
'input[name="__RequestVerificationToken"]',
|
||||
);
|
||||
const searchWrapper = document.createElement("div");
|
||||
searchWrapper.className = "firka-search-wrapper";
|
||||
const firkaHeader = document.createElement("div");
|
||||
firkaHeader.className = "firka-header";
|
||||
const logoText = document.createElement('p');
|
||||
logoText.className = 'logo-text';
|
||||
|
||||
const logoImg = document.createElement('img');
|
||||
logoImg.src = chrome.runtime.getURL('images/firka_logo.png');
|
||||
logoImg.alt = 'Firka';
|
||||
logoImg.className = 'logo';
|
||||
|
||||
logoText.appendChild(logoImg);
|
||||
logoText.appendChild(document.createTextNode('Firka'));
|
||||
|
||||
const searchTitle = document.createElement('h1');
|
||||
searchTitle.className = 'search-title';
|
||||
searchTitle.textContent = 'Válassz iskolát';
|
||||
|
||||
firkaHeader.appendChild(logoText);
|
||||
firkaHeader.appendChild(searchTitle);
|
||||
const formContainer = document.createElement("div");
|
||||
formContainer.className = "firka-form-container";
|
||||
const firkaFooter = document.createElement("div");
|
||||
firkaFooter.className = "firka-footer";
|
||||
const privacyLink = document.createElement('a');
|
||||
privacyLink.href = 'https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926';
|
||||
privacyLink.target = '_blank';
|
||||
privacyLink.className = 'privacy-link';
|
||||
privacyLink.textContent = 'Adatkezelési tájékoztató';
|
||||
|
||||
firkaFooter.appendChild(privacyLink);
|
||||
const existingWrapper = document.querySelector(".firka-search-wrapper");
|
||||
if (existingWrapper) {
|
||||
existingWrapper.remove();
|
||||
}
|
||||
@@ -61,33 +82,32 @@ function applyFirkaStyling() {
|
||||
document.body.appendChild(searchWrapper);
|
||||
setupAutocompleteListeners();
|
||||
if (redirectButton) {
|
||||
redirectButton.addEventListener('click', function(event) {
|
||||
redirectButton.addEventListener("click", function (event) {
|
||||
if (!instituteCodeInput.value) {
|
||||
event.preventDefault();
|
||||
alert('Kérjük, válasszon egy intézményt a folytatáshoz!');
|
||||
alert(LanguageManager.t("search.select_institution"));
|
||||
}
|
||||
});
|
||||
}
|
||||
observeAutocompleteValue(instituteCodeInput, redirectButton);
|
||||
} catch (error) {
|
||||
console.error('Error applying Firka styling:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupAutocompleteListeners() {
|
||||
const autocompleteInput = document.querySelector('.autocomplete');
|
||||
const autocompleteValue = document.querySelector('.autocomplete-value');
|
||||
const redirectButton = document.getElementById('redirectToInstitute');
|
||||
|
||||
const autocompleteInput = document.querySelector(".autocomplete");
|
||||
const autocompleteValue = document.querySelector(".autocomplete-value");
|
||||
const redirectButton = document.getElementById("redirectToInstitute");
|
||||
|
||||
if (autocompleteInput && autocompleteValue) {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const dropdown = document.querySelector('.autocomplete-dropdown');
|
||||
const dropdown = document.querySelector(".autocomplete-dropdown");
|
||||
if (dropdown) {
|
||||
dropdown.classList.add('dropdown-menu');
|
||||
const items = dropdown.querySelectorAll('li');
|
||||
items.forEach(item => {
|
||||
item.classList.add('dropdown-item');
|
||||
item.addEventListener('click', () => {
|
||||
dropdown.classList.add("dropdown-menu");
|
||||
const items = dropdown.querySelectorAll("li");
|
||||
items.forEach((item) => {
|
||||
item.classList.add("dropdown-item");
|
||||
item.addEventListener("click", () => {
|
||||
if (redirectButton) {
|
||||
redirectButton.disabled = false;
|
||||
}
|
||||
@@ -95,10 +115,10 @@ function setupAutocompleteListeners() {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -112,7 +132,7 @@ function observeAutocompleteValue(valueInput, button) {
|
||||
|
||||
observer.observe(valueInput, {
|
||||
attributes: true,
|
||||
attributeFilter: ['value']
|
||||
attributeFilter: ["value"],
|
||||
});
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
@@ -121,4 +141,4 @@ function observeAutocompleteValue(valueInput, button) {
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,276 +1,606 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 400px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif;
|
||||
font-size: 14px;
|
||||
width:400px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width:none;
|
||||
-ms-overflow-style:none;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
display: none;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.popup-container {
|
||||
padding: 16px;
|
||||
padding:16px;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
text-align:center;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
.logo-text {
|
||||
color:var(--text-primary);
|
||||
font-size:20px;
|
||||
font-weight:600;
|
||||
margin:8px 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
.logo {
|
||||
width:20px;
|
||||
border-radius:6px;
|
||||
margin-right:8px;
|
||||
}
|
||||
.settings-card,.about-card,.support-card {
|
||||
background:var(--card-card);
|
||||
border-radius:16px;
|
||||
padding:16px;
|
||||
margin-bottom:16px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
h2 {
|
||||
font-size:16px;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
margin-bottom:12px;
|
||||
background-color:var(--card-card);
|
||||
}
|
||||
.settings-group {
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:16px;
|
||||
}
|
||||
.setting-section {
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:12px;
|
||||
}
|
||||
.setting-header {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
font-weight:600;
|
||||
font-size:16px;
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 8px 0;
|
||||
.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;
|
||||
grid-template-columns:repeat(2,1fr);
|
||||
gap:12px;
|
||||
}
|
||||
.theme-option,.language-option {
|
||||
background:none;
|
||||
border:none;
|
||||
padding:0;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
.theme-option:hover,.language-option:hover {
|
||||
transform:translateY(-2px);
|
||||
}
|
||||
.theme-option.active .theme-preview {
|
||||
outline:2px solid var(--accent-accent);
|
||||
outline-offset:2px;
|
||||
}
|
||||
.language-option.active .language-preview {
|
||||
outline:2px solid var(--accent-accent);
|
||||
outline-offset:2px;
|
||||
}
|
||||
.theme-preview {
|
||||
width:100%;
|
||||
height:100px;
|
||||
border-radius:8px;
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
}
|
||||
.theme-option.disabled {
|
||||
opacity:0.5;
|
||||
cursor:not-allowed;
|
||||
position:relative;
|
||||
}
|
||||
.theme-option.disabled::after {
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color:rgba(0,0,0,0.1);
|
||||
border-radius:8px;
|
||||
}
|
||||
.language-option {
|
||||
background:var(--card-card);
|
||||
border:1px solid var(--border-border);
|
||||
border-radius:8px;
|
||||
padding:12px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
.language-option:hover {
|
||||
background:var(--card-hover);
|
||||
border-color:var(--accent-accent);
|
||||
}
|
||||
.language-option.active {
|
||||
background:var(--accent-accent);
|
||||
border-color:var(--accent-accent);
|
||||
color:white;
|
||||
}
|
||||
.language-name {
|
||||
color:var(--text-primary);
|
||||
font-size:12px;
|
||||
font-weight:500;
|
||||
font-family: "Montserrat", serif;
|
||||
}
|
||||
|
||||
.theme-preview.light-green {
|
||||
background:#FAFFF0;
|
||||
}
|
||||
.theme-preview.light-green .preview-header {
|
||||
background:#F3FBDE;
|
||||
}
|
||||
.theme-preview.light-green .preview-card {
|
||||
background:#FEFFFD;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green {
|
||||
background:#0D1202;
|
||||
}
|
||||
.theme-preview.dark-green .preview-header {
|
||||
background:#141905;
|
||||
}
|
||||
.theme-preview.dark-green .preview-card {
|
||||
background:#20290b;
|
||||
}
|
||||
.preview-header {
|
||||
height:30%;
|
||||
width:100%;
|
||||
}
|
||||
.preview-content {
|
||||
padding:8px;
|
||||
}
|
||||
.preview-card {
|
||||
height:30px;
|
||||
border-radius:4px;
|
||||
}
|
||||
.theme-name {
|
||||
color:var(--text-primary);
|
||||
font-size:12px;
|
||||
font-weight:500;
|
||||
}
|
||||
.about-content,.support-content {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
line-height:1.5;
|
||||
}
|
||||
.about-content p,.support-content p {
|
||||
margin-bottom:12px;
|
||||
}
|
||||
.about-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.about-link {
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
color:var(--accent-accent);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
transition:color 0.2s;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.about-link:hover {
|
||||
color:var(--accent-secondary);
|
||||
}
|
||||
.support-buttons {
|
||||
display:flex;
|
||||
gap:8px;
|
||||
margin-top:12px;
|
||||
}
|
||||
.support-button {
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
gap:6px;
|
||||
padding:8px;
|
||||
background:var(--accent-15);
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
border-radius:8px;
|
||||
font-weight:500;
|
||||
transition:all 0.2s;
|
||||
}
|
||||
.support-button:hover {
|
||||
background:var(--accent-accent);
|
||||
color:var(--button-secondaryFill);
|
||||
}
|
||||
.popup-footer {
|
||||
text-align:center;
|
||||
margin-top:16px;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
border-radius: 6px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.settings-card,
|
||||
.about-card,
|
||||
.support-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.setting-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.setting-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.theme-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.theme-option {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.theme-option:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.theme-option.active .theme-preview {
|
||||
outline: 2px solid var(--accent-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.theme-preview {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
.theme-option.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.theme-option.disabled::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
.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-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.theme-preview.light-green .preview-header {
|
||||
background: #F3FBDE;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green .preview-header {
|
||||
background: #141905;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green .preview-card {
|
||||
background: #20290b;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
height: 30%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.preview-card {
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.theme-name {
|
||||
color: var(--text-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.about-content,
|
||||
.support-content {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.about-content p,
|
||||
.support-content p {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.github-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--accent-accent);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.github-link:hover {
|
||||
color: var(--accent-secondary);
|
||||
}
|
||||
|
||||
.support-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.support-button {
|
||||
flex: 1;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px;
|
||||
background: var(--accent-15);
|
||||
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);
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.support-button:hover {
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.version-info {
|
||||
.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;
|
||||
vertical-align: middle;
|
||||
}
|
||||
font-size:18px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
@@ -17,29 +17,20 @@
|
||||
<div class="popup-container">
|
||||
<header class="popup-header">
|
||||
<p class="logo-text">
|
||||
<img src="https://i.imgur.com/WugwlzI.png" alt="Firka" class="logo">
|
||||
<img src="../images/firka_logo.png" alt="Firka" class="logo">
|
||||
Firxa
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<div class="settings-card">
|
||||
<h2>Beállítások</h2>
|
||||
<h2 data-i18n="settings.title">Beállítások</h2>
|
||||
<div class="settings-group">
|
||||
<div class="setting-section">
|
||||
<div class="setting-header">
|
||||
<span class="material-icons-round">palette</span>
|
||||
Téma
|
||||
<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">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>
|
||||
@@ -47,17 +38,9 @@
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">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">Sötét Kék</span>
|
||||
<span class="theme-name" data-i18n="settings.themes.light_green">Világos Zöld</span>
|
||||
</button>
|
||||
|
||||
<button class="theme-option" data-theme="dark-green">
|
||||
<div class="theme-preview dark-green">
|
||||
<div class="preview-header"></div>
|
||||
@@ -65,7 +48,143 @@
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">Sötét Zöld</span>
|
||||
<span class="theme-name" data-i18n="settings.themes.dark_green">Sötét Zöld</span>
|
||||
</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>
|
||||
<span data-i18n="settings.language">Nyelv</span>
|
||||
</div>
|
||||
<div class="language-grid">
|
||||
<button class="language-option" data-language="hu">
|
||||
<span class="language-name" data-i18n="settings.languages.hu">Magyar</span>
|
||||
</button>
|
||||
<button class="language-option" data-language="en">
|
||||
<span class="language-name" data-i18n="settings.languages.en">English</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,33 +192,45 @@
|
||||
</div>
|
||||
|
||||
<div class="about-card">
|
||||
<h2>Névjegy</h2>
|
||||
<h2 data-i18n="settings.about.title">Névjegy</h2>
|
||||
<div class="about-content">
|
||||
<p>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>
|
||||
GitHub
|
||||
</a>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<div class="support-card">
|
||||
<h2>Támogatás</h2>
|
||||
<h2 data-i18n="settings.support.title">Támogatás</h2>
|
||||
<div class="support-content">
|
||||
<p>Ha tetszik a munkánk és szeretnéd támogatni a fejlesztést, az alábbi módon teheted meg:</p>
|
||||
<p data-i18n="settings.support.description">Ha tetszik a munkánk és szeretnéd támogatni a fejlesztést, az alábbi módon teheted meg:</p>
|
||||
<div class="support-buttons">
|
||||
<a href="https://ko-fi.com/zan1456" target="_blank" class="support-button">
|
||||
<span class="material-icons-round">coffee</span>
|
||||
Ko-Fi
|
||||
<span data-i18n="settings.support.kofi">Ko-Fi</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</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="index.js"></script>
|
||||
<script src="../tools/storageManager.js"></script>
|
||||
<script src="../global/language.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,187 +1,570 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
|
||||
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;
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
while (typeof window.LanguageManager === "undefined") {
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
|
||||
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';
|
||||
return (
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function updateThemeButtons(currentTheme) {
|
||||
document.querySelectorAll('.theme-option').forEach(button => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle('active', theme === currentTheme);
|
||||
});
|
||||
updateThemeAvailability();
|
||||
document.querySelectorAll(".theme-option").forEach((button) => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle("active", theme === currentTheme);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
function getCurrentLanguage() {
|
||||
return (
|
||||
localStorage.getItem("languagePreference") ||
|
||||
"hu"
|
||||
);
|
||||
}
|
||||
|
||||
function updateLanguageButtons(currentLanguage) {
|
||||
document.querySelectorAll(".language-option").forEach((button) => {
|
||||
const language = button.dataset.language;
|
||||
button.classList.toggle("active", language === currentLanguage);
|
||||
});
|
||||
}
|
||||
|
||||
async function applyLanguage(language) {
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
updateLanguageButtons(language);
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach((tab) => {
|
||||
chrome.tabs
|
||||
.sendMessage(tab.id, {
|
||||
action: "changeLanguage",
|
||||
language: language,
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
async function applyTheme(theme) {
|
||||
setCookie('themePreference', theme);
|
||||
localStorage.setItem('themePreference', theme);
|
||||
|
||||
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
|
||||
updateThemeButtons(theme);
|
||||
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach(tab => {
|
||||
chrome.tabs.sendMessage(tab.id, {
|
||||
action: 'changeTheme',
|
||||
theme: theme
|
||||
}).catch(() => {
|
||||
|
||||
console.log('Tab not ready for theme change:', tab.id);
|
||||
});
|
||||
});
|
||||
localStorage.setItem("themePreference", theme);
|
||||
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
updateThemeButtons(theme);
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach((tab) => {
|
||||
chrome.tabs
|
||||
.sendMessage(tab.id, {
|
||||
action: "changeTheme",
|
||||
theme: theme,
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const themeButtons = document.querySelectorAll('.theme-option');
|
||||
themeButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const theme = button.dataset.theme;
|
||||
|
||||
|
||||
if (button.hasAttribute('disabled')) {
|
||||
alert('Ez a téma jelenleg nem elérhető.');
|
||||
return;
|
||||
}
|
||||
|
||||
applyTheme(theme);
|
||||
});
|
||||
|
||||
const themeButtons = document.querySelectorAll(".theme-option");
|
||||
themeButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const theme = button.dataset.theme;
|
||||
|
||||
if (button.hasAttribute("disabled")) {
|
||||
alert(
|
||||
window.LanguageManager.t("common.warning") +
|
||||
": " +
|
||||
window.LanguageManager.t("settings.theme_not_available"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
applyTheme(theme);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
const languageButtons = document.querySelectorAll(".language-option");
|
||||
languageButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const language = button.dataset.language;
|
||||
applyLanguage(language);
|
||||
});
|
||||
});
|
||||
|
||||
let initialTheme = getCurrentTheme();
|
||||
|
||||
|
||||
if (isThemeDisabled(initialTheme)) {
|
||||
initialTheme = 'light-green';
|
||||
}
|
||||
|
||||
|
||||
updateThemeAvailability();
|
||||
|
||||
await applyTheme(initialTheme);
|
||||
|
||||
|
||||
|
||||
const initialLanguage = getCurrentLanguage();
|
||||
updateLanguageButtons(initialLanguage);
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'themeChanged') {
|
||||
updateThemeButtons(message.theme);
|
||||
document.documentElement.setAttribute('data-theme', message.theme);
|
||||
}
|
||||
if (message.action === "themeChanged") {
|
||||
updateThemeButtons(message.theme);
|
||||
document.documentElement.setAttribute("data-theme", message.theme);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const versionElement = document.getElementById('version');
|
||||
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 = 'Kék témák feloldva! 🎉';
|
||||
|
||||
|
||||
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")) {
|
||||
button.style.transform = "translateY(-2px)";
|
||||
}
|
||||
});
|
||||
|
||||
button.addEventListener("mouseout", () => {
|
||||
button.style.transform = "translateY(0)";
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
themeButtons.forEach(button => {
|
||||
button.addEventListener('mouseover', () => {
|
||||
if (!button.hasAttribute('disabled')) {
|
||||
button.style.transform = 'translateY(-2px)';
|
||||
}
|
||||
});
|
||||
|
||||
languageButtons.forEach((button) => {
|
||||
button.addEventListener("mouseover", () => {
|
||||
button.style.transform = "translateY(-2px)";
|
||||
});
|
||||
|
||||
button.addEventListener("mouseout", () => {
|
||||
button.style.transform = "translateY(0)";
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
button.addEventListener('mouseout', () => {
|
||||
button.style.transform = 'translateY(0)';
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
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,26 +1,27 @@
|
||||
const createTemplate = {
|
||||
header() {
|
||||
const data = {
|
||||
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',
|
||||
email: cookieManager.get('userEmail') || ''
|
||||
}
|
||||
};
|
||||
async header() {
|
||||
const data = {
|
||||
schoolInfo: {
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = helper.shortenSchoolName(schoolNameFull);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
const element = `<header class="kreta-header">
|
||||
const element = `<header class="kreta-header">
|
||||
<div class="school-info">
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
<img src="${chrome.runtime.getURL("images/firka_logo.png")}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
@@ -28,7 +29,7 @@ const createTemplate = {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="nav-toggle" aria-label="Navigáció megnyitása">
|
||||
<button class="nav-toggle" aria-label="${LanguageManager.t("navigation.nav_toggle")}">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
|
||||
</svg>
|
||||
@@ -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' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/dashboard-' + ( location.pathname == '/Intezmeny/Faliujsag' ? 'active' : 'inactive') + '.svg')}" alt="Kezdőlap">
|
||||
Kezdőlap
|
||||
<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' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/grades-' + ( location.pathname == '/TanuloErtekeles/Osztalyzatok' ? 'active' : 'inactive') + '.svg')}" alt="Jegyek">
|
||||
Jegyek
|
||||
<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' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/timetable-' + ( location.pathname == '/Orarend/InformaciokOrarend' ? 'active' : 'inactive') + '.svg')}" alt="Órarend">
|
||||
Órarend
|
||||
<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' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/absences-' + ( location.pathname == '/Hianyzas/Hianyzasok' ? 'active' : 'inactive') + '.svg')}" alt="Mulasztások">
|
||||
Mulasztások
|
||||
<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="Egyéb">
|
||||
Egyéb
|
||||
<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,69 +68,52 @@ const createTemplate = {
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="/Adminisztracio/Profil" data-page="profile" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL('icons/profile.svg')}" alt="Profil">
|
||||
Profil
|
||||
<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>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<img src="${chrome.runtime.getURL('icons/settings.svg')}" alt="Beállítások">
|
||||
Beállítások
|
||||
<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">
|
||||
<img src="${chrome.runtime.getURL('icons/logout.svg')}" alt="Kijelentkezés">
|
||||
Kijelentkezés
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</header>`
|
||||
</header>`;
|
||||
|
||||
const startTime = parseInt(data.userData.time?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
const timerEl = document.getElementById('logoutTimer');
|
||||
if (timerEl) {
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
const startTime = parseInt(data.userData.time?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
setInterval(updateTimer, 1000);
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
const timerEl = document.getElementById("logoutTimer");
|
||||
if (timerEl) {
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = "/Home/Logout";
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
|
||||
importFonts() {
|
||||
const links = [
|
||||
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
|
||||
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
|
||||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap' },
|
||||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons+Round' }
|
||||
];
|
||||
|
||||
links.forEach(link => {
|
||||
const linkElement = document.createElement('link');
|
||||
Object.entries(link).forEach(([key, value]) => {
|
||||
linkElement[key] = value;
|
||||
});
|
||||
document.head.appendChild(linkElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
setInterval(updateTimer, 1000);
|
||||
|
||||
return element;
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await helper.waitForElement('#settingsBtn');
|
||||
document.querySelector('#settingsBtn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
});
|
||||
await helper.waitForElement("#settingsBtn");
|
||||
document.querySelector("#settingsBtn").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL("settings/index.html");
|
||||
window.open(url, "_blank", "width=400,height=600");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
const helper = {
|
||||
shortenSchoolName(name, maxLength = 50) {
|
||||
if (!name) return '';
|
||||
if (name.length <= maxLength) return name;
|
||||
|
||||
const parts = name.split(' - ');
|
||||
if (parts.length === 2) {
|
||||
const [code, fullName] = parts;
|
||||
if (fullName.length > maxLength - code.length - 3) {
|
||||
return `${code} - ${fullName.substring(0, maxLength - code.length - 6)}...`;
|
||||
}
|
||||
}
|
||||
return name.substring(0, maxLength - 3) + '...';
|
||||
},
|
||||
|
||||
async waitForElement(selector) {
|
||||
return new Promise(resolve => {
|
||||
if (document.querySelector(selector)) {
|
||||
return resolve(document.querySelector(selector));
|
||||
}
|
||||
shortenSchoolName(name, maxLength = 50) {
|
||||
if (!name) return "";
|
||||
if (name.length <= maxLength) return name;
|
||||
|
||||
const observer = new MutationObserver(mutations => {
|
||||
if (document.querySelector(selector)) {
|
||||
observer.disconnect();
|
||||
resolve(document.querySelector(selector));
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
convertTimeToMinutes(timeStr) {
|
||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||||
return hours * 60 + minutes;
|
||||
const parts = name.split(" - ");
|
||||
if (parts.length === 2) {
|
||||
const [code, fullName] = parts;
|
||||
if (fullName.length > maxLength - code.length - 3) {
|
||||
return `${code} - ${fullName.substring(0, maxLength - code.length - 6)}...`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name.substring(0, maxLength - 3) + "...";
|
||||
},
|
||||
|
||||
async waitForElement(selector) {
|
||||
return new Promise((resolve) => {
|
||||
if (document.querySelector(selector)) {
|
||||
return resolve(document.querySelector(selector));
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
if (document.querySelector(selector)) {
|
||||
observer.disconnect();
|
||||
resolve(document.querySelector(selector));
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
convertTimeToMinutes(timeStr) {
|
||||
const [hours, minutes] = timeStr.split(":").map(Number);
|
||||
return hours * 60 + minutes;
|
||||
},
|
||||
};
|
||||
@@ -1,59 +1,53 @@
|
||||
.modalBckgroundMain {
|
||||
display: none !important;
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
body:not(.loaded) {
|
||||
opacity: 0 !important;
|
||||
visibility: hidden !important;
|
||||
height: 100vh !important;
|
||||
overflow: hidden !important;
|
||||
opacity:0 !important;
|
||||
visibility:hidden !important;
|
||||
height:100vh !important;
|
||||
overflow:hidden !important;
|
||||
}
|
||||
|
||||
.loading-screen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: var(--background);
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 0.3s ease;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100vw;
|
||||
height:100vh;
|
||||
background-color:var(--background);
|
||||
z-index:9999;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
transition:opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:16px;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.loading-text2 {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
@@ -1,47 +1,77 @@
|
||||
const loadingScreen = {
|
||||
show() {
|
||||
document.body.classList.remove('loaded');
|
||||
const existingLoadingScreen = document.querySelector('.loading-screen');
|
||||
if (existingLoadingScreen) return;
|
||||
show() {
|
||||
document.body.classList.remove("loaded");
|
||||
const existingLoadingScreen = document.querySelector(".loading-screen");
|
||||
if (existingLoadingScreen) return;
|
||||
|
||||
const loadingScreen = document.createElement('div');
|
||||
loadingScreen.className = 'loading-screen';
|
||||
loadingScreen.innerHTML = `
|
||||
<div class="loading-content">
|
||||
<img src="${chrome.runtime.getURL('images/loading.gif')}" alt="Firka" class="loading-logo">
|
||||
<div class="loading-text">Betöltés alatt...</div>
|
||||
<div class="loading-text2">Kis türelmet!</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(loadingScreen);
|
||||
document.body.classList.add('loaded');
|
||||
},
|
||||
const loadingScreen = document.createElement("div");
|
||||
loadingScreen.className = "loading-screen";
|
||||
|
||||
const loadingContent = document.createElement('div');
|
||||
loadingContent.className = 'loading-content';
|
||||
|
||||
const loadingLogo = document.createElement('img');
|
||||
loadingLogo.src = chrome.runtime.getURL("images/loading.gif");
|
||||
loadingLogo.alt = 'Firka';
|
||||
loadingLogo.className = 'loading-logo';
|
||||
|
||||
const loadingText = document.createElement('div');
|
||||
loadingText.className = 'loading-text';
|
||||
loadingText.setAttribute('data-i18n', 'loading.text');
|
||||
loadingText.textContent = 'Betöltés alatt...';
|
||||
|
||||
const loadingText2 = document.createElement('div');
|
||||
loadingText2.className = 'loading-text2';
|
||||
loadingText2.setAttribute('data-i18n', 'loading.subtext');
|
||||
loadingText2.textContent = 'Kis türelmet!';
|
||||
|
||||
loadingContent.appendChild(loadingLogo);
|
||||
loadingContent.appendChild(loadingText);
|
||||
loadingContent.appendChild(loadingText2);
|
||||
loadingScreen.appendChild(loadingContent);
|
||||
document.body.appendChild(loadingScreen);
|
||||
document.body.classList.add("loaded");
|
||||
},
|
||||
|
||||
hide() {
|
||||
document.body.classList.add('loaded');
|
||||
const loadingScreen = document.querySelector('.loading-screen');
|
||||
if (loadingScreen) {
|
||||
loadingScreen.style.opacity = '0';
|
||||
loadingScreen.addEventListener('transitionend', () => {
|
||||
loadingScreen.remove();
|
||||
});
|
||||
hide() {
|
||||
document.body.classList.add("loaded");
|
||||
const loadingScreen = document.querySelector(".loading-screen");
|
||||
if (loadingScreen) {
|
||||
loadingScreen.style.opacity = "0";
|
||||
|
||||
const removeLoadingScreen = () => {
|
||||
if (loadingScreen && loadingScreen.parentNode) {
|
||||
loadingScreen.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const urls = [];
|
||||
|
||||
if (manifest.content_scripts) {
|
||||
manifest.content_scripts.forEach(script => {
|
||||
if (script.matches) {
|
||||
urls.push(...script.matches);
|
||||
}
|
||||
});
|
||||
loadingScreen.addEventListener("transitionend", removeLoadingScreen, {
|
||||
once: true,
|
||||
});
|
||||
setTimeout(removeLoadingScreen, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (urls.some(url => url.includes(location.pathname))) {
|
||||
loadingScreen.show();
|
||||
}
|
||||
});
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const urls = [];
|
||||
|
||||
if (manifest.content_scripts) {
|
||||
manifest.content_scripts.forEach((script) => {
|
||||
if (script.matches) {
|
||||
urls.push(...script.matches);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
};
|
||||