mirror of
https://github.com/QwIT-Development/firka-extension.git
synced 2026-06-12 03:41:39 +02:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ec99a3b5c8 | ||
|
|
02ffa23e1a | ||
|
|
d7ea449a1b | ||
|
|
e7ec225e18 | ||
|
|
5a9837e655 | ||
|
|
1a340a1950 | ||
|
|
eef39c28d2 | ||
|
|
89266bc3c9 | ||
|
|
5408a1e08a | ||
|
|
6a52c51ece | ||
|
|
107e20f5c1 | ||
|
|
cb54d51b8c | ||
|
|
8eb7256f5b | ||
|
|
3510288181 | ||
|
|
8c9e1b215f | ||
|
|
e930706eb1 | ||
|
|
5340c1dff0 | ||
|
|
f3439a93d0 | ||
|
|
3e7b7089dd | ||
|
|
185f486a62 | ||
|
|
048f249dc5 | ||
|
|
5d9ae6971b | ||
|
|
42bfa0912f | ||
|
|
0322b31146 | ||
|
|
52fc99ca99 | ||
|
|
0a65ed3dda | ||
|
|
5a836947e1 | ||
|
|
ebb291ee87 | ||
|
|
56dcef30e0 | ||
|
|
cfe6e0fccf | ||
|
|
bacf77b506 | ||
|
|
3ee34b90e6 | ||
|
|
0e1f97eaaa | ||
|
|
699d2604c6 | ||
|
|
d8f1622b5b | ||
|
|
b69c9f3f6a | ||
|
|
ebf6aa8d61 | ||
|
|
0048ebb932 | ||
|
|
a55e40ecf2 | ||
|
|
ea5e01ce9c | ||
|
|
c0e738fd8b | ||
|
|
842588a0bb | ||
|
|
be2e7a192b | ||
|
|
60ad73ffae | ||
|
|
3a9bbbcb2a | ||
|
|
afb7a3d79b | ||
|
|
95d50e9297 | ||
|
|
e88566369a | ||
|
|
b9985ccf09 | ||
|
|
88706017f9 | ||
|
|
0aef3950e7 | ||
|
|
db74cb1a37 | ||
|
|
0d71510c7f | ||
| ee26b6d966 | |||
|
|
731511d28a | ||
|
|
79b09cb1ab | ||
|
|
1730c108df | ||
|
|
f990e2e899 | ||
|
|
2feef43ef2 | ||
|
|
dfc0c362c7 | ||
|
|
367547f67f | ||
|
|
003db8569e | ||
|
|
4eee8fa7e6 |
71
.github/workflows/build.yml
vendored
Normal file
71
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
name: Package and Release Extension
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- test
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
run: |
|
||||
echo "DATE=$(date +'%Y.%m.%d. %H:%M')" >> $GITHUB_ENV
|
||||
echo "DATE_FOR_ZIP=$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV
|
||||
|
||||
- name: Create ZIP file
|
||||
run: |
|
||||
zip -r "pre-firxa-${{ env.DATE_FOR_ZIP }}.zip" . -x "*.git*" "*.github*" "*.idea*"
|
||||
|
||||
- name: Delete previous pre-release
|
||||
uses: dev-drprasad/delete-tag-and-release@v0.2.1
|
||||
with:
|
||||
delete_release: true
|
||||
tag_name: pre-release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
continue-on-error: true
|
||||
|
||||
- name: Create new pre-release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: pre-release
|
||||
release_name: Fejlesztői build
|
||||
body: |
|
||||
Ez egy kiadás előtti build, amely minden egyes commit után frissül!
|
||||
A build automatikusan készült ekkor: ${{ env.DATE }}
|
||||
draft: false
|
||||
prerelease: true
|
||||
|
||||
- name: Upload ZIP to release
|
||||
if: steps.create_release.outputs.upload_url != ''
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./pre-firxa-${{ env.DATE_FOR_ZIP }}.zip
|
||||
asset_name: pre-firxa-${{ env.DATE_FOR_ZIP }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
check-links:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Link Checker
|
||||
id: lychee
|
||||
uses: lycheeverse/lychee-action@v2
|
||||
with:
|
||||
fail: false
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -7,3 +7,5 @@ META-INF/cose.sig
|
||||
META-INF/manifest.mf
|
||||
META-INF/mozilla.sf
|
||||
dashboard/KRÉTA Iskolai Alaprendszer.html
|
||||
*.xml
|
||||
*.xml
|
||||
|
||||
9
.idea/Firkaextension.iml
generated
9
.idea/Firkaextension.iml
generated
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Firkaextension.iml" filepath="$PROJECT_DIR$/.idea/Firkaextension.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
45
.idea/workspace.xml
generated
45
.idea/workspace.xml
generated
@@ -1,45 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="NONE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="2540850d-5586-4ef8-a1c0-838ec2731d44" name="Changes" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="ClangdSettings">
|
||||
<option name="formatViaClangd" value="false" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo"><![CDATA[{
|
||||
"associatedIndex": 0
|
||||
}]]></component>
|
||||
<component name="ProjectId" id="2uHD20KrXgQVbKPvZ8rqEw44Sjy" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.cidr.known.project.marker": "true",
|
||||
"RunOnceActivity.readMode.enableVisualFormatting": "true",
|
||||
"cf.first.check.clang-format": "false",
|
||||
"cidr.known.project.marker": "true",
|
||||
"kotlin-language-version-configured": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="2540850d-5586-4ef8-a1c0-838ec2731d44" name="Changes" comment="" />
|
||||
<created>1741896394934</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1741896394934</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
</project>
|
||||
32
README.md
32
README.md
@@ -8,14 +8,23 @@
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/Zan1456/Firkaextension/releases">
|
||||
<img src="https://img.shields.io/github/downloads-pre/Zan1456/Firkaextension/latest/total?style=for-the-badge&logo=github&logoColor=EAF7CC&label=Let%C3%B6lt%C3%A9sek&labelColor=141905&color=A7DC22" alt="Downloads">
|
||||
<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 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>
|
||||
<a href="https://github.com/Zan1456/Firkaextension/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/Zan1456/Firkaextension?style=for-the-badge&logo=discord&logoColor=EAF7CC&label=Discord&labelColor=0D1202&color=A7DC22" alt="License">
|
||||
<a href="https://github.com/QwIT-Development/firka-extension/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/QwIT-Development/firka-extension?style=for-the-badge&logo=discord&logoColor=EAF7CC&label=Discord&labelColor=0D1202&color=A7DC22" alt="License">
|
||||
</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>
|
||||
|
||||
@@ -34,13 +43,7 @@
|
||||
|
||||
## 🚀 Telepítés
|
||||
|
||||
1. Töltsd le a legfrissebb verziót a [Releases](https://github.com/Zan1456/Firkaextension/releases) oldalról
|
||||
2. Csomagold ki a letöltött fájlt
|
||||
3. Chrome böngészőben navigálj a `chrome://extensions` oldalra
|
||||
4. Kapcsold be a "Fejlesztői mód"-ot a jobb felső sarokban
|
||||
5. Kattints a "Kicsomagolt bővítmény betöltése" gombra
|
||||
6. Válaszd ki a kicsomagolt mappát
|
||||
7. Kész! 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
|
||||
|
||||
@@ -61,12 +64,13 @@ A bővítmény jelenleg az alábbi e-KRÉTA oldalakat támogatja:
|
||||
- Hiányzások
|
||||
- Házi feladatok
|
||||
- Jegyek
|
||||
- Intézménykereső
|
||||
|
||||
## 👥 Csapat
|
||||
|
||||
- **[Zan1456](https://github.com/Zan1456)** - Vezető Fejlesztő
|
||||
- **[BalazsManus](https://github.com/BalazsManus)** - Fejlesztő
|
||||
- **[Xou](https://github.com/Xou)** - Designer
|
||||
- **[BalazsManus](https://github.com/olajcsere)** - Fejlesztő
|
||||
- **[Xou](https://yoursit.ee/xou)** - Designer
|
||||
|
||||
## 🤝 Közreműködés
|
||||
|
||||
@@ -80,7 +84,7 @@ A bővítmény jelenleg az alábbi e-KRÉTA oldalakat támogatja:
|
||||
|
||||
## 📝 Licensz
|
||||
|
||||
A projekt [GNU General Public License v3.0](LICENSE) alatt jelent meg. További információért lásd a LICENSE fájlt.
|
||||
A projekt [GNU Affero General Public License v3.0](LICENSE) alatt jelent meg. További információért lásd a LICENSE fájlt.
|
||||
|
||||
## 💬 Kapcsolat
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ body {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school user"
|
||||
"nav nav";
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@@ -110,77 +110,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.kreta-nav {
|
||||
padding: 0 clamp(0.5rem, 3vw, 1.5rem);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links a {
|
||||
padding: 0.5rem;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.nav-links a .material-icons-round {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.nav-links a.active {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
@@ -212,19 +141,6 @@ body {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.user-time {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
|
||||
@@ -1,213 +1,101 @@
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function 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 function 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
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function collectAbsencesData() {
|
||||
await waitForElement('#HianyzasGrid');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: getCookie('schoolName') || 'Iskola',
|
||||
id: getCookie('schoolCode') || ''
|
||||
name: cookieManager.get('schoolName') || 'Iskola',
|
||||
id: cookieManager.get('schoolCode') || ''
|
||||
},
|
||||
userData: {
|
||||
name: getCookie('userName') || 'Felhasználó',
|
||||
name: cookieManager.get('userName') || 'Felhasználó',
|
||||
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 };
|
||||
}
|
||||
|
||||
function showLoadingScreen() {
|
||||
const loadingHTML = `
|
||||
<div class="loading-overlay">
|
||||
<div class="loading-container">
|
||||
<img src="https://i.imgur.com/JE3LzRc.gif" alt="Firka" class="loading-logo"><!--logó csere-->
|
||||
<div class="loading-text">Betöltés alatt...</div>
|
||||
<p class="loading-text2">Kis türelmet</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', loadingHTML);
|
||||
}
|
||||
|
||||
function hideLoadingScreen() {
|
||||
const loadingOverlay = document.querySelector('.loading-overlay');
|
||||
if (loadingOverlay) {
|
||||
loadingOverlay.style.opacity = '0';
|
||||
loadingOverlay.style.transition = 'opacity 0.3s ease';
|
||||
setTimeout(() => loadingOverlay.remove(), 300);
|
||||
return { basicData, absences, groupedAbsences };
|
||||
} catch (error) {
|
||||
console.error('Hiba az API hívás során:', error);
|
||||
return { basicData, absences: [], groupedAbsences: {} };
|
||||
}
|
||||
}
|
||||
|
||||
async function transformAbsencesPage() {
|
||||
showLoadingScreen();
|
||||
const { basicData, absences, groupedAbsences } = await collectAbsencesData();
|
||||
|
||||
|
||||
const schoolNameFull = `${basicData.schoolInfo.id} - ${basicData.schoolInfo.name}`;
|
||||
const shortenedSchoolName = shortenSchoolName(schoolNameFull);
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
<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">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
${shortenedSchoolName}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/dashboard-inactive.svg')}" alt="Kezdőlap">
|
||||
Kezdőlap
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/grades-inactive.svg')}" alt="Jegyek">
|
||||
Jegyek
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/timetable-inactive.svg')}" alt="Órarend">
|
||||
Órarend
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item active">
|
||||
<img src="${chrome.runtime.getURL('icons/absences-active.svg')}" alt="Mulasztások">
|
||||
Mulasztások
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/others.svg')}" alt="Egyéb">
|
||||
Egyéb
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="user-profile">
|
||||
<button class="user-dropdown-btn">
|
||||
<div class="user-info">
|
||||
<span class="user-name">${basicData.userData.name}</span>
|
||||
<span class="nav-logout-timer" id="logoutTimer">${basicData.userData.time}</span>
|
||||
</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>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<img src="${chrome.runtime.getURL('icons/settings.svg')}" alt="Beállítások">
|
||||
Beállítások
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>Szűrés</h2>
|
||||
<h2>${LanguageManager.t('absences.filter_title')}</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">date_range</span>
|
||||
Dátum
|
||||
${LanguageManager.t('absences.date')}
|
||||
</label>
|
||||
<input type="date" id="dateFilter" class="filter-input" disabled>
|
||||
<input type="date" id="dateFilter" class="filter-input">
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">school</span>
|
||||
Tantárgy
|
||||
${LanguageManager.t('absences.subject')}
|
||||
</label>
|
||||
<select id="subjectFilter" class="filter-input">
|
||||
<option value="">Minden tantárgy</option>
|
||||
<option value="">${LanguageManager.t('absences.all_subjects')}</option>
|
||||
${[...new Set(absences.map(a => a.subject))].sort().map(subject =>
|
||||
`<option value="${subject}">${subject}</option>`
|
||||
).join('')}
|
||||
@@ -216,13 +104,13 @@ async function transformAbsencesPage() {
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">check_circle</span>
|
||||
Igazolás
|
||||
${LanguageManager.t('absences.justification')}
|
||||
</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>
|
||||
<option value="">${LanguageManager.t('absences.all_types')}</option>
|
||||
<option value="justified">${LanguageManager.t('absences.justified')}</option>
|
||||
<option value="unjustified">${LanguageManager.t('absences.unjustified')}</option>
|
||||
<option value="pending">${LanguageManager.t('absences.pending')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -234,7 +122,7 @@ async function transformAbsencesPage() {
|
||||
<div class="absence-date">
|
||||
<span class="material-icons-round">event</span>
|
||||
${date}
|
||||
<span class="absence-count">${dayAbsences.length} óra</span>
|
||||
<span class="absence-count">${dayAbsences.length} ${LanguageManager.t('absences.hours')}</span>
|
||||
</div>
|
||||
<div class="absence-list">
|
||||
${dayAbsences.map(absence => `
|
||||
@@ -243,7 +131,7 @@ async function transformAbsencesPage() {
|
||||
data-justified="${absence.justified}">
|
||||
<div class="absence-time">
|
||||
<span class="material-icons-round">schedule</span>
|
||||
${absence.lesson}. óra
|
||||
${absence.lesson}. ${LanguageManager.t('absences.lesson').toLowerCase()}
|
||||
</div>
|
||||
<div class="absence-details">
|
||||
<div class="absence-subject">${absence.subject}</div>
|
||||
@@ -251,10 +139,10 @@ async function transformAbsencesPage() {
|
||||
</div>
|
||||
<div class="absence-status ${absence.justificationStatus}">
|
||||
${absence.justificationStatus === 'justified' ?
|
||||
`Igazolt <span class="material-icons-round">check_circle</span>` :
|
||||
`${LanguageManager.t('absences.justified')} <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>`}
|
||||
`${LanguageManager.t('absences.unjustified')} <span class="material-icons-round">cancel</span>` :
|
||||
`${LanguageManager.t('absences.pending')} <span class="material-icons-round">pending</span>`}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
@@ -266,69 +154,17 @@ async function transformAbsencesPage() {
|
||||
</div>
|
||||
`;
|
||||
|
||||
|
||||
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);
|
||||
});
|
||||
createTemplate.importFonts();
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
|
||||
setupEventListeners();
|
||||
setupFilters();
|
||||
|
||||
hideLoadingScreen();
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function setupEventListeners(data) {
|
||||
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');
|
||||
});
|
||||
|
||||
const timerEl = document.getElementById('logoutTimer');
|
||||
if (timerEl) {
|
||||
const startTime = parseInt(timerEl.textContent?.match(/\d+/)?.[0] || "30");
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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 setupEventListeners() {
|
||||
}
|
||||
|
||||
function setupFilters() {
|
||||
@@ -345,56 +181,42 @@ function setupFilters() {
|
||||
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('.');
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
// if (selectedDate && dateFilterValue) {
|
||||
// // Compare year, month, and day to ignore time
|
||||
// showGroup = groupDate.getFullYear() === selectedDate.getFullYear() &&
|
||||
// groupDate.getMonth() === selectedDate.getMonth() &&
|
||||
// groupDate.getDate() === selectedDate.getDate();
|
||||
//
|
||||
// console.log(`Comparing dates: ${groupDate.toDateString()} vs ${selectedDate.toDateString()}, match: ${showGroup}`);
|
||||
// }
|
||||
if (selectedDate) {
|
||||
if (groupDate.getFullYear() !== selectedDate.getFullYear() ||
|
||||
groupDate.getMonth() !== selectedDate.getMonth() ||
|
||||
groupDate.getDate() !== selectedDate.getDate()) {
|
||||
showGroup = false;
|
||||
}
|
||||
}
|
||||
|
||||
const absenceItems = group.querySelectorAll('.absence-item');
|
||||
let visibleItems = 0;
|
||||
@@ -422,15 +244,9 @@ function setupFilters() {
|
||||
};
|
||||
|
||||
|
||||
// if (!filters.dateFilter.value) {
|
||||
// const today = new Date();
|
||||
// filters.dateFilter.value = today.toISOString().split('T')[0]; // Set date to today by default
|
||||
// }
|
||||
|
||||
|
||||
Object.values(filters).forEach(filter => {
|
||||
try {
|
||||
if (filter && filter !== filters.dateFilter) { // Don't add event listener to dateFilter
|
||||
if (filter) {
|
||||
filter.addEventListener('change', filterAbsences);
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -457,6 +273,6 @@ function setupFilters() {
|
||||
|
||||
if (window.location.href.includes('/Hianyzas/Hianyzasok')) {
|
||||
transformAbsencesPage().catch(error => {
|
||||
console.error('Hiba történt az oldal átalakítása során:', 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,185 @@ 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;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.widget-subtitle {
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.widget-meta {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.widget-empty {
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.grade {
|
||||
width: 32px;
|
||||
@@ -84,15 +231,25 @@ 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;
|
||||
}
|
||||
.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);
|
||||
}
|
||||
|
||||
.exam-type {
|
||||
color: var(--accent-accent);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
@@ -120,6 +277,7 @@ body {
|
||||
.grade-3 {color: var(--grades-3); background-color: var(--grades-background-3);}
|
||||
.grade-4 {color: var(--grades-4); background-color: var(--grades-background-4);}
|
||||
.grade-5 {color: var(--grades-5); background-color: var(--grades-background-5);}
|
||||
.grade-Sz {color: var(--grades-3); background-color: var(--grades-background-3);}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
@@ -179,15 +337,25 @@ body {
|
||||
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);
|
||||
}
|
||||
|
||||
.exam-type {
|
||||
color: var(--accent-accent);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
@@ -211,22 +379,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,52 +1,49 @@
|
||||
const utils = {
|
||||
shortenSchoolName(name, maxLength = 50) {
|
||||
if (!name || name.length <= maxLength) return name || '';
|
||||
|
||||
const [code, fullName] = name.split(' - ');
|
||||
if (fullName) {
|
||||
const maxFullNameLength = maxLength - code.length - 3;
|
||||
if (fullName.length > maxFullNameLength) {
|
||||
return `${code} - ${fullName.substring(0, maxFullNameLength)}...`;
|
||||
}
|
||||
}
|
||||
return `${name.substring(0, maxLength - 3)}...`;
|
||||
},
|
||||
|
||||
const DashboardUtils = {
|
||||
formatGradeValue(value) {
|
||||
return value?.trim() || '';
|
||||
const trimmedValue = value?.trim() || '';
|
||||
if (trimmedValue.toLowerCase() === 'szöveges') {
|
||||
return 'Sz';
|
||||
}
|
||||
return trimmedValue;
|
||||
},
|
||||
|
||||
parseDate(dateStr) {
|
||||
return dateStr?.trim() || '';
|
||||
},
|
||||
|
||||
|
||||
formatHungarianDate(dateStr) {
|
||||
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: [],
|
||||
@@ -55,46 +52,69 @@ class DashboardDataExtractor {
|
||||
};
|
||||
}
|
||||
|
||||
extractGrades() {
|
||||
extractGradeData() {
|
||||
const gradeRows = document.querySelectorAll('#legutobbiErtekelesek tr:not(:first-child)');
|
||||
|
||||
this.data.grades = Array.from(gradeRows).map(row => {
|
||||
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 } = this.parseSubjectInfo(fullSubject);
|
||||
const { subject, type, dateInSubject } = this.parseSubjectInformation(fullSubject);
|
||||
|
||||
return {
|
||||
value: utils.formatGradeValue(gradeValue),
|
||||
value: DashboardUtils.formatGradeValue(gradeValue),
|
||||
subject,
|
||||
date: utils.parseDate(date),
|
||||
type: type || 'Értékelés'
|
||||
date: DashboardUtils.parseDate(date),
|
||||
type: type || LanguageManager.t('dashboard.evaluation'),
|
||||
dateInSubject: dateInSubject || null
|
||||
};
|
||||
}).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);
|
||||
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 (!monthMatch) return { subject: fullSubject, type: '' };
|
||||
if (dateMatch) {
|
||||
const subjectPart = fullSubject.substring(0, dateMatch.index).trim();
|
||||
const datePart = dateMatch[0].trim();
|
||||
return {
|
||||
subject: subjectPart,
|
||||
type: '',
|
||||
dateInSubject: datePart
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const monthIndex = fullSubject.lastIndexOf(monthMatch[0]);
|
||||
return {
|
||||
subject: fullSubject.substring(0, monthIndex).trim(),
|
||||
type: fullSubject.substring(monthIndex).trim()
|
||||
};
|
||||
if (monthMatch) {
|
||||
const monthIndex = fullSubject.lastIndexOf(monthMatch[0]);
|
||||
return {
|
||||
subject: fullSubject.substring(0, monthIndex).trim(),
|
||||
type: fullSubject.substring(monthIndex).trim()
|
||||
};
|
||||
}
|
||||
|
||||
return { subject: fullSubject, type: '' };
|
||||
}
|
||||
|
||||
extractAbsences() {
|
||||
extractAbsenceData() {
|
||||
const absenceRows = document.querySelectorAll('#legutobbiMulasztasok tr:not(:first-child)');
|
||||
|
||||
this.data.absences = Array.from(absenceRows).map(row => {
|
||||
this.dashboardData.absences = Array.from(absenceRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 4) return null;
|
||||
|
||||
@@ -107,10 +127,10 @@ class DashboardDataExtractor {
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
extractNotes() {
|
||||
extractNoteData() {
|
||||
const noteRows = document.querySelectorAll('#legutobbiFeljegyzesek tr:not(:first-child)');
|
||||
|
||||
this.data.notes = Array.from(noteRows).map(row => {
|
||||
this.dashboardData.notes = Array.from(noteRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 3) return null;
|
||||
|
||||
@@ -122,10 +142,10 @@ class DashboardDataExtractor {
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
extractExams() {
|
||||
extractExamData() {
|
||||
const examRows = document.querySelectorAll('#legutobbiBejelentettSzamonkeres tr:not(:first-child)');
|
||||
|
||||
this.data.upcomingExams = Array.from(examRows).map(row => {
|
||||
this.dashboardData.upcomingExams = Array.from(examRows).map(row => {
|
||||
const spans = row.querySelectorAll('span');
|
||||
if (spans.length < 4) return null;
|
||||
|
||||
@@ -138,309 +158,294 @@ class DashboardDataExtractor {
|
||||
}).filter(Boolean);
|
||||
}
|
||||
|
||||
extractNews() {
|
||||
const newsContainer = document.querySelector('.faliujsag-lista, #faliujsagLista');
|
||||
if (!newsContainer) return;
|
||||
async extractNewsData() {
|
||||
|
||||
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');
|
||||
try {
|
||||
const timestamp = Date.now();
|
||||
const apiUrl = `https://${window.location.hostname}/Intezmeny/Faliujsag/GetMoreEntries?startindex=0&range=10&_=${timestamp}`;
|
||||
|
||||
|
||||
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;
|
||||
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 data = await response.json();
|
||||
|
||||
const authorElement = item.querySelector('.auth-name span, .news-author');
|
||||
if (!data.FaliujsagElemek || !Array.isArray(data.FaliujsagElemek)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
title: titleElement?.textContent?.trim() || '',
|
||||
date: dateStr.trim(),
|
||||
content: contentElement?.textContent?.trim() || '',
|
||||
author: authorElement?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(news => news.title || news.content);
|
||||
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.data = {
|
||||
...data,
|
||||
schoolInfo: {
|
||||
name: cookies.getCookie(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
id: cookies.getCookie(COOKIE_KEYS.SCHOOL_CODE) || ''
|
||||
name: cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
id: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || ''
|
||||
},
|
||||
userData: {
|
||||
name: cookies.getCookie(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
||||
}
|
||||
};
|
||||
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
|
||||
this.shortenedSchoolName = utils.shortenSchoolName(this.schoolNameFull);
|
||||
this.shortenedSchoolName = helper.shortenSchoolName(this.schoolNameFull);
|
||||
}
|
||||
|
||||
|
||||
static generateHeaderHTML(data, schoolNameFull, shortenedSchoolName) {
|
||||
return `
|
||||
<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">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
${shortenedSchoolName}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item active">
|
||||
<img src="${chrome.runtime.getURL('icons/dashboard-active.svg')}" alt="Kezdőlap">
|
||||
Kezdőlap
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/grades-inactive.svg')}" alt="Jegyek">
|
||||
Jegyek
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/timetable-inactive.svg')}" alt="Órarend">
|
||||
Órarend
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/absences-inactive.svg')}" alt="Mulasztások">
|
||||
Mulasztások
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/others.svg')}" alt="Egyéb">
|
||||
Egyéb
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="user-profile">
|
||||
<button class="user-dropdown-btn">
|
||||
<div class="user-info">
|
||||
<span class="user-name">${data.userData.name}</span>
|
||||
<span class="nav-logout-timer" id="logoutTimer">${data.userData.time}</span>
|
||||
</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>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<img src="${chrome.runtime.getURL('icons/settings.svg')}" alt="Beállítások">
|
||||
Beállítások
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
`;
|
||||
}
|
||||
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() {
|
||||
createNewsCard() {
|
||||
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>
|
||||
<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('');
|
||||
|
||||
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() {
|
||||
|
||||
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('');
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.grades'), gradeItems, '/TanuloErtekeles/Osztalyzatok', LanguageManager.t('dashboard.all_grades'));
|
||||
}
|
||||
|
||||
createAbsenceCard() {
|
||||
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>
|
||||
<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('');
|
||||
|
||||
return this.generateCard('Mulasztások', absenceItems, '/Hianyzas/Hianyzasok', 'Összes mulasztás');
|
||||
return this.createCard(LanguageManager.t('dashboard.absences'), absenceItems, '/Hianyzas/Hianyzasok', LanguageManager.t('dashboard.all_absences'));
|
||||
}
|
||||
generateNoteCard() {
|
||||
|
||||
createNoteCard() {
|
||||
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>
|
||||
<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('');
|
||||
|
||||
return this.generateCard('Feljegyzések', noteItems, '/TanuloErtekeles/InformaciokFeljegyzesek', 'Összes üzeneted');
|
||||
return this.createCard(LanguageManager.t('dashboard.notes'), noteItems, '/TanuloErtekeles/InformaciokFeljegyzesek', LanguageManager.t('dashboard.all_messages'));
|
||||
}
|
||||
generateExamCard() {
|
||||
|
||||
createExamCard() {
|
||||
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>
|
||||
<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.generateCard('Bejelentett dolgozatok', examItems, '/Tanulo/TanuloBejelentettSzamonkeresek', 'Összes dolgozat');
|
||||
return this.createCard(LanguageManager.t('dashboard.exams'), examItems, '/Tanulo/TanuloBejelentettSzamonkeresek', LanguageManager.t('dashboard.all_exams'));
|
||||
}
|
||||
generateCard(title, content, linkHref, linkText) {
|
||||
|
||||
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">
|
||||
${DashboardUI.generateHeaderHTML(this.data, this.schoolNameFull, this.shortenedSchoolName)}
|
||||
${this.generateMainContentHTML()}
|
||||
${createTemplate.header()}
|
||||
${this.generateMainContent()}
|
||||
</div>
|
||||
`;
|
||||
setupUserDropdown();
|
||||
setupLogoutTimer();
|
||||
setupMobileNavigation();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function setupLogoutTimer() {
|
||||
const timerElement = document.querySelector('.nav-logout-timer');
|
||||
if (!timerElement) return;
|
||||
|
||||
const timeString = timerElement.textContent;
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
class FontLoader {
|
||||
static loadFonts() {
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
FontLoader.loadFonts();
|
||||
const ui = new DashboardUI(dashboardData);
|
||||
ui.render();
|
||||
const dataManager = new DashboardDataManager();
|
||||
const dashboardData = await dataManager.extractAllData();
|
||||
createTemplate.importFonts();
|
||||
const renderer = new DashboardRenderer(dashboardData);
|
||||
renderer.render();
|
||||
} catch (error) {
|
||||
console.error('Error initializing dashboard:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
new DashboardApp();
|
||||
new DashboardApplication();
|
||||
@@ -1,202 +1,292 @@
|
||||
: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;
|
||||
}
|
||||
|
||||
* {
|
||||
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;
|
||||
}
|
||||
|
||||
.forgot-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.forgot-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;
|
||||
}
|
||||
|
||||
.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;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.forgot-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.forgot-form {
|
||||
width: 100%;
|
||||
=======
|
||||
.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;
|
||||
margin-bottom: 8px;
|
||||
color: var(--text-primary);
|
||||
font-family: Montserrat;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.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;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
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;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.help-link:hover {
|
||||
color: var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
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-submit:hover {
|
||||
background: var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-submit:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
animation: fadeIn 0.3s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message.success {
|
||||
background: var(--success-card);
|
||||
color: var(--success-text);
|
||||
border: 1px solid var(--success-accent);
|
||||
}
|
||||
|
||||
.message.error {
|
||||
background: var(--error-card);
|
||||
color: var(--error-text);
|
||||
border: 1px solid var(--error-accent);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.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;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
background: var(--card);
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
margin-bottom: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.forgot-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.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;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.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;
|
||||
height: 44px;
|
||||
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);
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
.help-link {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.forgot-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.g-recaptcha {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.forgot-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
@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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,67 +1,169 @@
|
||||
(() => {
|
||||
const transformForgotPasswordPage = () => {
|
||||
const renderRecaptcha = () => {
|
||||
const container = document.getElementById('recaptcha-container');
|
||||
if (container && typeof grecaptcha !== 'undefined' && grecaptcha.render) {
|
||||
try {
|
||||
grecaptcha.render('recaptcha-container', {
|
||||
'sitekey': '6LfKURIqAAAAAD5bF2evQ-_Sf6MRrOkUEBwb_mMy',
|
||||
'theme': 'light'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error rendering reCAPTCHA:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const loadDependencies = async () => {
|
||||
if (typeof cookieManager === 'undefined') {
|
||||
const cookieScript = document.createElement('script');
|
||||
cookieScript.src = chrome.runtime.getURL('tools/cookieManager.js');
|
||||
document.head.appendChild(cookieScript);
|
||||
|
||||
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);
|
||||
}
|
||||
await new Promise(resolve => {
|
||||
cookieScript.onload = resolve;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (typeof LanguageManager === 'undefined') {
|
||||
const langScript = document.createElement('script');
|
||||
langScript.src = chrome.runtime.getURL('global/language.js');
|
||||
document.head.appendChild(langScript);
|
||||
|
||||
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">
|
||||
|
||||
await new Promise(resolve => {
|
||||
langScript.onload = resolve;
|
||||
});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
if (!document.querySelector('script[src*="recaptcha"]')) {
|
||||
await new Promise((resolve) => {
|
||||
window.onRecaptchaLoad = resolve;
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://www.google.com/recaptcha/api.js?hl=hu&onload=onRecaptchaLoad&render=explicit';
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const createPageStructure = () => {
|
||||
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">
|
||||
<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">
|
||||
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>
|
||||
|
||||
<div id="recaptcha-container"></div>
|
||||
|
||||
<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();
|
||||
</div>
|
||||
`;
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
renderRecaptcha();
|
||||
}, 500);
|
||||
|
||||
setupFormValidation();
|
||||
};
|
||||
|
||||
const setupFormValidation = () => {
|
||||
const form = document.getElementById('forgotForm');
|
||||
@@ -97,29 +199,83 @@
|
||||
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();
|
||||
}
|
||||
}, 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;
|
||||
}
|
||||
|
||||
let recaptchaResponse = '';
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
recaptchaResponse = grecaptcha.getResponse();
|
||||
if (!recaptchaResponse) {
|
||||
showMessage(LanguageManager.t('forgotpassword.recaptcha_required'), true);
|
||||
isValid = false;
|
||||
}
|
||||
} else {
|
||||
showMessage('reCAPTCHA nem töltődött be. Kérjük, frissítse az oldalt!', true);
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
formData.append('ReCaptcha', grecaptcha.getResponse());
|
||||
}
|
||||
|
||||
const response = await fetch('/Adminisztracio/ElfelejtettJelszo/LinkKuldes', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
@@ -127,26 +283,46 @@
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
|
||||
if (result.Success) {
|
||||
window.location.href = '/Adminisztracio/Login';
|
||||
showMessage(LanguageManager.t('forgotpassword.success_message'));
|
||||
|
||||
form.reset();
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Adminisztracio/Login';
|
||||
}, 3000);
|
||||
} 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();
|
||||
showMessage(result.Message || LanguageManager.t('forgotpassword.error_message'), true);
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
//alert('Hiba történt a jelszó visszaállítása során.');
|
||||
grecaptcha.reset();
|
||||
console.error('Password reset error:', error);
|
||||
showMessage(LanguageManager.t('forgotpassword.error_message'), true);
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
} finally {
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = originalText;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (window.location.href.includes('/Adminisztracio/ElfelejtettJelszo')) {
|
||||
transformForgotPasswordPage();
|
||||
transformForgotPasswordPage().catch(console.error);
|
||||
}
|
||||
})();
|
||||
131
global/language.js
Normal file
131
global/language.js
Normal file
@@ -0,0 +1,131 @@
|
||||
(function() {
|
||||
let currentLanguage = 'hu';
|
||||
let translations = {};
|
||||
|
||||
async function setLanguage(language) {
|
||||
try {
|
||||
currentLanguage = language;
|
||||
|
||||
cookieManager.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() {
|
||||
const cookieLanguage = cookieManager.get('languagePreference');
|
||||
const localStorageLanguage = localStorage.getItem('languagePreference');
|
||||
|
||||
const language = cookieLanguage || localStorageLanguage || 'hu';
|
||||
|
||||
await setLanguage(language);
|
||||
|
||||
|
||||
if (cookieLanguage !== localStorageLanguage) {
|
||||
if (cookieLanguage) {
|
||||
localStorage.setItem('languagePreference', cookieLanguage);
|
||||
} else if (localStorageLanguage) {
|
||||
cookieManager.set('languagePreference', localStorageLanguage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
});
|
||||
|
||||
|
||||
window.LanguageManager = {
|
||||
getCurrentLanguage: () => currentLanguage,
|
||||
changeLanguage: setLanguage,
|
||||
t: getTranslation,
|
||||
getAvailableLanguages: () => [
|
||||
{ code: 'hu', name: 'Magyar' },
|
||||
{ code: 'en', name: 'English' }
|
||||
]
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -1,3 +1,28 @@
|
||||
@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;
|
||||
}
|
||||
|
||||
body.maintenance-mode {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -7,7 +32,7 @@ body.maintenance-mode {
|
||||
justify-content: center;
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-family: 'Inter', sans-serif;
|
||||
font-family: 'Figtree', sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -35,6 +60,7 @@ body {
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--accent-accent);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-message {
|
||||
@@ -42,10 +68,22 @@ body {
|
||||
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;
|
||||
}
|
||||
@@ -7,18 +7,46 @@ function loadMaintenanceCSS() {
|
||||
|
||||
function checkMaintenancePage() {
|
||||
const maintenanceContent = document.querySelector('.login_content');
|
||||
if (maintenanceContent && maintenanceContent.textContent.includes('frissítés alatt')) {
|
||||
const bodyText = document.body ? document.body.textContent : '';
|
||||
|
||||
const specificMaintenanceMessage = 'Kedves Felhasználók! A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik. Köszönjük türelmüket és megértésüket! KRÉTA Csapat';
|
||||
const hasSpecificMessage = bodyText.includes('Kedves Felhasználók!') &&
|
||||
bodyText.includes('A KRÉTA rendszer jelenleg frissítés alatt van') &&
|
||||
bodyText.includes('KRÉTA Csapat');
|
||||
|
||||
const 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();
|
||||
@@ -34,20 +62,25 @@ function checkMaintenancePage() {
|
||||
|
||||
const title = document.createElement('h1');
|
||||
title.className = 'maintenance-title';
|
||||
title.textContent = 'Karbantartás';
|
||||
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 = 'A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.';
|
||||
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 = 'Köszönjük türelmüket és megértésüket!';
|
||||
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 = 'KRÉTA Csapat';
|
||||
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);
|
||||
@@ -59,6 +92,7 @@ function checkMaintenancePage() {
|
||||
container.appendChild(footer);
|
||||
|
||||
body.appendChild(container);
|
||||
body.appendChild(cactus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,16 +191,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Hamburger menu styles */
|
||||
.nav-toggle {
|
||||
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);
|
||||
}
|
||||
|
||||
.nav-toggle svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: var(--text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school user"
|
||||
"nav nav";
|
||||
"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;
|
||||
@@ -211,21 +237,24 @@
|
||||
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
font-size: 11px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.kreta-nav.show {
|
||||
display: flex;
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
@@ -233,25 +262,140 @@
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 0.25rem;
|
||||
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 {
|
||||
padding: 0.5rem;
|
||||
font-size: 13px;
|
||||
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: 14px;
|
||||
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"
|
||||
"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;
|
||||
}
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -6,31 +6,20 @@ const COOKIE_KEYS = {
|
||||
};
|
||||
|
||||
const DEFAULT_VALUES = {
|
||||
SCHOOL: 'Iskola',
|
||||
USER: 'Felhasználó',
|
||||
SCHOOL: LanguageManager.t('navigation.school_default'),
|
||||
USER: LanguageManager.t('navigation.user_default'),
|
||||
TIMER: '45:00'
|
||||
};
|
||||
|
||||
const cookies = {
|
||||
getCookie(name) {
|
||||
const value = `; ${document.cookie}`;
|
||||
const parts = value.split(`; ${name}=`);
|
||||
return parts.length === 2 ? parts.pop().split(';').shift() : null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
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: cookies.getCookie(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
schoolId: cookies.getCookie(COOKIE_KEYS.SCHOOL_CODE) || '',
|
||||
name: cookies.getCookie(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
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
|
||||
};
|
||||
|
||||
@@ -95,9 +84,39 @@ function setupSettingsButton() {
|
||||
});
|
||||
}
|
||||
|
||||
function setupMobileNavigation() {
|
||||
setTimeout(() => {
|
||||
const navToggle = document.querySelector('.nav-toggle');
|
||||
const nav = document.querySelector('.kreta-nav');
|
||||
|
||||
if (!navToggle || !nav) {
|
||||
return;
|
||||
}
|
||||
|
||||
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');
|
||||
}
|
||||
});
|
||||
|
||||
const navItems = document.querySelectorAll('.nav-item');
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
nav.classList.remove('show');
|
||||
});
|
||||
});
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
});
|
||||
|
||||
111
global/theme.js
111
global/theme.js
@@ -1,87 +1,69 @@
|
||||
(() => {
|
||||
|
||||
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 getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function setTheme(theme) {
|
||||
try {
|
||||
|
||||
const actualTheme = theme === 'default' ? 'light-blue' : theme;
|
||||
|
||||
document.documentElement.setAttribute('data-theme', actualTheme);
|
||||
setCookie('themePreference', actualTheme);
|
||||
cookieManager.set('themePreference', actualTheme);
|
||||
localStorage.setItem('themePreference', actualTheme);
|
||||
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'themeChanged',
|
||||
theme: actualTheme
|
||||
}).catch(() => {
|
||||
|
||||
console.log('Extension context not available for theme sync');
|
||||
|
||||
});
|
||||
|
||||
console.log('Theme set to:', actualTheme);
|
||||
} 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 initializeTheme() {
|
||||
|
||||
const cookieTheme = getCookie('themePreference');
|
||||
const cookieTheme = cookieManager.get('themePreference');
|
||||
const localStorageTheme = localStorage.getItem('themePreference');
|
||||
|
||||
|
||||
const theme = cookieTheme || localStorageTheme || 'light-blue';
|
||||
|
||||
const theme = cookieTheme || localStorageTheme || 'light-green';
|
||||
|
||||
setTheme(theme);
|
||||
|
||||
setPageTitleAndFavicon();
|
||||
|
||||
if (cookieTheme !== localStorageTheme) {
|
||||
if (cookieTheme) {
|
||||
localStorage.setItem('themePreference', cookieTheme);
|
||||
} else if (localStorageTheme) {
|
||||
setCookie('themePreference', localStorageTheme);
|
||||
cookieManager.set('themePreference', localStorageTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initializeTheme();
|
||||
});
|
||||
|
||||
|
||||
initializeTheme();
|
||||
document.addEventListener('DOMContentLoaded', initializeTheme);
|
||||
} else {
|
||||
|
||||
initializeTheme();
|
||||
}
|
||||
|
||||
@@ -93,35 +75,58 @@
|
||||
}
|
||||
|
||||
if (message.action === 'getTheme') {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light-blue';
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light-green';
|
||||
sendResponse({ theme: currentTheme });
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
const savedTheme = getCookie('themePreference') || localStorage.getItem('themePreference');
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
})();
|
||||
File diff suppressed because one or more lines are too long
1182
grades/grades.css
1182
grades/grades.css
File diff suppressed because it is too large
Load Diff
1009
grades/grades.js
1009
grades/grades.js
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,3 @@
|
||||
@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;
|
||||
@@ -67,10 +42,10 @@ body {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school user"
|
||||
"nav nav";
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@@ -135,77 +110,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.kreta-nav {
|
||||
padding: 0 clamp(0.5rem, 3vw, 1.5rem);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links a {
|
||||
padding: 0.5rem;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.nav-links a .material-icons-round {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.nav-links a.active {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
@@ -235,31 +139,22 @@ body {
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
min-width: 200px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
width: 200px;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.user-dropdown.show {
|
||||
display: block;
|
||||
animation: dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
@@ -289,13 +184,13 @@ body {
|
||||
.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);
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
margin-bottom: 1rem;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.filter-header h2 {
|
||||
@@ -307,43 +202,40 @@ body {
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
gap: 1rem;
|
||||
width: 100%;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.filter-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
font-size: 14px;
|
||||
gap: 8px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.filter-group select,
|
||||
.filter-group input {
|
||||
padding: 0.75rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid var(--accent-15);
|
||||
background-color: var(--background);
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
width: 100%;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
transition: all 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);
|
||||
box-shadow: 0 0 0 2px var(--accent-accent);
|
||||
}
|
||||
|
||||
.filter-actions {
|
||||
@@ -379,134 +271,116 @@ body {
|
||||
|
||||
|
||||
.homework-list {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.homework-date-group {
|
||||
margin-bottom: 2rem;
|
||||
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);
|
||||
}
|
||||
|
||||
.date-header {
|
||||
padding: 16px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.homework-count {
|
||||
margin-left: auto;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.homework-list-items {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.date-header h3 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.homework-item {
|
||||
background: var(--card-card);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
margin: 0 16px 12px 16px;
|
||||
background: var(--accent-15);
|
||||
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);
|
||||
transform: translateX(4px);
|
||||
}
|
||||
|
||||
.homework-item.due-tomorrow {
|
||||
border-left: 4px solid var(--accent-accent);
|
||||
background-color: var(--accent-5);
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.homework-header {
|
||||
.homework-item.due-tomorrow .homework-subject,
|
||||
.homework-item.due-tomorrow .homework-content,
|
||||
.homework-item.due-tomorrow .homework-teacher {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.homework-details {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 0.5rem;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.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;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.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);
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.4;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.homework-teacher {
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
background-color: var(--background);
|
||||
padding: 2rem;
|
||||
border-radius: 16px;
|
||||
text-align: center;
|
||||
max-width: 90%;
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
width: 80px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.5rem;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.loading-text2 {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
color: var(--text-secondary);
|
||||
display: none;
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.empty-state p {
|
||||
@@ -524,4 +398,48 @@ body {
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: clamp(4px, 1vw, 8px);
|
||||
height: clamp(4px, 1vw, 8px);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
}
|
||||
@@ -1,89 +1,63 @@
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function 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 function 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));
|
||||
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'
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
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() {
|
||||
await waitForElement('#TanulotHaziFeladatkGrid');
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
const apiData = await fetchHomeworkData();
|
||||
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: getCookie('schoolName') || 'Iskola',
|
||||
id: getCookie('schoolCode') || ''
|
||||
name: cookieManager.get('schoolName') || 'Iskola',
|
||||
id: cookieManager.get('schoolCode') || ''
|
||||
},
|
||||
userData: {
|
||||
name: getCookie('userName') || 'Felhasználó',
|
||||
name: cookieManager.get('userName') || 'Felhasználó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00'
|
||||
}
|
||||
};
|
||||
|
||||
const homeworkItems = [];
|
||||
const rows = document.querySelectorAll('#TanulotHaziFeladatkGrid .k-grid-content tr');
|
||||
rows.forEach(row => {
|
||||
const cells = row.querySelectorAll('td');
|
||||
if (cells.length >= 7) {
|
||||
homeworkItems.push({
|
||||
subject: cells[3]?.textContent?.trim() || '',
|
||||
teacher: cells[4]?.textContent?.trim() || '',
|
||||
description: cells[5]?.textContent?.trim() || '',
|
||||
createdDate: cells[6]?.textContent?.trim() || '',
|
||||
deadline: cells[7]?.textContent?.trim() || ''
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
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(' ').slice(0, 3).join(' ');
|
||||
const deadlineDate = homework.deadline.split(' ')[0];
|
||||
if (!groupedHomework[deadlineDate]) {
|
||||
groupedHomework[deadlineDate] = [];
|
||||
}
|
||||
@@ -93,26 +67,28 @@ async function collectHomeworkData() {
|
||||
return { basicData, homeworkItems, groupedHomework };
|
||||
}
|
||||
|
||||
function showLoadingScreen() {
|
||||
const loadingHTML = `
|
||||
<div class="loading-overlay">
|
||||
<div class="loading-container">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="loading-logo">
|
||||
<div class="loading-text">Betöltés alatt...</div>
|
||||
<p class="loading-text2">Kis türelmet</p>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
function formatApiDate(dateString) {
|
||||
if (!dateString) return '';
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', loadingHTML);
|
||||
}
|
||||
|
||||
function hideLoadingScreen() {
|
||||
const loadingOverlay = document.querySelector('.loading-overlay');
|
||||
if (loadingOverlay) {
|
||||
loadingOverlay.style.opacity = '0';
|
||||
loadingOverlay.style.transition = 'opacity 0.3s ease';
|
||||
setTimeout(() => loadingOverlay.remove(), 300);
|
||||
try {
|
||||
const date = new Date(dateString);
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
|
||||
const dayNames = [
|
||||
LanguageManager.t('common.sunday'),
|
||||
LanguageManager.t('common.monday'),
|
||||
LanguageManager.t('common.tuesday'),
|
||||
LanguageManager.t('common.wednesday'),
|
||||
LanguageManager.t('common.thursday'),
|
||||
LanguageManager.t('common.friday'),
|
||||
LanguageManager.t('common.saturday')
|
||||
];
|
||||
const dayName = dayNames[date.getDay()];
|
||||
|
||||
return `${month}.${day}. (${dayName})`;
|
||||
} catch (error) {
|
||||
return dateString;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,7 +100,7 @@ function isTomorrow(dateStr) {
|
||||
if (parts.length < 3) return false;
|
||||
|
||||
const year = parseInt(parts[0].trim());
|
||||
const month = parseInt(parts[1].trim()) - 1; // JS months are 0-indexed
|
||||
const month = parseInt(parts[1].trim()) - 1;
|
||||
const day = parseInt(parts[2].trim());
|
||||
|
||||
const homeworkDate = new Date(year, month, day);
|
||||
@@ -143,88 +119,25 @@ function isTomorrow(dateStr) {
|
||||
}
|
||||
|
||||
async function transformHomeworkPage() {
|
||||
showLoadingScreen();
|
||||
const { basicData, homeworkItems, groupedHomework } = await collectHomeworkData();
|
||||
|
||||
|
||||
const schoolNameFull = `${basicData.schoolInfo.id} - ${basicData.schoolInfo.name}`;
|
||||
const shortenedSchoolName = shortenSchoolName(schoolNameFull);
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
<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">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
${shortenedSchoolName}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/dashboard-inactive.svg')}" alt="Kezdőlap">
|
||||
Kezdőlap
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/grades-inactive.svg')}" alt="Jegyek">
|
||||
Jegyek
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/timetable-inactive.svg')}" alt="Órarend">
|
||||
Órarend
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item">
|
||||
<img src="${chrome.runtime.getURL('icons/absences-inactive.svg')}" alt="Mulasztások">
|
||||
Mulasztások
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item active">
|
||||
<img src="${chrome.runtime.getURL('icons/others.svg')}" alt="Egyéb">
|
||||
Egyéb
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="user-profile">
|
||||
<button class="user-dropdown-btn">
|
||||
<div class="user-info">
|
||||
<span class="user-name">${basicData.userData.name}</span>
|
||||
<span class="nav-logout-timer" id="logoutTimer">${basicData.userData.time}</span>
|
||||
</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>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<img src="${chrome.runtime.getURL('icons/settings.svg')}" alt="Beállítások">
|
||||
Beállítások
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>Szűrés</h2>
|
||||
<h2>${LanguageManager.t('homework.filter_title')}</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">subject</span>-->
|
||||
Tantárgy
|
||||
${LanguageManager.t('homework.subject')}
|
||||
</label>
|
||||
<select id="subjectFilter">
|
||||
<option value="">Összes tantárgy</option>
|
||||
<option value="">${LanguageManager.t('homework.all_subjects')}</option>
|
||||
${[...new Set(homeworkItems.map(item => item.subject))]
|
||||
.sort()
|
||||
.map(subject => `<option value="${subject}">${subject}</option>`)
|
||||
@@ -234,10 +147,10 @@ async function transformHomeworkPage() {
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">person</span>-->
|
||||
Tanár
|
||||
${LanguageManager.t('homework.teacher')}
|
||||
</label>
|
||||
<select id="teacherFilter">
|
||||
<option value="">Összes tanár</option>
|
||||
<option value="">${LanguageManager.t('homework.all_teachers')}</option>
|
||||
${[...new Set(homeworkItems.map(item => item.teacher))]
|
||||
.sort()
|
||||
.map(teacher => `<option value="${teacher}">${teacher}</option>`)
|
||||
@@ -247,13 +160,13 @@ async function transformHomeworkPage() {
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">date_range</span>-->
|
||||
Határidő
|
||||
${LanguageManager.t('homework.due_date')}
|
||||
</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>
|
||||
<option value="">${LanguageManager.t('homework.all_deadlines')}</option>
|
||||
<option value="tomorrow">${LanguageManager.t('homework.tomorrow_deadline')}</option>
|
||||
<option value="thisWeek">${LanguageManager.t('homework.this_week')}</option>
|
||||
<option value="nextWeek">${LanguageManager.t('homework.next_week')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -268,22 +181,36 @@ async function transformHomeworkPage() {
|
||||
|
||||
setupFilters(homeworkItems, groupedHomework);
|
||||
setupUserDropdown();
|
||||
setupLogoutTimer();
|
||||
hideLoadingScreen();
|
||||
setupMobileNavigation();
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function renderHomeworkList(groupedHomework) {
|
||||
|
||||
const sortedDates = Object.keys(groupedHomework).sort((a, b) => {
|
||||
const dateA = new Date(a.replace(/\./g, ''));
|
||||
const dateB = new Date(b.replace(/\./g, ''));
|
||||
return dateA - dateB;
|
||||
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>
|
||||
<p>${LanguageManager.t('homework.no_homework')}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -294,24 +221,24 @@ function renderHomeworkList(groupedHomework) {
|
||||
<div class="homework-date-group" data-date="${date}">
|
||||
<div class="date-header">
|
||||
<h3>${formatDateHeader(date)}</h3>
|
||||
<span class="homework-count">${homeworkItems.length} ${LanguageManager.t('homework.items') || 'feladat'}</span>
|
||||
</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}">${formatDeadline(homework.deadline)}</div>
|
||||
<div class="homework-list-items">
|
||||
${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-details">
|
||||
<div class="homework-subject">${homework.subject}</div>
|
||||
<div class="homework-content">${homework.description}</div>
|
||||
<div class="homework-teacher">${homework.teacher}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="homework-content">${formatHomeworkDescription(homework.description)}</div>
|
||||
<div class="homework-footer">
|
||||
<div class="homework-teacher">${homework.teacher}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('')}
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
@@ -327,58 +254,37 @@ function formatDateHeader(dateStr) {
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const parts = dateStr.split('.');
|
||||
if (parts.length < 3) return dateStr;
|
||||
if (parts.length < 2) return dateStr;
|
||||
|
||||
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 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;
|
||||
return LanguageManager.t('common.today') + ' - ' + dateStr;
|
||||
} else if (date.toDateString() === tomorrow.toDateString()) {
|
||||
return 'Holnap - ' + dateStr;
|
||||
return LanguageManager.t('common.tomorrow') + ' - ' + dateStr;
|
||||
}
|
||||
|
||||
|
||||
const weekdays = ['Vasárnap', 'Hétfő', 'Kedd', 'Szerda', 'Csütörtök', 'Péntek', 'Szombat'];
|
||||
const weekdays = [
|
||||
LanguageManager.t('common.sunday'),
|
||||
LanguageManager.t('common.monday'),
|
||||
LanguageManager.t('common.tuesday'),
|
||||
LanguageManager.t('common.wednesday'),
|
||||
LanguageManager.t('common.thursday'),
|
||||
LanguageManager.t('common.friday'),
|
||||
LanguageManager.t('common.saturday')
|
||||
];
|
||||
return `${weekdays[date.getDay()]} - ${dateStr}`;
|
||||
}
|
||||
|
||||
function formatDeadline(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
|
||||
|
||||
if (isTomorrow(dateStr)) {
|
||||
return `Határidő: ${dateStr} (holnap!)`;
|
||||
}
|
||||
|
||||
return `Határidő: ${dateStr}`;
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
function formatHomeworkDescription(description) {
|
||||
if (!description) return '';
|
||||
|
||||
|
||||
description = description.replace(/(\d+\.)\s*(\w[^\n.]*)/g, '<strong>$1 $2</strong>');
|
||||
|
||||
|
||||
description = description.replace(/(Határidő:)\s*([^\n]+)/g, '<div class="homework-requirement"><span class="requirement-label">$1</span> $2</div>');
|
||||
description = description.replace(/(MS\s+[^\n.]+szerint\s+adható\s+be\.)/g, '<div class="homework-requirement"><span class="requirement-label">Beadás:</span> $1</div>');
|
||||
|
||||
|
||||
description = description.replace(/\n/g, '<br>');
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
function setupFilters(homeworkItems, groupedHomework) {
|
||||
const subjectFilter = document.getElementById('subjectFilter');
|
||||
const teacherFilter = document.getElementById('teacherFilter');
|
||||
@@ -437,11 +343,11 @@ function setupFilters(homeworkItems, groupedHomework) {
|
||||
|
||||
|
||||
const startOfWeek = new Date(today);
|
||||
const dayOfWeek = today.getDay() || 7; // Convert Sunday from 0 to 7
|
||||
startOfWeek.setDate(today.getDate() - dayOfWeek + 1); // Monday
|
||||
const dayOfWeek = today.getDay() || 7;
|
||||
startOfWeek.setDate(today.getDate() - dayOfWeek + 1);
|
||||
|
||||
const endOfWeek = new Date(startOfWeek);
|
||||
endOfWeek.setDate(startOfWeek.getDate() + 6); // Sunday
|
||||
endOfWeek.setDate(startOfWeek.getDate() + 6);
|
||||
|
||||
|
||||
const startOfNextWeek = new Date(endOfWeek);
|
||||
@@ -478,7 +384,7 @@ function setupFilters(homeworkItems, groupedHomework) {
|
||||
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>';
|
||||
emptyState.innerHTML = `<p>${LanguageManager.t('homework.no_matching_homework')}</p>`;
|
||||
homeworkList.appendChild(emptyState);
|
||||
}
|
||||
|
||||
@@ -519,50 +425,6 @@ function setupFilters(homeworkItems, groupedHomework) {
|
||||
deadlineFilter.addEventListener('change', applyFilters);
|
||||
}
|
||||
|
||||
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');
|
||||
});
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
userDropdown?.classList.remove('show');
|
||||
});
|
||||
|
||||
|
||||
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 setupLogoutTimer() {
|
||||
const timerElement = document.querySelector('.nav-logout-timer');
|
||||
if (!timerElement) return;
|
||||
|
||||
const timeString = timerElement.textContent;
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if (window.location.href.includes('/Tanulo/TanuloHaziFeladat')) {
|
||||
|
||||
343
i18n/en.json
Normal file
343
i18n/en.json
Normal file
@@ -0,0 +1,343 @@
|
||||
{
|
||||
"loading": {
|
||||
"text": "Loading...",
|
||||
"subtext": "Please wait!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"theme": "Theme",
|
||||
"language": "Language",
|
||||
"themes": {
|
||||
"light_blue": "Light Blue",
|
||||
"light_green": "Light Green",
|
||||
"dark_blue": "Dark Blue",
|
||||
"dark_green": "Dark Green",
|
||||
"dark_red": "Dark Red",
|
||||
"dark_purple": "Dark Purple",
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Home",
|
||||
"timetable": "Timetable",
|
||||
"grades": "Grades",
|
||||
"homework": "Homework",
|
||||
"absences": "Absences",
|
||||
"other": "Other",
|
||||
"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_evaluations": "Semester evaluations",
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"search": {
|
||||
"title": "Choose school",
|
||||
"select_institution": "Please select an institution to continue!"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Student Book",
|
||||
"student_description": "View grades, absences, timetable and other information.",
|
||||
"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.1.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 address format",
|
||||
"recaptcha_required": "Please complete the reCAPTCHA"
|
||||
}
|
||||
}
|
||||
343
i18n/hu.json
Normal file
343
i18n/hu.json
Normal file
@@ -0,0 +1,343 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"navigation": {
|
||||
"dashboard": "Kezdőlap",
|
||||
"timetable": "Órarend",
|
||||
"grades": "Jegyek",
|
||||
"homework": "Házi feladatok",
|
||||
"absences": "Mulasztások",
|
||||
"other": "Egyéb",
|
||||
"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_evaluations": "Félévi é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"
|
||||
},
|
||||
"homework": {
|
||||
"title": "Házi feladatok",
|
||||
"due_date": "Határidő",
|
||||
"subject": "Tantárgy",
|
||||
"description": "Leírás",
|
||||
"filter_title": "Szűrés",
|
||||
"all_subjects": "Összes tantárgy",
|
||||
"all_teachers": "Összes tanár",
|
||||
"all_deadlines": "Összes határidő",
|
||||
"tomorrow_deadline": "Holnapi határidő",
|
||||
"this_week": "Ezen a héten",
|
||||
"next_week": "Jövő 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": "feladat"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"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"
|
||||
},
|
||||
"search": {
|
||||
"title": "Válassz iskolát",
|
||||
"select_institution": "Kérjük, válasszon egy intézményt a folytatáshoz!"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Ellenőrzőkönyv",
|
||||
"student_description": "Jegyek, hiányzások, órarended és egyéb információk megtekintése.",
|
||||
"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.1.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"
|
||||
}
|
||||
}
|
||||
1
icons/messages.svg
Normal file
1
icons/messages.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 21a3 3 0 0 1-3-3v-3h5a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2h5v3a3 3 0 0 1-3 3H6zm15-8h-5a2 2 0 0 0-2 2h-4a2 2 0 0 0-2-2H3V6a3 3 0 0 1 3-3h12a3 3 0 0 1 3 3v7z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 327 B |
BIN
images/cactus.png
Normal file
BIN
images/cactus.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
images/chrome.png
Normal file
BIN
images/chrome.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
BIN
images/firefox.png
Normal file
BIN
images/firefox.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
@@ -1,28 +1,3 @@
|
||||
@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;
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
async function transformLoginPage() {
|
||||
try {
|
||||
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
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 || ''
|
||||
requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '',
|
||||
userName: document.querySelector('#UserName')?.value || '',
|
||||
password: document.querySelector('#Password')?.value || ''
|
||||
};
|
||||
|
||||
|
||||
const titleElement = document.querySelector('.page-title');
|
||||
const schoolInfo = {
|
||||
@@ -23,19 +22,16 @@ async function transformLoginPage() {
|
||||
kretaId: '',
|
||||
omCode: ''
|
||||
};
|
||||
|
||||
|
||||
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ó: ', '');
|
||||
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 newHTML = `
|
||||
<div class="login-container">
|
||||
@@ -48,7 +44,7 @@ async function transformLoginPage() {
|
||||
<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.omCode ? `<div>${LanguageManager.t('login.kreta_id')}: ${schoolInfo.omCode}</div>` : ''}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -61,27 +57,27 @@ 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>
|
||||
<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>
|
||||
<button type="button" class="show-password" aria-label="Jelszó mutatása">
|
||||
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>
|
||||
@@ -89,21 +85,19 @@ async function transformLoginPage() {
|
||||
|
||||
${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();
|
||||
|
||||
@@ -117,7 +111,6 @@ function setupEventListeners() {
|
||||
const passwordInput = document.getElementById('Password');
|
||||
const togglePasswordBtn = document.querySelector('.show-password');
|
||||
const formInputs = document.querySelectorAll('.form-control');
|
||||
|
||||
|
||||
if (togglePasswordBtn && passwordInput) {
|
||||
togglePasswordBtn.addEventListener('click', () => {
|
||||
@@ -175,11 +168,6 @@ function handleSubmit(event) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const submitButton = form.querySelector('.btn-login');
|
||||
const spinner = submitButton.querySelector('.spinner');
|
||||
|
||||
301
login/twofactor.css
Normal file
301
login/twofactor.css
Normal file
@@ -0,0 +1,301 @@
|
||||
:root {
|
||||
--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;
|
||||
}
|
||||
|
||||
: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;
|
||||
}
|
||||
|
||||
* {
|
||||
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;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
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);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.twofactor-form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
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;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.password-group {
|
||||
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;
|
||||
}
|
||||
|
||||
.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));
|
||||
}
|
||||
|
||||
.show-password:hover .icon-eye {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
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;
|
||||
}
|
||||
|
||||
.form-check-input:checked {
|
||||
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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
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;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
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;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
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;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
border: 1px solid var(--error-accent) !important;
|
||||
}
|
||||
|
||||
/* Hide original elements */
|
||||
header, main > .container-fluid, footer {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
.login-container {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
171
login/twofactor.js
Normal file
171
login/twofactor.js
Normal file
@@ -0,0 +1,171 @@
|
||||
async function transformTwoFactorPage() {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.show();
|
||||
}
|
||||
|
||||
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'
|
||||
};
|
||||
|
||||
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">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="twofactor-title">${LanguageManager.t('twofactor.title')}</h1>
|
||||
</div>
|
||||
|
||||
<form class="twofactor-form" action="${formData.action}" method="post" id="twoFactorForm">
|
||||
<input type="hidden" id="ClientId" name="ClientId" value="${formData.clientId}">
|
||||
<input type="hidden" id="RememberLogin" name="RememberLogin" value="${formData.rememberLogin}">
|
||||
<input type="hidden" id="ReturnUrl" name="ReturnUrl" value="${formData.returnUrl}">
|
||||
<input type="hidden" id="IsRecoveryCode" name="IsRecoveryCode" value="${formData.isRecoveryCode}">
|
||||
<input name="__RequestVerificationToken" type="hidden" value="${formData.requestToken}">
|
||||
|
||||
<div class="form-group password-group">
|
||||
<input class="form-control" type="password" id="VerificationCode" name="VerificationCode"
|
||||
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">${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">
|
||||
${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">${LanguageManager.t('twofactor.verify_button')}</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mt-3">
|
||||
<span class="subtext">
|
||||
${LanguageManager.t('twofactor.no_access')}
|
||||
<button type="submit" class="btn-link" formaction="/account/loginwithrecoverycode">
|
||||
${LanguageManager.t('twofactor.recovery_code')}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<footer class="login-footer">
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">${LanguageManager.t('login.privacy_policy')}</a>
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.innerHTML = newHTML;
|
||||
applyTheme();
|
||||
setupEventListeners();
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error transforming two-factor page:', error);
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyTheme() {
|
||||
try {
|
||||
if (typeof getCookie === 'function') {
|
||||
const theme = getCookie('theme') || 'light-blue';
|
||||
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');
|
||||
|
||||
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`);
|
||||
});
|
||||
}
|
||||
formInputs.forEach(input => {
|
||||
input.addEventListener('input', () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
if (twoFactorForm) {
|
||||
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');
|
||||
} else {
|
||||
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]');
|
||||
let isValid = true;
|
||||
inputs.forEach(input => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
if (isValid) {
|
||||
const submitButton = form.querySelector('.btn-kreta');
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
submitButton.innerHTML = `<span class="spinner"></span><span class="btn-text">${LanguageManager.t('twofactor.verifying')}</span>`;
|
||||
}
|
||||
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
transformTwoFactorPage();
|
||||
@@ -1,21 +1,4 @@
|
||||
(() => {
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function loadFonts() {
|
||||
// Create a new style element
|
||||
const style = document.createElement('style');
|
||||
@@ -27,8 +10,8 @@
|
||||
}
|
||||
function transformLogoutPage() {
|
||||
// Get current theme and school ID from cookies
|
||||
const theme = getCookie('themePreference') || localStorage.getItem('themePreference') || 'light-blue';
|
||||
const instituteCode = getCookie('schoolSubdomain');
|
||||
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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.3",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -12,80 +12,75 @@
|
||||
"128": "images/firka_logo_128.png"
|
||||
}
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "firxa@zan1456.hu",
|
||||
"strict_min_version": "58.0"
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [{
|
||||
"resources": [
|
||||
"settings/*",
|
||||
"global/language.js",
|
||||
"images/*",
|
||||
"fonts/*.woff2",
|
||||
"icons/*.svg",
|
||||
"grades/chart.js"
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/cookieManager.js"
|
||||
],
|
||||
"matches": ["https://*.e-kreta.hu/*"]
|
||||
"matches": ["<all_urls>"]
|
||||
}],
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/*"
|
||||
],
|
||||
"js": ["global/maintenance.js", "global/theme.js", "global/navigation.js"],
|
||||
"css": ["global/theme.css", "global/navigation.css"],
|
||||
"matches": ["https://*.e-kreta.hu/*"],
|
||||
"js": ["tools/loadingScreen.js, tools/cookieManager.js", "tools/helper.js", "tools/createTemplate.js",
|
||||
"global/language.js", "global/maintenance.js", "global/theme.js", "global/navigation.js"],
|
||||
"css": ["tools/loadingScreen.css", "global/theme.css", "global/navigation.css", "global/maintenance.css"],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/*"
|
||||
],
|
||||
"css": ["global/maintenance.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/Account/Login*"],
|
||||
"js": ["login/login.js"],
|
||||
"css": ["login/login.css"]
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Hianyzas/Hianyzasok*"
|
||||
],
|
||||
"matches": ["https://idp.e-kreta.hu/account/loginwithtwofactor*"],
|
||||
"js": ["login/twofactor.js"],
|
||||
"css": ["login/twofactor.css"]
|
||||
},
|
||||
{
|
||||
"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*"
|
||||
],
|
||||
"matches": ["https://idp.e-kreta.hu/Account/Logout*"],
|
||||
"js": ["logout/logout.js"],
|
||||
"css": ["logout/logout.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*"
|
||||
],
|
||||
"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*"
|
||||
],
|
||||
"matches": ["https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"],
|
||||
"js": ["forgotpassword/forgotpassword.js"],
|
||||
"css": ["forgotpassword/forgotpassword.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*"
|
||||
],
|
||||
"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*"
|
||||
"matches": [ "https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*"
|
||||
],
|
||||
"js": ["grades/grades.js", "grades/chart.js"],
|
||||
"css": ["grades/grades.css"],
|
||||
@@ -114,6 +109,14 @@
|
||||
"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"],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -59,37 +59,6 @@ body {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.nav-links a.active {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
@@ -115,19 +84,6 @@ body {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.user-time {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@@ -426,10 +382,10 @@ body {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school user"
|
||||
"nav nav";
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@@ -438,12 +394,6 @@ body {
|
||||
grid-area: school;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
grid-area: nav;
|
||||
margin-top: 0.5rem;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,4 @@
|
||||
(() => {
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function shortenSchoolName(name) {
|
||||
if (!name) return '';
|
||||
const maxLength = 30;
|
||||
if (name.length <= maxLength) return name;
|
||||
|
||||
const parts = name.split(' - ');
|
||||
if (parts.length === 2) {
|
||||
const [code, fullName] = parts;
|
||||
return `${code} - ${fullName.substring(0, maxLength - code.length - 5)}...`;
|
||||
}
|
||||
return name.substring(0, maxLength - 3) + '...';
|
||||
}
|
||||
|
||||
(() => {
|
||||
function createSecurityTab() {
|
||||
return `
|
||||
<div class="security-content">
|
||||
@@ -196,25 +166,25 @@
|
||||
const saveButton = form.querySelector('#saveContacts');
|
||||
|
||||
|
||||
emailInput.value = getCookie('userEmail') || '';
|
||||
phoneInput.value = getCookie('userPhone') || '';
|
||||
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ő!');
|
||||
alert(LanguageManager.t('profile.email_required'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (email && !isValidEmail(email)) {
|
||||
alert('Kérjük, adjon meg egy érvényes e-mail címet!');
|
||||
alert(LanguageManager.t('profile.invalid_email'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (phone && !isValidPhone(phone)) {
|
||||
alert('Kérjük, adjon meg egy érvényes telefonszámot!');
|
||||
alert(LanguageManager.t('profile.invalid_phone'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -229,13 +199,13 @@
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Elérhetőségek sikeresen mentve!');
|
||||
alert(LanguageManager.t('profile.contacts_saved'));
|
||||
} else {
|
||||
throw new Error('Hiba történt a mentés során.');
|
||||
throw new Error(LanguageManager.t('profile.contacts_save_error'));
|
||||
}
|
||||
} 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.');
|
||||
alert(LanguageManager.t('profile.save_error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -289,13 +259,13 @@
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Beállítások sikeresen mentve! A változtatások érvényesítéséhez jelentkezzen be újra.');
|
||||
alert(LanguageManager.t('profile.settings_saved'));
|
||||
} else {
|
||||
throw new Error('Hiba történt a mentés során.');
|
||||
throw new Error(LanguageManager.t('profile.settings_save_error'));
|
||||
}
|
||||
} 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.');
|
||||
alert(LanguageManager.t('profile.save_error'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -306,17 +276,17 @@
|
||||
const confirmPassword = document.getElementById('confirmPassword').value;
|
||||
|
||||
if (!currentPassword || !newPassword || !confirmPassword) {
|
||||
alert('Kérjük, töltse ki az összes mezőt!');
|
||||
alert(LanguageManager.t('profile.fill_all_fields'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
alert('Az új jelszavak nem egyeznek!');
|
||||
alert(LanguageManager.t('profile.passwords_not_match'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length < 8) {
|
||||
alert('Az új jelszónak legalább 8 karakter hosszúnak kell lennie!');
|
||||
alert(LanguageManager.t('profile.password_min_length'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -335,16 +305,16 @@
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert('Jelszó sikeresen módosítva!');
|
||||
alert(LanguageManager.t('profile.password_changed'));
|
||||
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.');
|
||||
throw new Error(LanguageManager.t('profile.password_change_error'));
|
||||
}
|
||||
} 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.');
|
||||
alert(LanguageManager.t('profile.password_change_error'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -371,67 +341,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
function createProfileHTML(data) {
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = shortenSchoolName(schoolNameFull);
|
||||
|
||||
function createProfileHTML() {
|
||||
return `
|
||||
<div class="kreta-container">
|
||||
<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">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
${shortenedSchoolName}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag">
|
||||
<span class="material-icons-round">calendar_today</span>
|
||||
Kezdőlap
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok">
|
||||
<span class="material-icons-round">bookmark_border</span>
|
||||
Jegyek
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend">
|
||||
<span class="material-icons-round">home</span>
|
||||
Órarend
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok">
|
||||
<span class="material-icons-round">schedule</span>
|
||||
Hiányok
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="user-profile">
|
||||
<button class="user-dropdown-btn">
|
||||
<div class="user-info">
|
||||
<span class="user-name">${data.userData.name}</span>
|
||||
<span class="user-time" id="logoutTimer">${data.userData.time}</span>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="/Adminisztracio/Profil" class="dropdown-item">
|
||||
<span class="material-icons-round">person</span>
|
||||
Profil
|
||||
</a>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<span class="material-icons-round">settings</span>
|
||||
Beállítások
|
||||
</a>
|
||||
<a href="/Home/Logout" class="dropdown-item">
|
||||
<span class="material-icons-round">logout</span>
|
||||
Kijelentkezés
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="card">
|
||||
@@ -469,34 +382,11 @@
|
||||
async function init() {
|
||||
if (window.location.pathname.includes('/Adminisztracio/Profil')) {
|
||||
|
||||
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' }
|
||||
];
|
||||
createTemplate.importFonts();
|
||||
|
||||
links.forEach(link => {
|
||||
const linkElement = document.createElement('link');
|
||||
Object.entries(link).forEach(([key, value]) => {
|
||||
linkElement[key] = value;
|
||||
});
|
||||
document.head.appendChild(linkElement);
|
||||
});
|
||||
|
||||
const userData = {
|
||||
schoolInfo: {
|
||||
name: getCookie('schoolName') || 'Iskola',
|
||||
id: getCookie('schoolCode') || ''
|
||||
},
|
||||
userData: {
|
||||
name: getCookie('userName') || 'Felhasználó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00',
|
||||
email: getCookie('userEmail') || ''
|
||||
}
|
||||
};
|
||||
|
||||
document.body.innerHTML = createProfileHTML(userData);
|
||||
document.body.innerHTML = createProfileHTML();
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
setupEventListeners();
|
||||
setupContactForm();
|
||||
}
|
||||
|
||||
@@ -1,29 +1,3 @@
|
||||
@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;
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
(() => {
|
||||
|
||||
const setCookie = (name, value, days = 365) => {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/; domain=.e-kreta.hu`;
|
||||
};
|
||||
|
||||
const startLogoutTimer = () => {
|
||||
let timeLeft = 45 * 60;
|
||||
const timerElement = document.getElementById('logoutTimer');
|
||||
@@ -41,7 +34,7 @@
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error changing role:', error);
|
||||
alert('Hiba történt a szerepkör váltása közben.');
|
||||
alert(LanguageManager.t('roleselect.role_change_error'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -73,8 +66,8 @@
|
||||
<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>
|
||||
@@ -85,8 +78,8 @@
|
||||
<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>
|
||||
|
||||
@@ -95,8 +88,8 @@
|
||||
<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>
|
||||
@@ -120,34 +113,22 @@
|
||||
const schoolSubdomain = window.location.hostname.split('.')[0];
|
||||
|
||||
const userNameEl = document.querySelector('.UserName');
|
||||
const userName = userNameEl?.textContent.trim() || 'Felhasználónév';
|
||||
const userName = userNameEl?.textContent.trim() || LanguageManager.t('common.username');
|
||||
|
||||
|
||||
if (schoolCode && fullSchoolName) {
|
||||
setCookie('schoolCode', schoolCode);
|
||||
setCookie('schoolName', fullSchoolName);
|
||||
setCookie('schoolSubdomain', schoolSubdomain);
|
||||
cookieManager.set('schoolCode', schoolCode);
|
||||
cookieManager.set('schoolName', fullSchoolName);
|
||||
cookieManager.set('schoolSubdomain', schoolSubdomain);
|
||||
}
|
||||
if (userName) {
|
||||
setCookie('userName', userName);
|
||||
cookieManager.set('userName', userName);
|
||||
}
|
||||
|
||||
|
||||
document.body.innerHTML = createHTML(schoolCode, fullSchoolName, userName);
|
||||
|
||||
|
||||
const links = [
|
||||
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
|
||||
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
|
||||
{ href: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&family=Figtree:wght@300..900&display=swap', rel: 'stylesheet' }
|
||||
];
|
||||
|
||||
links.forEach(link => {
|
||||
const linkElement = document.createElement('link');
|
||||
Object.entries(link).forEach(([key, value]) => linkElement[key] = value);
|
||||
document.head.appendChild(linkElement);
|
||||
});
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
const timerInterval = startLogoutTimer();
|
||||
|
||||
|
||||
222
search/search.css
Normal file
222
search/search.css
Normal file
@@ -0,0 +1,222 @@
|
||||
/* Hide original elements */
|
||||
header, footer, .page-title, .card-kreta {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
* {
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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%);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.logo {
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Form styling */
|
||||
form {
|
||||
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;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
li.dropdown-item:hover, li.dropdown-item:focus {
|
||||
background-color: var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
a.dropdown-item:hover, a.dropdown-item:focus {
|
||||
background-color: #00000000 !important;
|
||||
}
|
||||
|
||||
.dropdown-item.active {
|
||||
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;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
background-color: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:active {
|
||||
transform: translateY(1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:disabled {
|
||||
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%;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
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;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
.firka-search-wrapper {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.btn-kreta {
|
||||
padding: 10px 20px !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
}
|
||||
124
search/search.js
Normal file
124
search/search.js
Normal file
@@ -0,0 +1,124 @@
|
||||
function initializeTransformation() {
|
||||
const form = document.querySelector('form');
|
||||
const autocomplete = document.querySelector('.autocomplete');
|
||||
|
||||
if (form && autocomplete) {
|
||||
applyFirkaStyling();
|
||||
} else {
|
||||
setTimeout(initializeTransformation, 500);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
});
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
}
|
||||
|
||||
function applyFirkaStyling() {
|
||||
try {
|
||||
const theme = cookieManager.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');
|
||||
if (existingWrapper) {
|
||||
existingWrapper.remove();
|
||||
}
|
||||
searchWrapper.appendChild(firkaHeader);
|
||||
if (originalForm) {
|
||||
formContainer.appendChild(originalForm);
|
||||
searchWrapper.appendChild(formContainer);
|
||||
}
|
||||
searchWrapper.appendChild(firkaFooter);
|
||||
document.body.appendChild(searchWrapper);
|
||||
setupAutocompleteListeners();
|
||||
if (redirectButton) {
|
||||
redirectButton.addEventListener('click', function(event) {
|
||||
if (!instituteCodeInput.value) {
|
||||
event.preventDefault();
|
||||
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');
|
||||
|
||||
if (autocompleteInput && autocompleteValue) {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
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', () => {
|
||||
if (redirectButton) {
|
||||
redirectButton.disabled = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function observeAutocompleteValue(valueInput, button) {
|
||||
if (!valueInput || !button) return;
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
button.disabled = !valueInput.value;
|
||||
});
|
||||
|
||||
observer.observe(valueInput, {
|
||||
attributes: true,
|
||||
attributeFilter: ['value']
|
||||
});
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
if (valueInput.value) {
|
||||
button.disabled = false;
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
@@ -88,12 +88,14 @@ h2 {
|
||||
}
|
||||
|
||||
|
||||
.theme-grid {
|
||||
.theme-grid,
|
||||
.language-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
}
|
||||
.theme-option {
|
||||
.theme-option,
|
||||
.language-option {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
@@ -104,13 +106,18 @@ h2 {
|
||||
gap: 8px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
.theme-option:hover {
|
||||
.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;
|
||||
@@ -135,6 +142,31 @@ h2 {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
.theme-preview.light-blue {
|
||||
background: #DAE4F7;
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Firxa Beállítások</title>
|
||||
<title>Firxa - Beállítások</title>
|
||||
<link rel="icon" type="image/png" href="../images/firka_logo_128.png">
|
||||
<link rel="shortcut icon" type="image/png" href="../images/firka_logo_128.png">
|
||||
<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">
|
||||
@@ -21,12 +23,12 @@
|
||||
</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">
|
||||
@@ -36,7 +38,7 @@
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">Világos Kék</span>
|
||||
<span class="theme-name" data-i18n="settings.themes.light_blue">Világos Kék</span>
|
||||
</button>
|
||||
<button class="theme-option" data-theme="light-green">
|
||||
<div class="theme-preview light-green">
|
||||
@@ -45,7 +47,7 @@
|
||||
<div class="preview-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="theme-name">Világos Zöld</span>
|
||||
<span class="theme-name" data-i18n="settings.themes.light_green">Világos Zöld</span>
|
||||
</button>
|
||||
<button class="theme-option" data-theme="dark-blue">
|
||||
<div class="theme-preview dark-blue">
|
||||
@@ -54,7 +56,7 @@
|
||||
<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.dark_blue">Sötét Kék</span>
|
||||
</button>
|
||||
<button class="theme-option" data-theme="dark-green">
|
||||
<div class="theme-preview dark-green">
|
||||
@@ -63,7 +65,22 @@
|
||||
<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">
|
||||
<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>
|
||||
@@ -71,24 +88,24 @@
|
||||
</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>
|
||||
<p data-i18n="settings.about.description">A Firka egy nyílt forráskódú projekt, amely a KRÉTA rendszerhez készít saját felhasználói felületet.</p>
|
||||
<a href="https://github.com/QwIT-Development/" target="_blank" class="github-link">
|
||||
<span class="material-icons-round">code</span>
|
||||
GitHub
|
||||
<span data-i18n="settings.about.github">GitHub</span>
|
||||
</a>
|
||||
</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>
|
||||
@@ -98,6 +115,8 @@
|
||||
<div class="version-info" id="version">v1.1.0</div>
|
||||
</footer>
|
||||
</div>
|
||||
<script src="index.js"></script>
|
||||
<script src="../tools/cookieManager.js"></script>
|
||||
<script src="../global/language.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,4 +1,28 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
while (typeof window.LanguageManager === 'undefined') {
|
||||
await new Promise(resolve => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
function isThemeDisabled(theme) {
|
||||
const blueThemesUnlocked = localStorage.getItem('blueThemesUnlocked') === 'true';
|
||||
return (theme === 'default' || theme === 'light-blue' || theme === 'dark-blue') && !blueThemesUnlocked;
|
||||
}
|
||||
|
||||
function updateThemeAvailability() {
|
||||
const blueThemesUnlocked = localStorage.getItem('blueThemesUnlocked') === 'true';
|
||||
document.querySelectorAll('.theme-option').forEach(button => {
|
||||
const theme = button.dataset.theme;
|
||||
if (theme === 'default' || theme === 'light-blue' || theme === 'dark-blue') {
|
||||
if (blueThemesUnlocked) {
|
||||
button.style.display = 'block';
|
||||
button.classList.remove('disabled');
|
||||
button.removeAttribute('disabled');
|
||||
} else {
|
||||
button.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
@@ -25,43 +49,50 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
}
|
||||
|
||||
async function getCurrentTheme() {
|
||||
try {
|
||||
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
|
||||
const response = await chrome.tabs.sendMessage(tab.id, { action: 'getTheme' });
|
||||
return response.theme;
|
||||
} catch (error) {
|
||||
console.error('Error getting current theme:', error);
|
||||
return 'default';
|
||||
}
|
||||
function getCurrentTheme() {
|
||||
return localStorage.getItem('themePreference') ||
|
||||
getCookie('themePreference') ||
|
||||
'light-green';
|
||||
}
|
||||
|
||||
function updateThemeButtons(currentTheme) {
|
||||
document.querySelectorAll('.theme-option').forEach(button => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle('active', theme === currentTheme);
|
||||
|
||||
|
||||
/*if (theme === 'light-blue' || theme === 'dark-blue' || theme === 'default') {
|
||||
button.classList.add('disabled');
|
||||
button.setAttribute('disabled', 'true');
|
||||
}*/
|
||||
});
|
||||
updateThemeAvailability();
|
||||
}
|
||||
|
||||
function getCurrentLanguage() {
|
||||
return localStorage.getItem('languagePreference') ||
|
||||
getCookie('languagePreference') ||
|
||||
'hu';
|
||||
}
|
||||
|
||||
function updateLanguageButtons(currentLanguage) {
|
||||
document.querySelectorAll('.language-option').forEach(button => {
|
||||
const language = button.dataset.language;
|
||||
button.classList.toggle('active', language === currentLanguage);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function isThemeDisabled(theme) {
|
||||
return theme === 'default' || theme === 'dark-blue';
|
||||
async function applyLanguage(language) {
|
||||
setCookie('languagePreference', 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) {
|
||||
|
||||
if (isThemeDisabled(theme)) {
|
||||
alert('Ez a téma jelenleg nem elérhető.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
setCookie('themePreference', theme);
|
||||
localStorage.setItem('themePreference', theme);
|
||||
|
||||
@@ -78,8 +109,6 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
action: 'changeTheme',
|
||||
theme: theme
|
||||
}).catch(() => {
|
||||
|
||||
console.log('Tab not ready for theme change:', tab.id);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -92,7 +121,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
|
||||
|
||||
if (button.hasAttribute('disabled')) {
|
||||
alert('Ez a téma jelenleg nem elérhető.');
|
||||
alert(window.LanguageManager.t('common.warning') + ': ' + window.LanguageManager.t('settings.theme_not_available'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,11 +129,16 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
const languageButtons = document.querySelectorAll('.language-option');
|
||||
languageButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const language = button.dataset.language;
|
||||
applyLanguage(language);
|
||||
});
|
||||
});
|
||||
|
||||
let initialTheme = localStorage.getItem('themePreference') ||
|
||||
getCookie('themePreference') ||
|
||||
await getCurrentTheme() ||
|
||||
'light-green';
|
||||
|
||||
let initialTheme = getCurrentTheme();
|
||||
|
||||
|
||||
if (isThemeDisabled(initialTheme)) {
|
||||
@@ -112,8 +146,12 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
}
|
||||
|
||||
|
||||
updateThemeAvailability();
|
||||
await applyTheme(initialTheme);
|
||||
|
||||
const initialLanguage = getCurrentLanguage();
|
||||
updateLanguageButtons(initialLanguage);
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'themeChanged') {
|
||||
@@ -124,7 +162,56 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
|
||||
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
document.getElementById('version').textContent = `v${manifest.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 = window.LanguageManager.t('common.success') + ': ' + window.LanguageManager.t('settings.blue_themes_unlocked');
|
||||
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@keyframes slideIn {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
style.remove();
|
||||
}, 3000);
|
||||
|
||||
clickCount = 0;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
themeButtons.forEach(button => {
|
||||
@@ -138,4 +225,18 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
button.style.transform = 'translateY(0)';
|
||||
});
|
||||
});
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
@@ -1,32 +1,3 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtr6Hw5aXp-p7K4KLg.woff2) format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCtZ6Hw5aXp-p7K4KLg.woff2) format('woff2');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url(https://fonts.gstatic.com/s/montserrat/v25/JTUHjIg1_i6t8kCHKm4532VJOt5-QNFgpCu173w5aXp-p7K4KLg.woff2) format('woff2');
|
||||
}
|
||||
|
||||
@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;
|
||||
@@ -43,57 +14,6 @@ body {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* Loading Screen */
|
||||
.loading-screen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: var(--background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
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;
|
||||
}
|
||||
|
||||
.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%;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
@@ -106,7 +26,6 @@ body {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Update header styles to match dashboard */
|
||||
.kreta-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
@@ -123,10 +42,10 @@ body {
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school user"
|
||||
"nav nav";
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
@@ -191,82 +110,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Updated navigation styles */
|
||||
.kreta-nav {
|
||||
padding: 0 clamp(0.5rem, 3vw, 1.5rem);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links {
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.nav-links a {
|
||||
padding: 0.5rem;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.nav-links a .material-icons-round {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-links a:hover {
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
.nav-links a.active {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
/* User profile styles */
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
@@ -298,19 +141,6 @@ body {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.user-time {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
@@ -343,7 +173,6 @@ body {
|
||||
background: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
/* Main content styles */
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
@@ -352,7 +181,10 @@ body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Card styles */
|
||||
.k-overlay, .k-widget.k-window {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
@@ -360,7 +192,6 @@ body {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
/* Timetable specific styles */
|
||||
.timetable-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 80px repeat(5, 1fr);
|
||||
@@ -419,10 +250,8 @@ body {
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.lesson-slot:hover {
|
||||
transform: scale(1.02);
|
||||
display: grid;
|
||||
grid-gap: 16px;
|
||||
}
|
||||
|
||||
.lesson-card {
|
||||
@@ -516,8 +345,8 @@ body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 50%;
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
@@ -534,29 +363,57 @@ body {
|
||||
}
|
||||
|
||||
.lesson-indicator .material-icons-round {
|
||||
font-size: 14px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* Week selector styling */
|
||||
.week-controls {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 16px;
|
||||
justify-content: center;
|
||||
margin: 16px auto;
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
max-width: 400px;
|
||||
max-width: 800px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.week-select {
|
||||
flex: 1;
|
||||
padding: 12px;
|
||||
.week-selector-container {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.expand-week-view-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.expand-week-view-btn:hover {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.expand-week-view-btn .material-icons-round {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.week-selector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.week-nav-btn {
|
||||
@@ -566,19 +423,338 @@ body {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-secondary);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.week-nav-btn:hover {
|
||||
.week-nav-btn:hover:not(:disabled) {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.week-nav-btn .material-icons-round {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.week-display {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.week-cell {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 60px;
|
||||
height: 50px;
|
||||
border: 2px solid var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.week-cell:hover {
|
||||
background: var(--accent-15);
|
||||
border-color: var(--accent-accent);
|
||||
color: var(--accent-accent);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.week-cell.selected {
|
||||
background: var(--accent-accent);
|
||||
border-color: var(--accent-accent);
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.week-cell.selected:hover {
|
||||
background: var(--accent-accent);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.week-cell.current-week {
|
||||
border-color: var(--accent-accent);
|
||||
box-shadow: 0 0 0 1px var(--accent-accent);
|
||||
}
|
||||
|
||||
.week-cell.current-week.selected {
|
||||
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.week-number {
|
||||
font-size: 14px;
|
||||
font-weight: inherit;
|
||||
}
|
||||
|
||||
.current-indicator {
|
||||
font-size: 8px;
|
||||
color: var(--accent-accent);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.week-cell.selected .current-indicator {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.week-tooltip {
|
||||
position: absolute;
|
||||
background: var(--card-card);
|
||||
border: 1px solid var(--border-border);
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s ease;
|
||||
z-index: 1000;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.week-tooltip.show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.week-modal {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.week-modal-content {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
max-width: 1000px;
|
||||
max-height: 70vh;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.week-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px 24px;
|
||||
border-bottom: 1px solid var(--border-border);
|
||||
}
|
||||
|
||||
.week-modal-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, 1fr);
|
||||
gap: 8px;
|
||||
padding: 20px;
|
||||
max-height: calc(70vh - 80px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.modal-week-cell {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.week-modal-content {
|
||||
max-width: 95vw;
|
||||
max-height: 80vh;
|
||||
}
|
||||
|
||||
.week-modal-grid {
|
||||
grid-template-columns: repeat(10, 1fr);
|
||||
gap: 6px;
|
||||
padding: 16px;
|
||||
max-height: calc(80vh - 80px);
|
||||
}
|
||||
|
||||
.modal-week-cell {
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
.week-modal-header h3 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.week-modal-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.week-modal-close:hover {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
.week-modal-close .material-icons-round {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.week-modal-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(13, 1fr);
|
||||
gap: 8px;
|
||||
padding: 24px;
|
||||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.week-modal-grid .week-cell {
|
||||
width: 60px;
|
||||
height: 50px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.week-modal-grid {
|
||||
grid-template-columns: repeat(10, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.week-modal-grid {
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.week-modal-grid .week-cell {
|
||||
width: 50px;
|
||||
height: 45px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.week-modal-content {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.week-modal-header {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
.week-modal-grid {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.week-grid {
|
||||
grid-template-columns: repeat(10, 1fr);
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.week-cell {
|
||||
width: 40px;
|
||||
height: 35px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.week-controls {
|
||||
max-width: 600px;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.week-grid {
|
||||
grid-template-columns: repeat(8, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.week-cell {
|
||||
width: 35px;
|
||||
height: 30px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.week-controls {
|
||||
max-width: 400px;
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.day-navigation {
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1rem;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.day-nav-btn {
|
||||
background: var(--card-card);
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.day-nav-btn:hover {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.current-day-info {
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.current-day-name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.current-day-date {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.timetable-grid {
|
||||
grid-template-columns: 60px repeat(5, minmax(200px, 1fr));
|
||||
@@ -590,9 +766,33 @@ body {
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.day-navigation {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.timetable-container {
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.timetable-grid {
|
||||
grid-template-columns: 60px 1fr;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.grid-header:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.grid-header.active {
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.lesson-slot {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lesson-slot.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.lesson-card {
|
||||
@@ -609,7 +809,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Modal styles */
|
||||
.lesson-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
@@ -627,7 +826,7 @@ body {
|
||||
}
|
||||
|
||||
.lesson-modal.show {
|
||||
display: flex;
|
||||
display: flex !important;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -736,7 +935,14 @@ body {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
/* Animations */
|
||||
.detail-item .line-through {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.detail-item.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -770,7 +976,6 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
flex-direction: column;
|
||||
@@ -781,28 +986,11 @@ body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
justify-content: start;
|
||||
overflow-x: auto;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-links::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.lesson-cell {
|
||||
min-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
/* Material Icons */
|
||||
.material-icons-round {
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Scrollbar styling */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
@@ -819,4 +1007,85 @@ body {
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
}
|
||||
|
||||
.grid-header.special-day {
|
||||
background: linear-gradient(135deg, #F99F50, #FF8C42);
|
||||
color: white;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.special-day-indicator {
|
||||
display: block;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 500;
|
||||
margin-top: 2px;
|
||||
opacity: 0.9;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.special-day-card {
|
||||
background: #F99F50;
|
||||
color: white;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
margin: 4px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.special-day-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.special-day-title {
|
||||
font-weight: 600;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.special-day-subtitle {
|
||||
font-size: 0.9rem;
|
||||
opacity: 0.9;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.week-select {
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.special-day-indicator {
|
||||
font-size: 0.6rem;
|
||||
}
|
||||
|
||||
.special-day-card {
|
||||
padding: 8px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.special-day-title {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.special-day-subtitle {
|
||||
font-size: 0.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
color: var(--accent-accent);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
padding-top: 16px;
|
||||
transition: gap 0.2s ease;
|
||||
font-size: clamp(0.875rem, 1.5vw, 1rem);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
25
tools/cookieManager.js
Normal file
25
tools/cookieManager.js
Normal file
@@ -0,0 +1,25 @@
|
||||
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`;
|
||||
}
|
||||
}
|
||||
140
tools/createTemplate.js
Normal file
140
tools/createTemplate.js
Normal file
@@ -0,0 +1,140 @@
|
||||
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') || ''
|
||||
}
|
||||
};
|
||||
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = helper.shortenSchoolName(schoolNameFull);
|
||||
|
||||
|
||||
|
||||
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">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
${shortenedSchoolName}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
</button>
|
||||
|
||||
<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="${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="${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="${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="${LanguageManager.t('navigation.absences')}">
|
||||
${LanguageManager.t('navigation.absences')}
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item ${( location.pathname == '/Tanulo/TanuloHaziFeladat' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/others.svg')}" alt="${LanguageManager.t('navigation.other')}">
|
||||
${LanguageManager.t('navigation.other')}
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="user-profile">
|
||||
<button class="user-dropdown-btn">
|
||||
<div class="user-info">
|
||||
<span class="user-name">${data.userData.name}</span>
|
||||
<span class="nav-logout-timer" id="logoutTimer">${data.userData.time}</span>
|
||||
</div>
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="https://bmszc-puskas.e-kreta.hu/Home/Uzenetek" data-page="messages" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL('icons/messages.svg')}" alt="${LanguageManager.t('navigation.messages')}">
|
||||
${LanguageManager.t('navigation.messages')}
|
||||
</a>
|
||||
<a href="/Adminisztracio/Profil" data-page="profile" class="dropdown-item">
|
||||
<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="${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="${LanguageManager.t('navigation.logout')}">
|
||||
${LanguageManager.t('navigation.logout')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</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--;
|
||||
}
|
||||
};
|
||||
|
||||
setInterval(updateTimer, 1000);
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
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/css2?family=Figtree:ital,wght@0,300..900;1,300..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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
40
tools/helper.js
Normal file
40
tools/helper.js
Normal file
@@ -0,0 +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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
59
tools/loadingScreen.css
Normal file
59
tools/loadingScreen.css
Normal file
@@ -0,0 +1,59 @@
|
||||
.modalBckgroundMain {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
body:not(.loaded) {
|
||||
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;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
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;
|
||||
}
|
||||
|
||||
.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%;
|
||||
}
|
||||
53
tools/loadingScreen.js
Normal file
53
tools/loadingScreen.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const loadingScreen = {
|
||||
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" data-i18n="loading.text">Betöltés alatt...</div>
|
||||
<div class="loading-text2" data-i18n="loading.subtext">Kis türelmet!</div>
|
||||
</div>
|
||||
`;
|
||||
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';
|
||||
|
||||
const removeLoadingScreen = () => {
|
||||
if (loadingScreen && loadingScreen.parentNode) {
|
||||
loadingScreen.remove();
|
||||
}
|
||||
};
|
||||
|
||||
loadingScreen.addEventListener('transitionend', removeLoadingScreen, { once: true });
|
||||
setTimeout(removeLoadingScreen, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (urls.some(url => url.includes(location.pathname))) {
|
||||
loadingScreen.show();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user