Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6a5ecadbdc | ||
|
|
1bdc8b5692 | ||
|
|
aea3b20ff9 | ||
|
|
ee42a064d2 | ||
|
|
89296804be | ||
|
|
29566f4fae | ||
|
|
93c9c2d307 | ||
|
|
a94c06d893 | ||
|
|
7cd8c065b3 | ||
|
|
d44be3b029 | ||
|
|
3243ebdc2e | ||
|
|
0f69a1583b | ||
|
|
15ab433064 | ||
|
|
4aab9afebd | ||
|
|
e0df578dca | ||
|
|
dd320d3dc4 | ||
|
|
5248cfc12e | ||
|
|
1f34cacf25 | ||
|
|
f35d29f56c | ||
|
|
1429943dbe | ||
|
|
2ca1c9949a |
119
.github/workflows/build.yml
vendored
@@ -1,71 +1,82 @@
|
||||
name: Package and Release Extension
|
||||
name: Build and Release
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches:
|
||||
- test
|
||||
inputs:
|
||||
version:
|
||||
description: 'Release version (pl. v1.0.0)'
|
||||
required: true
|
||||
default: 'v1.0.0'
|
||||
|
||||
jobs:
|
||||
build-and-release:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get current date
|
||||
id: date
|
||||
- name: Set up build directories
|
||||
run: |
|
||||
echo "DATE=$(date +'%Y.%m.%d. %H:%M')" >> $GITHUB_ENV
|
||||
echo "DATE_FOR_ZIP=$(date +'%Y%m%d-%H%M')" >> $GITHUB_ENV
|
||||
mkdir -p build/chrome
|
||||
mkdir -p build/firefox
|
||||
|
||||
- name: Create ZIP file
|
||||
- name: Copy files – Chrome
|
||||
run: |
|
||||
zip -r "pre-firxa-${{ env.DATE_FOR_ZIP }}.zip" . -x "*.git*" "*.github*" "*.idea*"
|
||||
rsync -av \
|
||||
--exclude='.git' \
|
||||
--exclude='.gitea' \
|
||||
--exclude='README*' \
|
||||
--exclude='readme*' \
|
||||
--exclude='LICENSE*' \
|
||||
--exclude='license*' \
|
||||
--exclude='*.md' \
|
||||
--exclude='build/' \
|
||||
. build/chrome/
|
||||
|
||||
- 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: Copy files – Firefox
|
||||
run: |
|
||||
rsync -av \
|
||||
--exclude='.git' \
|
||||
--exclude='.gitea' \
|
||||
--exclude='README*' \
|
||||
--exclude='readme*' \
|
||||
--exclude='LICENSE*' \
|
||||
--exclude='license*' \
|
||||
--exclude='*.md' \
|
||||
--exclude='build/' \
|
||||
. build/firefox/
|
||||
|
||||
- name: Create new pre-release
|
||||
id: create_release
|
||||
uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Prepare Chrome build
|
||||
run: |
|
||||
rm -f build/chrome/manifest_fox.json
|
||||
|
||||
- name: Prepare Firefox build
|
||||
run: |
|
||||
rm -f build/firefox/manifest.json
|
||||
mv build/firefox/manifest_fox.json build/firefox/manifest.json
|
||||
|
||||
- name: Create ZIP archives
|
||||
run: |
|
||||
cd build/chrome
|
||||
zip -r ../../firka-extension-chrome-${{ github.event.inputs.version }}.zip .
|
||||
cd ../firefox
|
||||
zip -r ../../firka-extension-firefox-${{ github.event.inputs.version }}.zip .
|
||||
|
||||
- name: Create Release
|
||||
uses: actions/gitea-release@v1
|
||||
with:
|
||||
tag_name: pre-release
|
||||
release_name: Fejlesztői build
|
||||
token: ${{ secrets.GITEA_TOKEN }}
|
||||
tag_name: ${{ github.event.inputs.version }}
|
||||
release_name: ${{ github.event.inputs.version }}
|
||||
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 }}
|
||||
## Firka Extension ${{ github.event.inputs.version }}
|
||||
|
||||
### Letöltések
|
||||
- **Chrome / Chromium** – `firka-extension-chrome-${{ github.event.inputs.version }}.zip`
|
||||
- **Firefox** – `firka-extension-firefox-${{ github.event.inputs.version }}.zip`
|
||||
files: |
|
||||
firka-extension-chrome-${{ github.event.inputs.version }}.zip
|
||||
firka-extension-firefox-${{ github.event.inputs.version }}.zip
|
||||
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
|
||||
prerelease: false
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<p align="center">
|
||||
<img width="150" height="150" alt="firka_logo_128" src="https://github.com/user-attachments/assets/089b37c8-bdb1-48af-93e5-9fc656fe8c15" />
|
||||
<img width="150" height="150" alt="firka_logo_128" src="https://github.com/QwIT-Development/firka-extension/blob/main/images/firka_logo_128.png?raw=true" />
|
||||
<h1 align="center">Firka extension</h1>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ body {
|
||||
|
||||
.month-header {
|
||||
background: var(--button-secondaryFill);
|
||||
color: white;
|
||||
color: var(--text-primary);
|
||||
padding: 16px 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
@@ -377,7 +377,7 @@ body {
|
||||
.modal-header {
|
||||
background: var(--button-secondaryFill);
|
||||
border-bottom: 1px solid #00000000 !important;
|
||||
color: white;
|
||||
color: var(--text-primary);
|
||||
padding: 14px 18px !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -186,5 +186,6 @@
|
||||
{ code: "en", name: "English" },
|
||||
{ code: "de", name: "Deutsch" },
|
||||
],
|
||||
init: initializeLanguage,
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -197,7 +197,7 @@
|
||||
}
|
||||
|
||||
.dropdown-item:hover img {
|
||||
filter: none;
|
||||
filter: brightness(0) saturate(100%) invert(25%) sepia(50%) saturate(2000%) hue-rotate(90deg) brightness(90%) contrast(95%);
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
@@ -418,7 +418,7 @@
|
||||
}
|
||||
|
||||
.mobile-dropdown-item:hover img {
|
||||
filter: none;
|
||||
filter: brightness(0) saturate(100%) invert(25%) sepia(50%) saturate(2000%) hue-rotate(90deg) brightness(90%) contrast(95%);
|
||||
}
|
||||
|
||||
body {
|
||||
|
||||
39
i18n/de.json
@@ -278,10 +278,23 @@
|
||||
"school": "Schule",
|
||||
"student_id": "Schüler-ID",
|
||||
"settings_title": "Profileinstellungen",
|
||||
"tab_my_data": "Meine Daten",
|
||||
"tab_settings": "Einstellungen",
|
||||
"tab_password": "Passwort ändern",
|
||||
"tab_security": "Sicherheitseinstellungen",
|
||||
"tab_contacts": "Kontakte",
|
||||
"loading_data": "Daten werden geladen...",
|
||||
"loading_error": "Fehler beim Laden der Daten.",
|
||||
"my_data_title": "Meine persönlichen Daten",
|
||||
"personal_data": "Persönliche Daten",
|
||||
"contact_data": "Kontaktdaten",
|
||||
"address_data": "Adressdaten",
|
||||
"bank_account_data": "Bankverbindung",
|
||||
"student_card_data": "Schülerausweis Daten",
|
||||
"default_address": "Standard",
|
||||
"password_change_unavailable": "Die Passwortänderungsfunktion ist derzeit nicht verfügbar.",
|
||||
"security_settings_info": "Um Sicherheitseinstellungen zu verwalten, klicken Sie auf die Schaltfläche unten:",
|
||||
"open_security_settings": "Sicherheitseinstellungen öffnen",
|
||||
"two_factor_description": "Um die Zwei-Faktor-Authentifizierung zu verwenden, installieren Sie eine zeitbasierte Einmalpasswort-App (TOTP):",
|
||||
"android": "Android",
|
||||
"iphone": "iPhone",
|
||||
@@ -315,7 +328,31 @@
|
||||
"passwords_not_match": "Die neuen Passwörter stimmen nicht überein!",
|
||||
"password_too_short": "Das neue Passwort muss mindestens 8 Zeichen lang sein!",
|
||||
"password_changed": "Passwort erfolgreich geändert!",
|
||||
"password_change_error": "Fehler beim Ändern des Passworts. Bitte versuchen Sie es später erneut."
|
||||
"password_change_error": "Fehler beim Ändern des Passworts. Bitte versuchen Sie es später erneut.",
|
||||
"field_familyName": "Familienname",
|
||||
"field_firstName": "Vorname",
|
||||
"field_birthFamilyName": "Geburts-Familienname",
|
||||
"field_birthFirstName": "Geburts-Vorname",
|
||||
"field_motherFamilyName": "Geburts-Familienname der Mutter",
|
||||
"field_motherFirstName": "Geburts-Vorname der Mutter",
|
||||
"field_birthDate": "Geburtsdatum",
|
||||
"field_birthPlace": "Geburtsort",
|
||||
"field_birthCountry": "Geburtsland",
|
||||
"field_motherTongue": "Muttersprache",
|
||||
"field_citizenship": "Staatsangehörigkeit",
|
||||
"field_classTeacher": "Klassenlehrer",
|
||||
"field_className": "Klasse",
|
||||
"field_classroom": "Klassenzimmer",
|
||||
"field_username": "Benutzername",
|
||||
"field_phone": "Telefonnummer",
|
||||
"field_email": "Benachrichtigungs-E-Mail-Adresse",
|
||||
"field_accountNumber": "Bankkontonummer",
|
||||
"field_bankName": "Bankname",
|
||||
"field_accountOwner": "Kontoinhaber",
|
||||
"field_cardNumber": "Kartennummer",
|
||||
"field_taxId": "Steuer-ID",
|
||||
"field_studentCardNumber": "Studentenausweisnummer",
|
||||
"field_socialSecurityNumber": "Sozialversicherungsnummer"
|
||||
},
|
||||
"login": {
|
||||
"title": "Anmelden",
|
||||
|
||||
39
i18n/en.json
@@ -278,10 +278,23 @@
|
||||
"school": "School",
|
||||
"student_id": "Student ID",
|
||||
"settings_title": "Profile settings",
|
||||
"tab_my_data": "My Data",
|
||||
"tab_settings": "Settings",
|
||||
"tab_password": "Change password",
|
||||
"tab_security": "Security settings",
|
||||
"tab_contacts": "Contact information",
|
||||
"loading_data": "Loading data...",
|
||||
"loading_error": "An error occurred while loading the data.",
|
||||
"my_data_title": "My Personal Data",
|
||||
"personal_data": "Personal Information",
|
||||
"contact_data": "Contact Information",
|
||||
"address_data": "Address Data",
|
||||
"bank_account_data": "Bank Account Data",
|
||||
"student_card_data": "Student Card Data",
|
||||
"default_address": "Default",
|
||||
"password_change_unavailable": "The password change function is currently unavailable.",
|
||||
"security_settings_info": "To manage security settings, click the button below:",
|
||||
"open_security_settings": "Open Security Settings",
|
||||
"two_factor_description": "To use two-factor authentication, install a time-based one-time password (TOTP) application:",
|
||||
"android": "Android",
|
||||
"iphone": "iPhone",
|
||||
@@ -315,7 +328,31 @@
|
||||
"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."
|
||||
"password_change_error": "An error occurred while changing password. Please try again later.",
|
||||
"field_familyName": "Family name",
|
||||
"field_firstName": "First name",
|
||||
"field_birthFamilyName": "Birth family name",
|
||||
"field_birthFirstName": "Birth first name",
|
||||
"field_motherFamilyName": "Mother's birth family name",
|
||||
"field_motherFirstName": "Mother's birth first name",
|
||||
"field_birthDate": "Date of birth",
|
||||
"field_birthPlace": "Place of birth",
|
||||
"field_birthCountry": "Country of birth",
|
||||
"field_motherTongue": "Mother tongue",
|
||||
"field_citizenship": "Citizenship",
|
||||
"field_classTeacher": "Class teacher",
|
||||
"field_className": "Class",
|
||||
"field_classroom": "Classroom",
|
||||
"field_username": "Username",
|
||||
"field_phone": "Phone number",
|
||||
"field_email": "Notification email address",
|
||||
"field_accountNumber": "Bank account number",
|
||||
"field_bankName": "Bank name",
|
||||
"field_accountOwner": "Account owner's name",
|
||||
"field_cardNumber": "Card number",
|
||||
"field_taxId": "Tax ID",
|
||||
"field_studentCardNumber": "Student card number",
|
||||
"field_socialSecurityNumber": "Social security number"
|
||||
},
|
||||
"login": {
|
||||
"title": "Login",
|
||||
|
||||
39
i18n/hu.json
@@ -280,10 +280,23 @@
|
||||
"school": "Iskola",
|
||||
"student_id": "Diák azonosító",
|
||||
"settings_title": "Profil beállítások",
|
||||
"tab_my_data": "Adataim",
|
||||
"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",
|
||||
"loading_data": "Adatok betöltése...",
|
||||
"loading_error": "Hiba történt az adatok betöltése során.",
|
||||
"my_data_title": "Személyes adataim",
|
||||
"personal_data": "Személyes adatok",
|
||||
"contact_data": "Elérhetőségi adatok",
|
||||
"address_data": "Lakcím adatok",
|
||||
"bank_account_data": "Bankszámla adatok",
|
||||
"student_card_data": "Tanulói igazolvány adatok",
|
||||
"default_address": "Alapértelmezett",
|
||||
"password_change_unavailable": "A jelszó módosítás funkció jelenleg nem érhető el.",
|
||||
"security_settings_info": "A biztonsági beállítások kezeléséhez kattints az alábbi gombra:",
|
||||
"open_security_settings": "Biztonsági beállítások megnyitása",
|
||||
"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",
|
||||
@@ -317,7 +330,31 @@
|
||||
"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."
|
||||
"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.",
|
||||
"field_familyName": "Családi név",
|
||||
"field_firstName": "Utónév",
|
||||
"field_birthFamilyName": "Születési családi név",
|
||||
"field_birthFirstName": "Születési utónév",
|
||||
"field_motherFamilyName": "Anyja születési családi neve",
|
||||
"field_motherFirstName": "Anyja születési utóneve",
|
||||
"field_birthDate": "Születési idő",
|
||||
"field_birthPlace": "Születési hely",
|
||||
"field_birthCountry": "Születési ország",
|
||||
"field_motherTongue": "Anyanyelv",
|
||||
"field_citizenship": "Állampolgárság",
|
||||
"field_classTeacher": "Osztályfőnök",
|
||||
"field_className": "Osztály",
|
||||
"field_classroom": "Terem",
|
||||
"field_username": "Felhasználónév",
|
||||
"field_phone": "Telefonszám",
|
||||
"field_email": "Értesítési e-mail cím",
|
||||
"field_accountNumber": "Bankszámlaszám",
|
||||
"field_bankName": "Számlavezető bank",
|
||||
"field_accountOwner": "Bankszámla tulajdonos neve",
|
||||
"field_cardNumber": "Igazolvány száma",
|
||||
"field_taxId": "Adóazonosító jel",
|
||||
"field_studentCardNumber": "Diákigazolvány szám",
|
||||
"field_socialSecurityNumber": "TAJ-szám"
|
||||
},
|
||||
"login": {
|
||||
"title": "Bejelentkezés",
|
||||
|
||||
1
icons/contact.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 3.223a9.003 9.003 0 0 0-5.605 13.592L3 21l4.185-1.395A9.003 9.003 0 0 0 20.777 14m0-4A9.01 9.01 0 0 0 14 3.223M17 12a5 5 0 0 0-5-5m1 5a1 1 0 0 0-1-1"/></svg>
|
||||
|
After Width: | Height: | Size: 353 B |
@@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28" fill="none"><g fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="8" r="5" fill="currentColor"/><path d="M20 21a8 8 0 1 0-16 0"/></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="3 2 22 24" fill="none"><g fill-rule="evenodd" clip-rule="evenodd" fill="currentColor" stroke="currentColor" stroke-width="1.66667" stroke-linecap="round" stroke-linejoin="round"><circle cx="14" cy="9" r="5" fill="currentColor"/><path d="M22 22a8 8 0 1 0-16 0"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 343 B After Width: | Height: | Size: 343 B |
1
icons/project.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M3 20h.01M7 20a4 4 0 0 0-4-4m8 4a8 8 0 0 0-8-8"/><path fill="currentColor" d="M19 4H5a2 2 0 0 0-2 2v2.5c4 .167 12 2.7 12 11.5h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2"/></g></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
@@ -1 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 28 28" fill="none"><path fill="currentColor" fill-rule="evenodd" d="M9.024 2.783A1 1 0 0 1 10 2h4a1 1 0 0 1 .976.783l.44 1.981q.6.285 1.14.66l1.938-.61a1 1 0 0 1 1.166.454l2 3.464a1 1 0 0 1-.19 1.237l-1.497 1.373a8 8 0 0 1 0 1.316l1.497 1.373a1 1 0 0 1 .19 1.237l-2 3.464a1 1 0 0 1-1.166.454l-1.937-.61q-.54.375-1.14.66l-.44 1.98A1 1 0 0 1 14 22h-4a1 1 0 0 1-.976-.783l-.44-1.981q-.6-.285-1.14-.66l-1.938.61a1 1 0 0 1-1.166-.454l-2-3.464a1 1 0 0 1 .19-1.237l1.497-1.373a8 8 0 0 1 0-1.316L2.53 9.97a1 1 0 0 1-.19-1.237l2-3.464a1 1 0 0 1 1.166-.454l1.937.61q.54-.375 1.14-.66l.44-1.98zM12 15a3 3 0 1 0 0-6a3 3 0 0 0 0 6" clip-rule="evenodd"/></svg>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="2 2 24 24" fill="none">
|
||||
<path fill="currentColor" fill-rule="evenodd" d="M 10.748 4.096 C 10.85 3.638 11.255 3.313 11.724 3.313 L 15.724 3.313 C 16.193 3.313 16.598 3.638 16.7 4.096 L 17.14 6.077 C 17.54 6.267 17.92 6.487 18.28 6.737 L 20.218 6.127 C 20.665 5.986 21.15 6.175 21.384 6.581 L 23.384 10.045 C 23.618 10.451 23.539 10.965 23.194 11.282 L 21.697 12.655 C 21.733 13.093 21.733 13.533 21.697 13.971 L 23.194 15.344 C 23.539 15.661 23.618 16.175 23.384 16.581 L 21.384 20.045 C 21.15 20.451 20.665 20.639 20.218 20.499 L 18.281 19.889 C 17.921 20.139 17.541 20.359 17.141 20.549 L 16.701 22.529 C 16.6 22.987 16.193 23.313 15.724 23.313 L 11.724 23.313 C 11.255 23.313 10.85 22.987 10.748 22.53 L 10.308 20.549 C 9.908 20.359 9.528 20.139 9.168 19.889 L 7.23 20.499 C 6.783 20.639 6.298 20.451 6.064 20.045 L 4.064 16.581 C 3.83 16.175 3.908 15.661 4.254 15.344 L 5.751 13.971 C 5.715 13.533 5.715 13.093 5.751 12.655 L 4.254 11.283 C 3.908 10.966 3.83 10.452 4.064 10.046 L 6.064 6.582 C 6.298 6.176 6.783 5.987 7.23 6.128 L 9.167 6.738 C 9.527 6.488 9.907 6.268 10.307 6.078 L 10.747 4.098 L 10.748 4.096 Z M 13.931 17.38 C 17.01 17.38 18.935 14.046 17.395 11.38 C 16.68 10.142 15.36 9.38 13.931 9.38 C 10.852 9.38 8.927 12.713 10.467 15.38 C 11.181 16.617 12.502 17.38 13.931 17.38" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 722 B After Width: | Height: | Size: 1.4 KiB |
BIN
images/folio.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.8",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -40,9 +40,7 @@
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/storageManager.js",
|
||||
"tools/storageTest.js",
|
||||
"tools/sentry.js",
|
||||
"tools/sentry-browser.min.js"
|
||||
"tools/storageTest.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
@@ -67,8 +65,6 @@
|
||||
"https://eugyintezes.e-kreta.hu/*"
|
||||
],
|
||||
"js": [
|
||||
"tools/sentry-browser.min.js",
|
||||
"tools/sentry.js",
|
||||
"global/language.js",
|
||||
"global/theme.js",
|
||||
"tools/loadingScreen.js",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.4.6",
|
||||
"version": "1.4.8",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -40,9 +40,7 @@
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/storageManager.js",
|
||||
"tools/storageTest.js",
|
||||
"tools/sentry.js",
|
||||
"tools/sentry-browser.min.js"
|
||||
"tools/storageTest.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
@@ -67,8 +65,6 @@
|
||||
"https://eugyintezes.e-kreta.hu/*"
|
||||
],
|
||||
"js": [
|
||||
"tools/sentry-browser.min.js",
|
||||
"tools/sentry.js",
|
||||
"global/language.js",
|
||||
"global/theme.js",
|
||||
"tools/loadingScreen.js",
|
||||
|
||||
@@ -440,7 +440,6 @@ body.modal-open {
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
border-bottom: 1px solid var(--background-0);
|
||||
background: var(--background);
|
||||
border-radius: 12px 12px 0 0;
|
||||
}
|
||||
|
||||
@@ -525,7 +524,7 @@ body.modal-open {
|
||||
}
|
||||
|
||||
.message-info {
|
||||
background-color: var(--card-card);
|
||||
background-color: var(--button-secondaryFill);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 20px;
|
||||
@@ -564,7 +563,7 @@ body.modal-open {
|
||||
}
|
||||
|
||||
.message-text {
|
||||
background-color: var(--card-card);
|
||||
background-color: var(--button-secondaryFill);
|
||||
border-radius: 6px;
|
||||
padding: 15px;
|
||||
line-height: 1.6;
|
||||
@@ -591,14 +590,14 @@ body.modal-open {
|
||||
}
|
||||
|
||||
.message-attachments {
|
||||
background: #f9f9f9;
|
||||
background: var(--button-secondaryFill);
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.message-attachments h4 {
|
||||
margin: 0 0 10px 0;
|
||||
color: #333;
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,8 @@
|
||||
messageContent.appendChild(contentTitle);
|
||||
const messageText = document.createElement('div');
|
||||
messageText.className = 'message-text';
|
||||
messageText.textContent = content;
|
||||
messageText.innerHTML = content;
|
||||
|
||||
messageContent.appendChild(messageText);
|
||||
messageDetails.appendChild(messageContent);
|
||||
|
||||
@@ -320,14 +321,17 @@
|
||||
const attachTitle = document.createElement('h4');
|
||||
attachTitle.textContent = 'Mellékletek:';
|
||||
messageAttachments.appendChild(attachTitle);
|
||||
|
||||
|
||||
const attachList = document.createElement('ul');
|
||||
message.csatolmanyok.forEach(attachment => {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.href = '#';
|
||||
a.textContent = sanitizeHTML(attachment.nev);
|
||||
a.onclick = () => downloadAttachment(attachment.azonosito);
|
||||
a.textContent = sanitizeHTML(attachment.fajlNev || attachment.nev || 'Ismeretlen fájl');
|
||||
a.onclick = (e) => {
|
||||
e.preventDefault();
|
||||
downloadAttachment(attachment.azonosito, attachment.fajlNev || attachment.nev);
|
||||
};
|
||||
li.appendChild(a);
|
||||
attachList.appendChild(li);
|
||||
});
|
||||
@@ -345,6 +349,32 @@
|
||||
}
|
||||
document.body.classList.remove('modal-open');
|
||||
}
|
||||
|
||||
async function downloadAttachment(azonosito, fileName) {
|
||||
try {
|
||||
const response = await chrome.runtime.sendMessage({
|
||||
action: 'download_attachment',
|
||||
azonosito: azonosito,
|
||||
fileName: fileName
|
||||
});
|
||||
|
||||
if (response.success && response.data) {
|
||||
const a = document.createElement('a');
|
||||
a.href = response.data;
|
||||
a.download = response.fileName || 'letoltes';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
} else {
|
||||
console.error('Melléklet letöltési hiba:', response.error);
|
||||
alert('Nem sikerült letölteni a mellékletet.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Melléklet letöltési hiba:', error);
|
||||
alert('Hiba történt a melléklet letöltése során.');
|
||||
}
|
||||
}
|
||||
|
||||
window.openMessageModal = openMessageModal;
|
||||
window.closeMessageModal = closeMessageModal;
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
@import url('../global/theme.css');
|
||||
|
||||
|
||||
.main-header,
|
||||
.main-menu,
|
||||
.main-sidebar,
|
||||
@@ -11,11 +10,17 @@
|
||||
.navbar,
|
||||
.sidebar-container,
|
||||
#sidepanel_tabs,
|
||||
.sidepanel-wrapper {
|
||||
.sidepanel-wrapper,
|
||||
.main-footer2,
|
||||
.lakatimg,
|
||||
.modalContainer,
|
||||
.modalOuter,
|
||||
#ProfilTab,
|
||||
#KretaProgressBar {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -26,6 +31,11 @@ body {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: var(--card-card) !important;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.page-wrapper {
|
||||
background-color: var(--background) !important;
|
||||
min-height: 100vh;
|
||||
@@ -50,271 +60,295 @@ body {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
max-width: 1200px;
|
||||
.profile-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
background-color: var(--background) !important;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.profile-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: 280px 1fr;
|
||||
gap: 2rem;
|
||||
min-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
.firka-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
.profile-sidebar {
|
||||
position: sticky;
|
||||
top: 2rem;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0px 1px 2px 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.profile-tab {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--background);
|
||||
gap: 0.75rem;
|
||||
padding: 1rem;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-radius: 12px;
|
||||
transition: all 0.2s ease;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.profile-tab:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.profile-tab.active {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.profile-tab svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.profile-content {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
box-shadow: 0px 1px 2px 0px var(--accent-shadow);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
border-bottom: 2px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.tab-header h2 {
|
||||
margin: 0;
|
||||
color: var(--text-primary);
|
||||
font-size: 28px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
margin-bottom: 2.5rem;
|
||||
}
|
||||
|
||||
.data-section:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.data-section h3 {
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 1.5rem 0;
|
||||
padding-bottom: 0.75rem;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.back-button {
|
||||
.data-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.data-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.data-item label {
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.data-item span {
|
||||
color: var(--text-primary);
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
padding: 0.75rem;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.address-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.address-item {
|
||||
padding: 1.25rem;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 12px;
|
||||
border-left: 4px solid var(--accent-15);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.address-item:hover {
|
||||
transform: translateX(4px);
|
||||
box-shadow: 0px 2px 8px 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.address-item.default {
|
||||
border-left-color: var(--accent-accent);
|
||||
background: var(--accent-15);
|
||||
}
|
||||
|
||||
.address-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.address-type strong {
|
||||
color: var(--text-primary);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-decoration: none;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.back-button:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.back-button svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--text-primary);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
border-radius: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.address-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.loading-spinner {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4rem 2rem;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border: 4px solid var(--accent-15);
|
||||
border-top-color: var(--accent-accent);
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.loading-spinner p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.k-content {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.k-content h4 {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 28px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 0 0 2rem 0 !important;
|
||||
.info-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
padding: 3rem 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.k-tabstrip-wrapper {
|
||||
background: var(--card-card) !important;
|
||||
border-radius: 24px !important;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.k-tabstrip {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
border-radius: 24px 24px 0 0 !important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
color: var(--text-secondary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
padding: 16px 20px !important;
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
border-radius: 0 !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item.k-state-active .k-link {
|
||||
color: var(--accent-accent) !important;
|
||||
font-weight: 600 !important;
|
||||
border-bottom: 2px solid var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item:hover .k-link {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
|
||||
.k-tabstrip .k-content {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
padding: 20px !important;
|
||||
border-radius: 0 0 24px 24px !important;
|
||||
}
|
||||
|
||||
|
||||
form {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.container-fluid.details {
|
||||
background: transparent !important;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.windowInputLabel {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
select,
|
||||
textarea {
|
||||
background: var(--button-secondaryFill) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 16px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
box-shadow: 0 0 0 3px var(--accent-15) !important;
|
||||
}
|
||||
|
||||
.k-checkbox {
|
||||
appearance: none;
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
border: 2px solid var(--accent-15) !important;
|
||||
border-radius: 4px !important;
|
||||
background: var(--button-secondaryFill) !important;
|
||||
cursor: pointer !important;
|
||||
position: relative !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked {
|
||||
background: var(--accent-accent) !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
.info-message svg {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.k-checkbox-label {
|
||||
margin-left: 8px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
cursor: pointer !important;
|
||||
.info-message p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.k-button,
|
||||
button {
|
||||
background: var(--accent-accent) !important;
|
||||
border: none !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 24px !important;
|
||||
color: white !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 14px !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s ease !important;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow) !important;
|
||||
.error-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1.5rem;
|
||||
padding: 4rem 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.k-button:hover,
|
||||
button:hover {
|
||||
background: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow) !important;
|
||||
.error-message svg {
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.k-button:active,
|
||||
button:active {
|
||||
transform: translateY(0) !important;
|
||||
.error-message p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.content-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.firka-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.k-content h4 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
padding: 12px 16px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
.security-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 1rem 2rem;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow: 0px 2px 4px 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.security-btn:hover {
|
||||
background: var(--accent-secondary);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0px 4px 8px 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.security-btn:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.security-btn svg {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
@@ -327,159 +361,267 @@ button:active {
|
||||
}
|
||||
}
|
||||
|
||||
.k-tabstrip-wrapper {
|
||||
.profile-wrapper {
|
||||
animation: fadeIn 0.4s ease forwards;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
animation: fadeIn 0.5s ease forwards;
|
||||
}
|
||||
|
||||
|
||||
.k-widget,
|
||||
.k-header {
|
||||
background: var(--card-card) !important;
|
||||
color: var(--text-primary) !important;
|
||||
border: none !important;
|
||||
.data-section:nth-child(2) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.k-state-default {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
.data-section:nth-child(3) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.k-state-active {
|
||||
background: transparent !important;
|
||||
.data-section:nth-child(4) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.profile-wrapper {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.k-overlay,
|
||||
.k-window,
|
||||
.k-notification {
|
||||
display: none !important;
|
||||
.profile-sidebar {
|
||||
position: static;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.profile-tab {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
gap: 0.5rem;
|
||||
padding: 1rem 0.5rem;
|
||||
font-size: 13px;
|
||||
min-height: 75px;
|
||||
}
|
||||
|
||||
.profile-tab svg {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
.profile-tab span {
|
||||
line-height: 1.2;
|
||||
word-break: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.data-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.profile-container {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.main-content .content-content {
|
||||
display: block !important;
|
||||
.profile-wrapper {
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.profile-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.data-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.tab-header h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.data-section h3 {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 0.375rem;
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
.profile-tab {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
gap: 0.375rem;
|
||||
padding: 0.625rem 0.25rem;
|
||||
font-size: 11px;
|
||||
min-height: 55px;
|
||||
}
|
||||
|
||||
.profile-tab svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.profile-tab span {
|
||||
line-height: 1.1;
|
||||
word-break: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.address-item {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.security-btn {
|
||||
width: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.info-message,
|
||||
.error-message,
|
||||
.loading-spinner {
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.profile-container {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
align-items: center !important;
|
||||
margin-top: 2rem !important;
|
||||
padding-top: 2rem !important;
|
||||
border-top: 1px solid var(--accent-15) !important;
|
||||
.profile-wrapper {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.profile-content {
|
||||
padding: 0.875rem;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.tab-header h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.data-section h3 {
|
||||
font-size: 15px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.data-item label {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.data-item span {
|
||||
font-size: 13px;
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
padding: 0.25rem;
|
||||
gap: 0.25rem;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.profile-tab {
|
||||
padding: 0.5rem 0.25rem;
|
||||
min-height: 50px;
|
||||
font-size: 10px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.profile-tab svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.profile-tab span {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
|
||||
.address-item {
|
||||
padding: 0.75rem;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 9px;
|
||||
padding: 0.2rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] label {
|
||||
color: var(--text-secondary) !important;
|
||||
font-size: 12px !important;
|
||||
font-style: italic !important;
|
||||
margin: 0 !important;
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.error-message svg {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-contact-info {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
@media print {
|
||||
.profile-sidebar,
|
||||
.security-btn,
|
||||
.kreta-header,
|
||||
.mobile-header,
|
||||
.mobile-bottom-nav {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.profile-wrapper {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.profile-content {
|
||||
box-shadow: none;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.data-section {
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
.hidden-tab {
|
||||
display: none !important;
|
||||
.profile-tab:focus,
|
||||
.security-btn:focus {
|
||||
outline: 2px solid var(--accent-accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 {
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 500px;
|
||||
.profile-tab:focus:not(:focus-visible),
|
||||
.security-btn:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .container-fluid {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin-top: 20px;
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
#ProfilTab-3 h4 {
|
||||
color: #2c3e50;
|
||||
font-weight: 600;
|
||||
margin-bottom: 25px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 3px solid #3498db;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #3498db;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row:hover {
|
||||
background: #e3f2fd;
|
||||
transform: translateX(5px);
|
||||
box-shadow: 0 2px 10px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .windowInputLabel {
|
||||
color: #34495e;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button {
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 10px 20px;
|
||||
::selection {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button:hover {
|
||||
background: linear-gradient(135deg, #2980b9, #1f5f8b);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
|
||||
::-moz-selection {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input {
|
||||
border: 2px solid #e0e6ed;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input:focus {
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert {
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-info {
|
||||
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-success {
|
||||
background: linear-gradient(135deg, #e8f5e8, #c8e6c9);
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-warning {
|
||||
background: linear-gradient(135deg, #fff3e0, #ffcc02);
|
||||
color: #ef6c00;
|
||||
}
|
||||
|
||||
.details .row {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
@@ -1,228 +1,497 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function hideLoadingScreen() {
|
||||
const loadingElement = document.getElementById('KretaProgressBar');
|
||||
if (loadingElement) {
|
||||
loadingElement.style.display = 'none !important';
|
||||
loadingElement.style.visibility = 'hidden';
|
||||
loadingElement.style.opacity = '0';
|
||||
loadingElement.remove();
|
||||
|
||||
}
|
||||
|
||||
const TABS = {
|
||||
MY_DATA: 'my-data',
|
||||
PASSWORD: 'password',
|
||||
SECURITY: 'security'
|
||||
};
|
||||
|
||||
const loadingElements = document.querySelectorAll('[class*="loading"], [id*="loading"], [class*="Loading"], [id*="Loading"]');
|
||||
loadingElements.forEach(el => {
|
||||
el.style.display = 'none !important';
|
||||
el.style.visibility = 'hidden';
|
||||
el.style.opacity = '0';
|
||||
});
|
||||
let currentTab = TABS.MY_DATA;
|
||||
let profileData = null;
|
||||
let addressData = null;
|
||||
|
||||
function getApiUrls(subdomain) {
|
||||
return {
|
||||
PROFILE_DATA: `https://${subdomain}.e-kreta.hu/Adminisztracio/Profil/SajatAdatlapPopUp`,
|
||||
ADDRESS_DATA: `https://${subdomain}.e-kreta.hu/api/ProfilApi/GetElerhetosegCimGrid?sort=&page=1&pageSize=100&group=&filter=&data=%7B%7D&_=`
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function addBackButton() {
|
||||
function hideOriginalElements() {
|
||||
const elementsToHide = [
|
||||
'#KretaProgressBar',
|
||||
'.main-header',
|
||||
'.main-menu',
|
||||
'.main-sidebar',
|
||||
'.content-header',
|
||||
'.favoriteIconContainer',
|
||||
'#frissitesDatumDiv',
|
||||
'#layout_navigationBar',
|
||||
'.navbar',
|
||||
'.sidebar-container',
|
||||
'#sidepanel_tabs',
|
||||
'.sidepanel-wrapper',
|
||||
'.main-footer2',
|
||||
'.lakatimg',
|
||||
'.modalContainer',
|
||||
'.modalOuter',
|
||||
'#ProfilTab'
|
||||
];
|
||||
|
||||
if (document.getElementById('firka-back-button')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.id = 'firka-back-button';
|
||||
backButton.textContent = '← Vissza';
|
||||
backButton.style.cssText = `
|
||||
position: static;
|
||||
margin: 20px;
|
||||
z-index: 100;
|
||||
background-color: var(--card-background, #ffffff);
|
||||
color: var(--text-primary, #333333);
|
||||
border: 1px solid var(--border-color, #e0e0e0);
|
||||
border-radius: 8px;
|
||||
padding: 10px 16px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: auto;
|
||||
`;
|
||||
|
||||
|
||||
backButton.addEventListener('mouseenter', function() {
|
||||
this.style.backgroundColor = 'var(--card-hover, #f5f5f5)';
|
||||
this.style.transform = 'translateY(-1px)';
|
||||
this.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
|
||||
elementsToHide.forEach(selector => {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach(el => {
|
||||
el.style.display = 'none';
|
||||
el.style.visibility = 'hidden';
|
||||
});
|
||||
});
|
||||
|
||||
backButton.addEventListener('mouseleave', function() {
|
||||
this.style.backgroundColor = 'var(--card-background, #ffffff)';
|
||||
this.style.transform = 'translateY(0)';
|
||||
this.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
|
||||
|
||||
document.body.innerHTML = '';
|
||||
}
|
||||
|
||||
async function createNavbar() {
|
||||
const header = await createTemplate.header();
|
||||
const headerContainer = document.createElement('div');
|
||||
headerContainer.innerHTML = header;
|
||||
document.body.appendChild(headerContainer);
|
||||
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
}
|
||||
|
||||
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');
|
||||
userBtn?.classList.toggle('open');
|
||||
});
|
||||
|
||||
|
||||
backButton.addEventListener('click', function() {
|
||||
window.history.back();
|
||||
const mobileUserBtn = document.querySelector('#mobileUserBtn');
|
||||
const mobileUserDropdown = document.querySelector('#mobileUserDropdown');
|
||||
|
||||
mobileUserBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
mobileUserDropdown?.classList.toggle('show');
|
||||
mobileUserBtn?.classList.toggle('active');
|
||||
});
|
||||
|
||||
|
||||
document.body.insertBefore(backButton, document.body.firstChild);
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!userBtn?.contains(e.target) && !userDropdown?.contains(e.target)) {
|
||||
userDropdown?.classList.remove('show');
|
||||
userBtn?.classList.remove('open');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function hideMainFooter2() {
|
||||
const footer2 = document.querySelector('.main-footer2');
|
||||
if (footer2) {
|
||||
footer2.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideLakatImg() {
|
||||
const lakatImg = document.querySelector('.lakatimg');
|
||||
if (lakatImg) {
|
||||
lakatImg.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideCustomUserSettingsTab() {
|
||||
|
||||
const firstTab = document.querySelector('#ProfilTab .k-tabstrip-items li[aria-controls="ProfilTab-1"]');
|
||||
if (firstTab) {
|
||||
firstTab.classList.add('hidden-tab');
|
||||
}
|
||||
|
||||
|
||||
const tabLinks = document.querySelectorAll('#ProfilTab .k-tabstrip-items .k-link');
|
||||
tabLinks.forEach(link => {
|
||||
if (link.textContent && link.textContent.includes('Egyedi felhasználó beállítások')) {
|
||||
const parentTab = link.closest('li');
|
||||
if (parentTab) {
|
||||
parentTab.classList.add('hidden-tab');
|
||||
}
|
||||
if (!mobileUserBtn?.contains(e.target) && !mobileUserDropdown?.contains(e.target)) {
|
||||
mobileUserDropdown?.classList.remove('show');
|
||||
mobileUserBtn?.classList.remove('active');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const contentPanel = document.querySelector('#ProfilTab-1');
|
||||
if (contentPanel) {
|
||||
contentPanel.classList.add('hidden-tab');
|
||||
const mobileDropdownItems = document.querySelectorAll('.mobile-dropdown-item');
|
||||
mobileDropdownItems.forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
mobileUserDropdown?.classList.remove('show');
|
||||
mobileUserBtn?.classList.remove('active');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupSettingsButton() {
|
||||
document.getElementById('settingsBtn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
|
||||
document.getElementById('mobileSettingsBtn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
}
|
||||
|
||||
function createProfilePage() {
|
||||
const t = window.LanguageManager?.t || ((key) => key);
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.className = 'profile-container';
|
||||
container.innerHTML = `
|
||||
<div class="profile-wrapper">
|
||||
<div class="profile-sidebar">
|
||||
<div class="profile-tabs">
|
||||
<button class="profile-tab active" data-tab="${TABS.MY_DATA}">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
||||
<path fill="currentColor" d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
|
||||
</svg>
|
||||
<span>${t('profile.tab_my_data')}</span>
|
||||
</button>
|
||||
<button class="profile-tab" data-tab="${TABS.PASSWORD}">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
||||
<path fill="currentColor" d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm3.1-9H8.9V6c0-1.71 1.39-3.1 3.1-3.1 1.71 0 3.1 1.39 3.1 3.1v2z"/>
|
||||
</svg>
|
||||
<span>${t('profile.tab_password')}</span>
|
||||
</button>
|
||||
<button class="profile-tab" data-tab="${TABS.SECURITY}">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
||||
<path fill="currentColor" d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/>
|
||||
</svg>
|
||||
<span>${t('profile.tab_security')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-content">
|
||||
<div id="tab-${TABS.MY_DATA}" class="tab-content active">
|
||||
<div class="loading-spinner">
|
||||
<div class="spinner"></div>
|
||||
<p>${t('profile.loading_data')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-${TABS.PASSWORD}" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>${t('profile.tab_password')}</h2>
|
||||
</div>
|
||||
<div class="info-message">
|
||||
<svg viewBox="0 0 24 24" width="24" height="24">
|
||||
<path fill="currentColor" d="M11 15h2v2h-2zm0-8h2v6h-2zm.99-5C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/>
|
||||
</svg>
|
||||
<p>${t('profile.password_change_unavailable')}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="tab-${TABS.SECURITY}" class="tab-content">
|
||||
<div class="tab-header">
|
||||
<h2>${t('profile.tab_security')}</h2>
|
||||
</div>
|
||||
<div class="info-message">
|
||||
<p>${t('profile.security_settings_info')}</p>
|
||||
<button id="security-redirect-btn" class="security-btn">
|
||||
<svg viewBox="0 0 24 24" width="20" height="20">
|
||||
<path fill="currentColor" d="M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z"/>
|
||||
</svg>
|
||||
${t('profile.open_security_settings')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.appendChild(container);
|
||||
}
|
||||
|
||||
async function fetchProfileData() {
|
||||
try {
|
||||
const subdomain = await storageManager.get('schoolSubdomain', '');
|
||||
if (!subdomain) {
|
||||
console.error('Nincs beállítva az iskola alcím');
|
||||
return null;
|
||||
}
|
||||
|
||||
const apiUrls = getApiUrls(subdomain);
|
||||
const response = await fetch(apiUrls.PROFILE_DATA);
|
||||
const html = await response.text();
|
||||
return parseProfileHTML(html);
|
||||
} catch (error) {
|
||||
console.error('Hiba a profil adatok lekérésekor:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideAdditionalContactInfo() {
|
||||
async function fetchAddressData() {
|
||||
try {
|
||||
const subdomain = await storageManager.get('schoolSubdomain', '');
|
||||
if (!subdomain) {
|
||||
console.error('Nincs beállítva az iskola alcím');
|
||||
return null;
|
||||
}
|
||||
|
||||
function hideElementsWithText(text) {
|
||||
const elements = document.querySelectorAll('h4');
|
||||
elements.forEach(h4 => {
|
||||
if (h4.textContent && h4.textContent.includes(text)) {
|
||||
// Hide the parent row
|
||||
let parent = h4.closest('.row');
|
||||
if (parent) {
|
||||
parent.classList.add('hidden-contact-info');
|
||||
const apiUrls = getApiUrls(subdomain);
|
||||
const timestamp = new Date().getTime();
|
||||
const response = await fetch(apiUrls.ADDRESS_DATA + timestamp);
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Hiba a cím adatok lekérésekor:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function parseProfileHTML(html) {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(html, 'text/html');
|
||||
|
||||
const data = {
|
||||
personal: {},
|
||||
contact: {},
|
||||
bankAccount: {},
|
||||
studentCard: {}
|
||||
};
|
||||
|
||||
const personalFields = [
|
||||
{ id: 'AlapAdat_CsaladiNev', key: 'familyName' },
|
||||
{ id: 'AlapAdat_Utonev', key: 'firstName' },
|
||||
{ id: 'AlapAdat_SzuletesiCsaladNev', key: 'birthFamilyName' },
|
||||
{ id: 'AlapAdat_SzuletesiUtonev', key: 'birthFirstName' },
|
||||
{ id: 'AlapAdat_AnyjaCsaladiNeve', key: 'motherFamilyName' },
|
||||
{ id: 'AlapAdat_AnyjaUtonev', key: 'motherFirstName' },
|
||||
{ id: 'AlapAdat_SzuletesiIdo_SDATE', key: 'birthDate' },
|
||||
{ id: 'AlapAdat_SzuletesiHely', key: 'birthPlace' },
|
||||
{ id: 'AlapAdat_SzuletesiOrszag', key: 'birthCountry' },
|
||||
{ id: 'AlapAdat_Anyanyelv', key: 'motherTongue' },
|
||||
{ id: 'AlapAdat_Allampolgarsag', key: 'citizenship' },
|
||||
{ id: 'AlapAdat_OsztalyfonokNev', key: 'classTeacher' },
|
||||
{ id: 'AlapAdat_OsztalyNev', key: 'className' },
|
||||
{ id: 'AlapAdat_TeremNev', key: 'classroom' },
|
||||
{ id: 'AlapAdat_BelepesiNev', key: 'username' }
|
||||
];
|
||||
|
||||
personalFields.forEach(field => {
|
||||
const label = doc.querySelector(`label[displayfor="${field.id}"]`);
|
||||
if (label) {
|
||||
data.personal[field.key] = {
|
||||
key: field.key,
|
||||
value: label.textContent.trim()
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const phoneInput = doc.querySelector('#Elerhetosegek_ErtesitesiTelefon_TelefonSzam');
|
||||
const emailInput = doc.querySelector('#Elerhetosegek_ErtesitesiEmail_EmailCim');
|
||||
|
||||
if (phoneInput) {
|
||||
data.contact.phone = {
|
||||
key: 'phone',
|
||||
value: phoneInput.value || ''
|
||||
};
|
||||
}
|
||||
|
||||
if (emailInput) {
|
||||
data.contact.email = {
|
||||
key: 'email',
|
||||
value: emailInput.value || ''
|
||||
};
|
||||
}
|
||||
|
||||
const bankFields = [
|
||||
{ id: 'BankszamlaSzam', key: 'accountNumber' },
|
||||
{ id: 'SzamlavezetoBank', key: 'bankName' },
|
||||
{ id: 'BankszamlaTulajdonosNeve', key: 'accountOwner' }
|
||||
];
|
||||
|
||||
bankFields.forEach(field => {
|
||||
const input = doc.querySelector(`#${field.id}`);
|
||||
if (input) {
|
||||
data.bankAccount[field.key] = {
|
||||
key: field.key,
|
||||
value: input.value || ''
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const cardFields = [
|
||||
{ id: 'TanuloIgazolvany_Igazolvanyszam', key: 'cardNumber' },
|
||||
{ id: 'TanuloIgazolvany_AdoazonositoJel', key: 'taxId' },
|
||||
{ id: 'TanuloIgazolvany_DiakigazolvanySzam', key: 'studentCardNumber' },
|
||||
{ id: 'TanuloIgazolvany_TajSzam', key: 'socialSecurityNumber' }
|
||||
];
|
||||
|
||||
cardFields.forEach(field => {
|
||||
const label = doc.querySelector(`label[displayfor="${field.id}"]`);
|
||||
if (label) {
|
||||
data.studentCard[field.key] = {
|
||||
key: field.key,
|
||||
value: label.textContent.trim()
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function renderProfileData() {
|
||||
const t = window.LanguageManager?.t || ((key) => key);
|
||||
const container = document.getElementById(`tab-${TABS.MY_DATA}`);
|
||||
|
||||
if (!profileData && !addressData) {
|
||||
container.innerHTML = `
|
||||
<div class="error-message">
|
||||
<svg viewBox="0 0 24 24" width="48" height="48">
|
||||
<path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
||||
</svg>
|
||||
<p>${t('profile.loading_error')}</p>
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `<div class="tab-header"><h2>${t('profile.my_data_title')}</h2></div>`;
|
||||
|
||||
if (profileData && profileData.personal && Object.keys(profileData.personal).length > 0) {
|
||||
html += `<div class="data-section"><h3>${t('profile.personal_data')}</h3><div class="data-grid">`;
|
||||
|
||||
Object.values(profileData.personal).forEach(field => {
|
||||
if (field.value && field.value !== 'XY') {
|
||||
html += `
|
||||
<div class="data-item">
|
||||
<label>${t(`profile.field_${field.key}`)}</label>
|
||||
<span>${field.value}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
}
|
||||
|
||||
if (profileData && profileData.contact && Object.keys(profileData.contact).length > 0) {
|
||||
html += `<div class="data-section"><h3>${t('profile.contact_data')}</h3><div class="data-grid">`;
|
||||
|
||||
Object.values(profileData.contact).forEach(field => {
|
||||
if (field.value) {
|
||||
html += `
|
||||
<div class="data-item">
|
||||
<label>${t(`profile.field_${field.key}`)}</label>
|
||||
<span>${field.value}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
}
|
||||
|
||||
if (addressData && addressData.Data && addressData.Data.length > 0) {
|
||||
html += `<div class="data-section"><h3>${t('profile.address_data')}</h3><div class="address-list">`;
|
||||
|
||||
addressData.Data.forEach(address => {
|
||||
const fullAddress = `${address.Irsz} ${address.Varos}, ${address.Kozterulet} ${address.KozteruletJellegeNev || ''} ${address.HazSzam}${address.Emelet ? ' ' + address.Emelet : ''}${address.Ajto ? ' ' + address.Ajto : ''}`;
|
||||
const isDefault = address.Alapertelmezett_BOOL;
|
||||
|
||||
html += `
|
||||
<div class="address-item ${isDefault ? 'default' : ''}">
|
||||
<div class="address-type">
|
||||
<strong>${address.CimTipus_DNAME}</strong>
|
||||
${isDefault ? `<span class="badge">${t('profile.default_address')}</span>` : ''}
|
||||
</div>
|
||||
<div class="address-details">${fullAddress}</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
}
|
||||
|
||||
if (profileData && profileData.bankAccount && Object.keys(profileData.bankAccount).length > 0) {
|
||||
const hasData = Object.values(profileData.bankAccount).some(field => field.value);
|
||||
|
||||
if (hasData) {
|
||||
html += `<div class="data-section"><h3>${t('profile.bank_account_data')}</h3><div class="data-grid">`;
|
||||
|
||||
Object.values(profileData.bankAccount).forEach(field => {
|
||||
if (field.value) {
|
||||
html += `
|
||||
<div class="data-item">
|
||||
<label>${t(`profile.field_${field.key}`)}</label>
|
||||
<span>${field.value}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
}
|
||||
}
|
||||
|
||||
if (profileData && profileData.studentCard && Object.keys(profileData.studentCard).length > 0) {
|
||||
const hasData = Object.values(profileData.studentCard).some(field => field.value && field.value !== 'XY');
|
||||
|
||||
if (hasData) {
|
||||
html += `<div class="data-section"><h3>${t('profile.student_card_data')}</h3><div class="data-grid">`;
|
||||
|
||||
Object.values(profileData.studentCard).forEach(field => {
|
||||
if (field.value && field.value !== 'XY') {
|
||||
html += `
|
||||
<div class="data-item">
|
||||
<label>${t(`profile.field_${field.key}`)}</label>
|
||||
<span>${field.value}</span>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
html += '</div></div>';
|
||||
}
|
||||
}
|
||||
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
function setupTabSwitching() {
|
||||
const tabs = document.querySelectorAll('.profile-tab');
|
||||
const tabContents = document.querySelectorAll('.tab-content');
|
||||
|
||||
tabs.forEach(tab => {
|
||||
tab.addEventListener('click', () => {
|
||||
const tabId = tab.getAttribute('data-tab');
|
||||
|
||||
tabs.forEach(t => t.classList.remove('active'));
|
||||
tab.classList.add('active');
|
||||
|
||||
tabContents.forEach(tc => tc.classList.remove('active'));
|
||||
document.getElementById(`tab-${tabId}`).classList.add('active');
|
||||
|
||||
currentTab = tabId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function setupSecurityRedirect() {
|
||||
const btn = document.getElementById('security-redirect-btn');
|
||||
if (btn) {
|
||||
btn.addEventListener('click', async () => {
|
||||
const subdomain = await storageManager.get('schoolSubdomain', '');
|
||||
const url = `https://idp.e-kreta.hu/security?returnUrl=https%3A%2F%2F${subdomain}.e-kreta.hu%2FAdminisztracio%2FProfil`;
|
||||
window.location.href = url;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
hideElementsWithText('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK');
|
||||
hideElementsWithText('TOVÁBBI TELEFONSZÁMOK');
|
||||
|
||||
|
||||
const rows = document.querySelectorAll('.row');
|
||||
rows.forEach(row => {
|
||||
const h4Elements = row.querySelectorAll('h4');
|
||||
h4Elements.forEach(h4 => {
|
||||
if (h4.textContent &&
|
||||
(h4.textContent.includes('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK') ||
|
||||
h4.textContent.includes('TOVÁBBI TELEFONSZÁMOK'))) {
|
||||
row.classList.add('hidden-contact-info');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
hideLoadingScreen();
|
||||
addBackButton();
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
|
||||
async function init() {
|
||||
try {
|
||||
hideOriginalElements();
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
if (typeof window.LanguageManager !== 'undefined' && window.LanguageManager.init) {
|
||||
await window.LanguageManager.init();
|
||||
}
|
||||
|
||||
await createNavbar();
|
||||
createProfilePage();
|
||||
setupTabSwitching();
|
||||
setupSecurityRedirect();
|
||||
|
||||
[profileData, addressData] = await Promise.all([
|
||||
fetchProfileData(),
|
||||
fetchAddressData()
|
||||
]);
|
||||
|
||||
renderProfileData();
|
||||
} catch (error) {
|
||||
console.error('Hiba az inicializálás során:', error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('load', init);
|
||||
|
||||
|
||||
setTimeout(hideLoadingScreen, 1000);
|
||||
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 20;
|
||||
const aggressiveHide = setInterval(() => {
|
||||
attempts++;
|
||||
hideLoadingScreen();
|
||||
|
||||
if (attempts >= maxAttempts) {
|
||||
clearInterval(aggressiveHide);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType === 1) {
|
||||
if (node.id === 'KretaProgressBar' ||
|
||||
node.className && (node.className.includes('loading') || node.className.includes('Loading'))) {
|
||||
node.style.display = 'none !important';
|
||||
node.style.visibility = 'hidden';
|
||||
node.style.opacity = '0';
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -593,29 +593,6 @@ h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.modal-close:hover {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.modal-close .material-icons-round {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 16px;
|
||||
}
|
||||
@@ -840,7 +817,6 @@ h2 {
|
||||
width: 100%;
|
||||
min-height: 80px;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--text-teritary);
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
@@ -851,11 +827,6 @@ h2 {
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.share-code-wrapper textarea:focus,
|
||||
#importCode:focus {
|
||||
border-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
@@ -1150,3 +1121,256 @@ h2 {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.update-modal .modal-content {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.update-version-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
padding: 16px;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.version-badge {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.version-badge.current {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.version-badge.latest {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.version-label {
|
||||
font-size: 11px;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.version-number {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.version-badge.latest .version-number {
|
||||
color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.version-arrow {
|
||||
color: var(--accent-accent);
|
||||
font-size: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.update-changelog-section {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.update-changelog-section h4 {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 12px 0;
|
||||
}
|
||||
|
||||
.update-changelog {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
padding: 12px;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.update-changelog p {
|
||||
margin: 0 0 8px 0;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.update-changelog p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.update-changelog h1,
|
||||
.update-changelog h2,
|
||||
.update-changelog h3 {
|
||||
color: var(--text-primary);
|
||||
margin: 12px 0 8px 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.update-changelog h1 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.update-changelog h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.update-changelog h3 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.update-changelog ul,
|
||||
.update-changelog ol {
|
||||
margin: 8px 0;
|
||||
padding-left: 24px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.update-changelog li {
|
||||
margin: 4px 0;
|
||||
}
|
||||
|
||||
.update-changelog code {
|
||||
background: var(--accent-15);
|
||||
color: var(--accent-accent);
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.update-changelog pre {
|
||||
background: var(--background);
|
||||
color: var(--text-primary);
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
overflow-x: auto;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.update-changelog pre code {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.update-changelog a {
|
||||
color: var(--accent-accent);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.update-changelog a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.update-changelog blockquote {
|
||||
border-left: 3px solid var(--accent-accent);
|
||||
padding-left: 12px;
|
||||
margin: 8px 0;
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.update-changelog strong {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.update-changelog em {
|
||||
font-style: italic;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.update-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
text-decoration: none;
|
||||
justify-content: center;
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.update-button .material-icons-round {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.folio-ad-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: linear-gradient(135deg, #00D2A9 0%, #00b896 100%);
|
||||
border-radius: 16px;
|
||||
padding: 14px 16px;
|
||||
margin: 4px 16px 16px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: transform 0.15s ease, box-shadow 0.15s ease;
|
||||
box-shadow: 0 2px 12px rgba(0, 210, 169, 0.35);
|
||||
}
|
||||
|
||||
.folio-ad-card:hover {
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 16px rgba(0, 210, 169, 0.5);
|
||||
}
|
||||
|
||||
.folio-ad-card:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.folio-ad-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.folio-ad-logo {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 10px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.folio-ad-text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.folio-ad-title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.folio-ad-desc {
|
||||
font-size: 11px;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
|
||||
.folio-ad-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 8px;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
|
||||
.folio-ad-right .material-icons-round {
|
||||
font-size: 16px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.folio-ad-cta {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@@ -103,6 +103,19 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="https://folio.zan1456.dev" target="_blank" class="folio-ad-card">
|
||||
<div class="folio-ad-left">
|
||||
<img src="../images/folio.png" alt="Folio" class="folio-ad-logo">
|
||||
<div class="folio-ad-text">
|
||||
<span class="folio-ad-title">Folio</span>
|
||||
<span class="folio-ad-desc">Material You KRÉTA app Androidra</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="folio-ad-right">
|
||||
<span class="material-icons-round">download</span>
|
||||
<span class="folio-ad-cta">Letöltés</span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="tab-content" id="tab-settings">
|
||||
@@ -188,13 +201,43 @@
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-overlay" id="updateModal">
|
||||
<div class="modal-content update-modal">
|
||||
<div class="modal-header">
|
||||
<h3 data-i18n="settings.update.title">Új verzió érhető el!</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="update-version-info">
|
||||
<div class="version-badge current">
|
||||
<span class="version-label" data-i18n="settings.update.current_version">Jelenlegi verzió:</span>
|
||||
<span class="version-number" id="currentVersion">-</span>
|
||||
</div>
|
||||
<span class="material-icons-round version-arrow">arrow_forward</span>
|
||||
<div class="version-badge latest">
|
||||
<span class="version-label" data-i18n="settings.update.latest_version">Legújabb verzió:</span>
|
||||
<span class="version-number" id="latestVersion">-</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="update-changelog-section">
|
||||
<h4 data-i18n="settings.update.whats_new">Újdonságok:</h4>
|
||||
<div class="update-changelog" id="updateChangelog">
|
||||
<p data-i18n="settings.update.loading">Betöltés...</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn-secondary" id="dismissUpdate" data-i18n="settings.update.dismiss">Bezárás</button>
|
||||
<a class="btn-primary update-button" id="updateButton" href="#" target="_blank">
|
||||
<span data-i18n="settings.update.download">Letöltés</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal-overlay" id="themeEditorModal">
|
||||
<div class="modal-content theme-editor-modal">
|
||||
<div class="modal-header">
|
||||
<h3 id="themeEditorTitle" data-i18n="settings.custom_themes.create">Új téma létrehozása</h3>
|
||||
<button class="modal-close" id="closeThemeEditor">
|
||||
<span class="material-icons-round">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="theme-form">
|
||||
@@ -265,9 +308,6 @@
|
||||
<div class="modal-content share-modal">
|
||||
<div class="modal-header">
|
||||
<h3 data-i18n="settings.custom_themes.share">Téma megosztása</h3>
|
||||
<button class="modal-close" id="closeShareModal">
|
||||
<span class="material-icons-round">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p data-i18n="settings.custom_themes.share_description">Másold ki a kódot és oszd meg másokkal:</p>
|
||||
@@ -288,9 +328,6 @@
|
||||
<div class="modal-content import-modal">
|
||||
<div class="modal-header">
|
||||
<h3 data-i18n="settings.custom_themes.import">Téma importálása</h3>
|
||||
<button class="modal-close" id="closeImportModal">
|
||||
<span class="material-icons-round">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p data-i18n="settings.custom_themes.import_description">Illeszd be a téma kódot:</p>
|
||||
@@ -304,8 +341,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../tools/sentry-browser.min.js"></script>
|
||||
<script src="../tools/sentry.js"></script>
|
||||
<script src="../tools/helper.js"></script>
|
||||
<script src="../tools/storageManager.js"></script>
|
||||
<script src="../global/language.js"></script>
|
||||
|
||||
@@ -1048,6 +1048,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
await initTabs();
|
||||
await initErrorReporting();
|
||||
await checkForUpdates();
|
||||
});
|
||||
|
||||
async function initErrorReporting() {
|
||||
@@ -1067,3 +1068,101 @@ async function initErrorReporting() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function checkForUpdates() {
|
||||
try {
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const currentVersion = manifest.version;
|
||||
|
||||
const response = await fetch('https://api.github.com/repos/QwIT-Development/firka-extension/releases/latest');
|
||||
if (!response.ok) {
|
||||
console.error('Failed to fetch latest release');
|
||||
return;
|
||||
}
|
||||
|
||||
const latestRelease = await response.json();
|
||||
const latestVersion = latestRelease.tag_name.replace(/^v/, '');
|
||||
|
||||
if (compareVersions(latestVersion, currentVersion) > 0) {
|
||||
showUpdateModal(currentVersion, latestVersion, latestRelease);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking for updates:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function compareVersions(v1, v2) {
|
||||
const parts1 = v1.split('.').map(Number);
|
||||
const parts2 = v2.split('.').map(Number);
|
||||
|
||||
for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {
|
||||
const part1 = parts1[i] || 0;
|
||||
const part2 = parts2[i] || 0;
|
||||
|
||||
if (part1 > part2) return 1;
|
||||
if (part1 < part2) return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function parseMarkdown(markdown) {
|
||||
let html = markdown;
|
||||
|
||||
html = html.replace(/^### (.*$)/gim, '<h3>$1</h3>');
|
||||
html = html.replace(/^## (.*$)/gim, '<h2>$1</h2>');
|
||||
html = html.replace(/^# (.*$)/gim, '<h1>$1</h1>');
|
||||
|
||||
html = html.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>');
|
||||
html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
|
||||
html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
|
||||
html = html.replace(/__(.+?)__/g, '<strong>$1</strong>');
|
||||
html = html.replace(/_(.+?)_/g, '<em>$1</em>');
|
||||
|
||||
html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
|
||||
|
||||
html = html.replace(/```([^```]+)```/g, '<pre><code>$1</code></pre>');
|
||||
|
||||
html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
|
||||
|
||||
html = html.replace(/^> (.+)/gim, '<blockquote>$1</blockquote>');
|
||||
|
||||
html = html.replace(/^\* (.+)$/gim, '<li>$1</li>');
|
||||
html = html.replace(/^- (.+)$/gim, '<li>$1</li>');
|
||||
html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
|
||||
|
||||
html = html.replace(/^\d+\. (.+)$/gim, '<li>$1</li>');
|
||||
|
||||
html = html.replace(/\n\n/g, '</p><p>');
|
||||
html = html.replace(/^(?!<[hou]|<li|<pre|<blockquote)(.+)$/gim, '<p>$1</p>');
|
||||
|
||||
html = html.replace(/<p><\/p>/g, '');
|
||||
html = html.replace(/<p>(<[hou])/g, '$1');
|
||||
html = html.replace(/(<\/[hou]l?>)<\/p>/g, '$1');
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function showUpdateModal(currentVersion, latestVersion, releaseData) {
|
||||
const modal = document.getElementById('updateModal');
|
||||
const currentVersionEl = document.getElementById('currentVersion');
|
||||
const latestVersionEl = document.getElementById('latestVersion');
|
||||
const changelogEl = document.getElementById('updateChangelog');
|
||||
const updateButton = document.getElementById('updateButton');
|
||||
|
||||
currentVersionEl.textContent = `v${currentVersion}`;
|
||||
latestVersionEl.textContent = `v${latestVersion}`;
|
||||
|
||||
const changelog = releaseData.body || 'Nincs elérhető változásnapló.';
|
||||
changelogEl.innerHTML = parseMarkdown(changelog);
|
||||
|
||||
updateButton.href = releaseData.html_url;
|
||||
|
||||
modal.classList.add('active');
|
||||
document.getElementById('dismissUpdate').addEventListener('click', closeUpdateModal);
|
||||
}
|
||||
|
||||
function closeUpdateModal() {
|
||||
const modal = document.getElementById('updateModal');
|
||||
modal.classList.remove('active');
|
||||
}
|
||||
|
||||
@@ -152,8 +152,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="../tools/sentry-browser.min.js"></script>
|
||||
<script src="../tools/sentry.js"></script>
|
||||
<script src="../tools/storageManager.js"></script>
|
||||
<script src="../global/language.js"></script>
|
||||
<script src="setup.js"></script>
|
||||
|
||||
@@ -147,7 +147,8 @@ body {
|
||||
transition:all 0.3s cubic-bezier(0.4,0,0.2,1);
|
||||
transform:translateY(0);
|
||||
}
|
||||
.lesson-card:hover {
|
||||
.lesson-card:hover,
|
||||
.lesson-card.group-hover {
|
||||
transform:translateY(-4px);
|
||||
box-shadow:0 8px 12px var(--accent-shadow);
|
||||
}
|
||||
@@ -162,6 +163,28 @@ body {
|
||||
opacity:0.5;
|
||||
text-decoration:line-through;
|
||||
}
|
||||
|
||||
.lesson-card.lesson-spans-multiple {
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.lesson-card.lesson-continuation.continuation-middle {
|
||||
border-radius: 0;
|
||||
}
|
||||
.lesson-card.lesson-continuation.continuation-end {
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.lesson-slot.has-multi-start {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.lesson-slot.has-continuation {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.lesson-subject {
|
||||
align-self:stretch;
|
||||
color:var(--text-primary);
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
}
|
||||
|
||||
function getLessonKey(lesson) {
|
||||
return `${lesson.subject}_${lesson.startTime}_${lesson.day}`;
|
||||
return `${lesson.subject}_${lesson.startTime}_${lesson.date}`;
|
||||
}
|
||||
|
||||
async function updateHomeworkIconsFromCookie() {
|
||||
@@ -313,7 +313,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTestDetailsFromAPI(testId) {
|
||||
let cachedTestData = null;
|
||||
let testDataTimestamp = 0;
|
||||
const TEST_DATA_CACHE_DURATION = 60000;
|
||||
|
||||
async function loadAllTestDataFromAPI() {
|
||||
const now = Date.now();
|
||||
if (cachedTestData && (now - testDataTimestamp) < TEST_DATA_CACHE_DURATION) {
|
||||
return cachedTestData;
|
||||
}
|
||||
|
||||
try {
|
||||
const timestamp = Date.now();
|
||||
const apiUrl = `https://${window.location.hostname}/api/TanuloBejelentettSzamonkeresekApi/GetBejelentettSzamonkeresekGrid?sort=SzamonkeresDatuma-asc~Oraszam-asc&page=1&pageSize=1000&group=&filter=&data=%7B%22RegiSzamonkeresekElrejtese%22%3Afalse%7D&_=${timestamp}`;
|
||||
@@ -327,15 +336,30 @@
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Számonkérés API hiba: ${response.status}`,
|
||||
);
|
||||
throw new Error(`Számonkérés API hiba: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const testData = data.Data || [];
|
||||
cachedTestData = data.Data || [];
|
||||
testDataTimestamp = now;
|
||||
return cachedTestData;
|
||||
} catch (error) {
|
||||
console.error("Számonkérés adatok betöltési hiba:", error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function getTestTypeById(testId) {
|
||||
const testData = await loadAllTestDataFromAPI();
|
||||
const testDetail = testData.find(test => test.ID === testId.toString());
|
||||
return testDetail ? testDetail.ErtekelesModNev : null;
|
||||
}
|
||||
|
||||
async function loadTestDetailsFromAPI(testId) {
|
||||
try {
|
||||
const testData = await loadAllTestDataFromAPI();
|
||||
const testDetail = testData.find(test => test.ID === testId.toString());
|
||||
|
||||
|
||||
if (testDetail) {
|
||||
return {
|
||||
name: testDetail.SzamonkeresMegnevezes || 'Nincs megnevezés',
|
||||
@@ -343,7 +367,7 @@
|
||||
announceDate: testDetail.BejelentesDatuma ? new Date(testDetail.BejelentesDatuma).toLocaleDateString('hu-HU') : 'Nincs dátum'
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
console.error("Számonkérés adatok betöltési hiba:", error);
|
||||
@@ -410,6 +434,7 @@
|
||||
originalTeacher: "",
|
||||
room: "",
|
||||
day: dayIndex,
|
||||
date: weekDates[dayIndex]?.fullDate || eventDate.toISOString().split('T')[0],
|
||||
isSubstituted: false,
|
||||
isCancelled: false,
|
||||
hasHomework: false,
|
||||
@@ -446,9 +471,9 @@
|
||||
"Ismeretlen tantárgy";
|
||||
|
||||
if (startTimeStr && subject) {
|
||||
const isCancelled = event.isElmaradt || event.Elmaradt || event.cancelled || event.isCancelled ||
|
||||
const isCancelled = event.isElmaradt || event.Elmaradt || event.cancelled || event.isCancelled ||
|
||||
event.oraType === 6 || (event.title && event.title.toLowerCase().includes('elmarad'));
|
||||
|
||||
|
||||
const lesson = {
|
||||
startTime: startTimeStr,
|
||||
endTime: endTimeStr,
|
||||
@@ -457,14 +482,15 @@
|
||||
originalTeacher: event.helyettesitoId ? teacher : "",
|
||||
room: room,
|
||||
day: dayIndex,
|
||||
date: weekDates[dayIndex]?.fullDate || eventDate.toISOString().split('T')[0],
|
||||
isSubstituted: !!event.helyettesitoId,
|
||||
isCancelled: isCancelled,
|
||||
hasHomework: event.hasHaziFeladat || false,
|
||||
testInfo: event.hasBejelentettSzamonkeres
|
||||
? event.Tema || LanguageManager.t("timetable.test_indicator")
|
||||
: "",
|
||||
testId: event.hasBejelentettSzamonkeres && event.BejelentettSzamonkeresIdList && event.BejelentettSzamonkeresIdList.length > 0
|
||||
? event.BejelentettSzamonkeresIdList[0]
|
||||
testId: event.hasBejelentettSzamonkeres && event.BejelentettSzamonkeresIdList && event.BejelentettSzamonkeresIdList.length > 0
|
||||
? event.BejelentettSzamonkeresIdList[0]
|
||||
: null,
|
||||
testDetails: "",
|
||||
homeworkDetails: "",
|
||||
@@ -497,6 +523,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
const testTypeMap = {};
|
||||
const lessonsWithTests = lessons.filter(l => l.testId);
|
||||
if (lessonsWithTests.length > 0) {
|
||||
await loadAllTestDataFromAPI();
|
||||
for (const lesson of lessonsWithTests) {
|
||||
testTypeMap[lesson.testId] = await getTestTypeById(lesson.testId);
|
||||
}
|
||||
}
|
||||
|
||||
const times = [...new Set(regularLessons.map((l) => l.startTime))].sort(
|
||||
(a, b) => {
|
||||
const timeA = helper.convertTimeToMinutes(a);
|
||||
@@ -504,6 +539,26 @@
|
||||
return timeA - timeB;
|
||||
},
|
||||
);
|
||||
|
||||
function getLessonTimeSlots(lesson, allTimes) {
|
||||
const startMinutes = helper.convertTimeToMinutes(lesson.startTime);
|
||||
const endMinutes = helper.convertTimeToMinutes(lesson.endTime);
|
||||
const slots = [];
|
||||
for (let i = 0; i < allTimes.length; i++) {
|
||||
const slotMinutes = helper.convertTimeToMinutes(allTimes[i]);
|
||||
if (slotMinutes >= startMinutes && slotMinutes < endMinutes) {
|
||||
slots.push(i);
|
||||
}
|
||||
}
|
||||
return slots.length > 0 ? slots : [allTimes.indexOf(lesson.startTime)];
|
||||
}
|
||||
|
||||
const lessonSlotMap = new Map();
|
||||
regularLessons.forEach(lesson => {
|
||||
const slots = getLessonTimeSlots(lesson, times);
|
||||
lessonSlotMap.set(lesson, slots);
|
||||
});
|
||||
|
||||
const days = [
|
||||
LanguageManager.t("timetable.monday"),
|
||||
LanguageManager.t("timetable.tuesday"),
|
||||
@@ -569,38 +624,84 @@
|
||||
const dayLessons = regularLessons.filter(
|
||||
(l) => l.startTime === time && l.day === dayIndex,
|
||||
);
|
||||
|
||||
const continuingInSlot = regularLessons.filter(lesson => {
|
||||
if (lesson.day !== dayIndex) return false;
|
||||
const slots = lessonSlotMap.get(lesson);
|
||||
return slots && slots.includes(timeIndex) && slots[0] !== timeIndex;
|
||||
});
|
||||
|
||||
const hasMultiLesson = dayLessons.some(lesson => {
|
||||
const slots = lessonSlotMap.get(lesson);
|
||||
return slots && slots.length > 1;
|
||||
});
|
||||
|
||||
const lastLessonTime = lastLessonTimes[dayIndex];
|
||||
const isAfterLastLesson = lastLessonTime && helper.convertTimeToMinutes(time) > helper.convertTimeToMinutes(lastLessonTime);
|
||||
|
||||
if (dayLessons.length === 0 && isAfterLastLesson) {
|
||||
|
||||
if (dayLessons.length === 0 && continuingInSlot.length === 0 && isAfterLastLesson) {
|
||||
return `<div class="lesson-slot"></div>`;
|
||||
}
|
||||
|
||||
|
||||
if (continuingInSlot.length > 0) {
|
||||
return `
|
||||
<div class="lesson-slot ${dayLessons.length === 0 ? 'empty-slot' : ''}">
|
||||
${dayLessons.length === 0 ? '<div class="empty-lesson-placeholder"></div>' : ''}
|
||||
${dayLessons
|
||||
.map(
|
||||
(lesson) => `
|
||||
<div class="lesson-card ${lesson.isSubstituted ? "substituted" : ""}
|
||||
<div class="lesson-slot has-continuation">
|
||||
${continuingInSlot.map(lesson => {
|
||||
const slots = lessonSlotMap.get(lesson);
|
||||
const isLastSlot = slots[slots.length - 1] === timeIndex;
|
||||
const lessonGroupId = `${lesson.subject}_${lesson.day}_${lesson.date}_${lesson.startTime}`;
|
||||
return `
|
||||
<div class="lesson-card ${lesson.isSubstituted ? "substituted" : ""}
|
||||
${lesson.isCancelled ? "cancelled" : ""}
|
||||
${lesson.hasHomework ? "has-homework" : ""}"
|
||||
lesson-continuation ${isLastSlot ? 'continuation-end' : 'continuation-middle'}"
|
||||
data-lesson='${JSON.stringify(lesson)}'
|
||||
data-lesson-id='${lesson.lessonId || ""}'>
|
||||
<div class="lesson-subject">${lesson.subject}</div>
|
||||
<div class="lesson-teacher">${lesson.teacher}</div>
|
||||
data-lesson-id='${lesson.lessonId || ""}'
|
||||
data-lesson-group='${lessonGroupId}'>
|
||||
<div class="lesson-bottom">
|
||||
<div class="lesson-room">${lesson.room}</div>
|
||||
<div class="lesson-time">${lesson.isCancelled ? LanguageManager.t("timetable.cancelled") : lesson.startTime}</div>
|
||||
</div>
|
||||
</div>
|
||||
`}).join('')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
return `
|
||||
<div class="lesson-slot ${dayLessons.length === 0 ? 'empty-slot' : ''} ${hasMultiLesson ? 'has-multi-start' : ''}">
|
||||
${dayLessons.length === 0 ? '<div class="empty-lesson-placeholder"></div>' : ''}
|
||||
${dayLessons
|
||||
.map(
|
||||
(lesson) => {
|
||||
const slots = lessonSlotMap.get(lesson);
|
||||
const spansMultiple = slots && slots.length > 1;
|
||||
const lessonGroupId = `${lesson.subject}_${lesson.day}_${lesson.date}_${lesson.startTime}`;
|
||||
return `
|
||||
<div class="lesson-card ${lesson.isSubstituted ? "substituted" : ""}
|
||||
${lesson.isCancelled ? "cancelled" : ""}
|
||||
${lesson.hasHomework ? "has-homework" : ""}
|
||||
${spansMultiple ? "lesson-spans-multiple" : ""}"
|
||||
data-lesson='${JSON.stringify(lesson)}'
|
||||
data-lesson-id='${lesson.lessonId || ""}'
|
||||
data-spans='${slots ? slots.length : 1}'
|
||||
data-lesson-group='${lessonGroupId}'>
|
||||
<div class="lesson-subject">${lesson.subject}</div>
|
||||
<div class="lesson-teacher">${lesson.teacher}</div>
|
||||
${!spansMultiple ? `<div class="lesson-bottom">
|
||||
<div class="lesson-room">${lesson.room}</div>
|
||||
<div class="lesson-time">${lesson.isCancelled ? LanguageManager.t("timetable.cancelled") : lesson.startTime}</div>
|
||||
</div>` : ''}
|
||||
${
|
||||
(() => {
|
||||
const lessonKey = `${lesson.subject}_${lesson.startTime}_${lesson.day}`;
|
||||
const hasCustomHomework = customHomework[lessonKey] && customHomework[lessonKey].length > 0;
|
||||
const hasCustomTests = customTests[lessonKey] && customTests[lessonKey].length > 0;
|
||||
const lessonKey = `${lesson.subject}_${lesson.startTime}_${lesson.date}`;
|
||||
const customHomeworkItems = customHomework[lessonKey] || [];
|
||||
const customTestItems = customTests[lessonKey] || [];
|
||||
const hasCustomHomework = customHomeworkItems.length > 0;
|
||||
const hasCustomTests = customTestItems.length > 0;
|
||||
const allCustomHomeworkCompleted = hasCustomHomework && customHomeworkItems.every(hw => hw.completed);
|
||||
const allCustomTestsCompleted = hasCustomTests && customTestItems.every(test => test.completed);
|
||||
const hasAnyIndicators = lesson.hasHomework || lesson.testInfo || hasCustomHomework || hasCustomTests;
|
||||
|
||||
|
||||
return hasAnyIndicators ? `
|
||||
<div class="lesson-indicators">
|
||||
${
|
||||
@@ -614,18 +715,40 @@
|
||||
}
|
||||
${
|
||||
lesson.testInfo
|
||||
? `
|
||||
<span class="lesson-indicator test-indicator" title="${LanguageManager.t("timetable.test_indicator")}">
|
||||
<img src="${chrome.runtime.getURL("icons/assigment.svg")}" alt="Teszt" style="width: 20px; height: 20px;">
|
||||
? (() => {
|
||||
const testType = lesson.testId ? testTypeMap[lesson.testId] : null;
|
||||
const isKontaktOra = testType === "KONTAKT ÓRA";
|
||||
const isProjektOra = testType === "PROJEKT ÓRA";
|
||||
let indicatorClass = "test-indicator";
|
||||
let iconPath = "icons/assigment.svg";
|
||||
let titleText = LanguageManager.t("timetable.test_indicator");
|
||||
let altText = "Teszt";
|
||||
|
||||
if (isKontaktOra) {
|
||||
indicatorClass = "homework-indicator";
|
||||
iconPath = "icons/contact.svg";
|
||||
titleText = "Kontakt óra";
|
||||
altText = "Kontakt óra";
|
||||
} else if (isProjektOra) {
|
||||
indicatorClass = "homework-indicator";
|
||||
iconPath = "icons/project.svg";
|
||||
titleText = "Projekt óra";
|
||||
altText = "Projekt óra";
|
||||
}
|
||||
|
||||
return `
|
||||
<span class="lesson-indicator ${indicatorClass}" title="${titleText}">
|
||||
<img src="${chrome.runtime.getURL(iconPath)}" alt="${altText}" style="width: 20px; height: 20px;">
|
||||
</span>
|
||||
`
|
||||
`;
|
||||
})()
|
||||
: ""
|
||||
}
|
||||
${
|
||||
hasCustomHomework
|
||||
? `
|
||||
<span class="lesson-indicator custom-homework-indicator" title="Saját házi feladat">
|
||||
<img src="${chrome.runtime.getURL("icons/homework.svg")}" alt="Saját házi feladat" style="width: 20px; height: 20px; opacity: 0.7;">
|
||||
<img src="${chrome.runtime.getURL(allCustomHomeworkCompleted ? "icons/pipa.svg" : "icons/homework.svg")}" alt="${allCustomHomeworkCompleted ? 'Megoldott saját házi feladat' : 'Saját házi feladat'}" style="width: 20px; height: 20px; opacity: 0.7;">
|
||||
</span>
|
||||
`
|
||||
: ""
|
||||
@@ -634,7 +757,7 @@
|
||||
hasCustomTests
|
||||
? `
|
||||
<span class="lesson-indicator custom-test-indicator" title="Saját számonkérés">
|
||||
<img src="${chrome.runtime.getURL("icons/assigment.svg")}" alt="Saját számonkérés" style="width: 20px; height: 20px; opacity: 0.7;">
|
||||
<img src="${chrome.runtime.getURL(allCustomTestsCompleted ? "icons/pipa.svg" : "icons/assigment.svg")}" alt="${allCustomTestsCompleted ? 'Megoldott saját számonkérés' : 'Saját számonkérés'}" style="width: 20px; height: 20px; opacity: 0.7;">
|
||||
</span>
|
||||
`
|
||||
: ""
|
||||
@@ -644,8 +767,8 @@
|
||||
})()
|
||||
}
|
||||
</div>
|
||||
`,
|
||||
)
|
||||
`;
|
||||
})
|
||||
.join("")
|
||||
}
|
||||
</div>
|
||||
@@ -1196,83 +1319,92 @@
|
||||
}
|
||||
|
||||
if (lesson.testInfo) {
|
||||
let testDetails = null;
|
||||
if (lesson.testId) {
|
||||
testDetails = await loadTestDetailsFromAPI(lesson.testId);
|
||||
}
|
||||
|
||||
const isKontaktOra = testDetails && testDetails.type === "KONTAKT ÓRA";
|
||||
const isProjektOra = testDetails && testDetails.type === "PROJEKT ÓRA";
|
||||
const isSpecialType = isKontaktOra || isProjektOra;
|
||||
|
||||
const testSection = document.createElement('div');
|
||||
testSection.className = 'modal-section test-section';
|
||||
|
||||
testSection.className = isSpecialType ? 'modal-section homework-section' : 'modal-section test-section';
|
||||
|
||||
const testH4 = document.createElement('h4');
|
||||
const testIcon = document.createElement('img');
|
||||
testIcon.src = chrome.runtime.getURL('icons/assigment.svg');
|
||||
testIcon.alt = 'Teszt';
|
||||
|
||||
let iconPath = 'icons/assigment.svg';
|
||||
let sectionTitle = LanguageManager.t('timetable.test_indicator');
|
||||
let altText = 'Teszt';
|
||||
|
||||
if (isKontaktOra) {
|
||||
iconPath = 'icons/contact.svg';
|
||||
sectionTitle = 'Kontakt óra';
|
||||
altText = 'Kontakt óra';
|
||||
} else if (isProjektOra) {
|
||||
iconPath = 'icons/project.svg';
|
||||
sectionTitle = 'Projekt óra';
|
||||
altText = 'Projekt óra';
|
||||
}
|
||||
|
||||
testIcon.src = chrome.runtime.getURL(iconPath);
|
||||
testIcon.alt = altText;
|
||||
testIcon.style.width = '20px';
|
||||
testIcon.style.height = '20px';
|
||||
testH4.appendChild(testIcon);
|
||||
testH4.appendChild(document.createTextNode(LanguageManager.t('timetable.test_indicator')));
|
||||
|
||||
testH4.appendChild(document.createTextNode(sectionTitle));
|
||||
if (isSpecialType) {
|
||||
testH4.style.color = 'var(--accent-accent)';
|
||||
}
|
||||
|
||||
const testContent = document.createElement('div');
|
||||
testContent.className = 'test-content';
|
||||
|
||||
if (lesson.testId) {
|
||||
const loadingDiv = document.createElement('div');
|
||||
loadingDiv.className = 'test-details-loading';
|
||||
loadingDiv.textContent = 'Részletek betöltése...';
|
||||
testContent.appendChild(loadingDiv);
|
||||
if (testDetails) {
|
||||
const detailsDiv = document.createElement('div');
|
||||
detailsDiv.className = 'test-details';
|
||||
|
||||
loadTestDetailsFromAPI(lesson.testId).then(testDetails => {
|
||||
loadingDiv.remove();
|
||||
|
||||
if (testDetails) {
|
||||
const detailsDiv = document.createElement('div');
|
||||
detailsDiv.className = 'test-details';
|
||||
|
||||
const nameP = document.createElement('p');
|
||||
const nameStrong = document.createElement('strong');
|
||||
nameStrong.textContent = 'Megnevezés: ';
|
||||
nameP.appendChild(nameStrong);
|
||||
nameP.appendChild(document.createTextNode(testDetails.name));
|
||||
detailsDiv.appendChild(nameP);
|
||||
|
||||
const typeP = document.createElement('p');
|
||||
const typeStrong = document.createElement('strong');
|
||||
typeStrong.textContent = 'Típus: ';
|
||||
typeP.appendChild(typeStrong);
|
||||
typeP.appendChild(document.createTextNode(testDetails.type));
|
||||
detailsDiv.appendChild(typeP);
|
||||
|
||||
const dateP = document.createElement('p');
|
||||
const dateStrong = document.createElement('strong');
|
||||
dateStrong.textContent = 'Bejelentés dátuma: ';
|
||||
dateP.appendChild(dateStrong);
|
||||
dateP.appendChild(document.createTextNode(testDetails.announceDate));
|
||||
detailsDiv.appendChild(dateP);
|
||||
|
||||
testContent.appendChild(detailsDiv);
|
||||
} else {
|
||||
const errorP = document.createElement('p');
|
||||
errorP.className = 'test-details-error';
|
||||
errorP.textContent = 'Nem sikerült betölteni a számonkérés részleteit.';
|
||||
testContent.appendChild(errorP);
|
||||
}
|
||||
}).catch(error => {
|
||||
loadingDiv.remove();
|
||||
const errorP = document.createElement('p');
|
||||
errorP.className = 'test-details-error';
|
||||
errorP.textContent = 'Hiba történt a számonkérés részletek betöltése során.';
|
||||
testContent.appendChild(errorP);
|
||||
});
|
||||
const nameP = document.createElement('p');
|
||||
const nameStrong = document.createElement('strong');
|
||||
nameStrong.textContent = 'Megnevezés: ';
|
||||
nameP.appendChild(nameStrong);
|
||||
nameP.appendChild(document.createTextNode(testDetails.name));
|
||||
detailsDiv.appendChild(nameP);
|
||||
|
||||
const typeP = document.createElement('p');
|
||||
const typeStrong = document.createElement('strong');
|
||||
typeStrong.textContent = 'Típus: ';
|
||||
typeP.appendChild(typeStrong);
|
||||
typeP.appendChild(document.createTextNode(testDetails.type));
|
||||
detailsDiv.appendChild(typeP);
|
||||
|
||||
const dateP = document.createElement('p');
|
||||
const dateStrong = document.createElement('strong');
|
||||
dateStrong.textContent = 'Bejelentés dátuma: ';
|
||||
dateP.appendChild(dateStrong);
|
||||
dateP.appendChild(document.createTextNode(testDetails.announceDate));
|
||||
detailsDiv.appendChild(dateP);
|
||||
|
||||
testContent.appendChild(detailsDiv);
|
||||
} else if (lesson.testId) {
|
||||
const errorP = document.createElement('p');
|
||||
errorP.className = 'test-details-error';
|
||||
errorP.textContent = 'Nem sikerült betölteni a számonkérés részleteit.';
|
||||
testContent.appendChild(errorP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const lessonKey = getLessonKey(lesson);
|
||||
const customTests = await getCustomTests();
|
||||
const customTestItems = customTests[lessonKey] || [];
|
||||
|
||||
|
||||
if (customTestItems.length > 0) {
|
||||
const customTestsDiv = document.createElement('div');
|
||||
customTestsDiv.className = 'custom-tests-in-section';
|
||||
customTestsDiv.style.marginTop = '1rem';
|
||||
customTestsDiv.style.paddingTop = '1rem';
|
||||
customTestsDiv.style.borderTop = '1px solid var(--background-0)';
|
||||
|
||||
|
||||
const customTestsTitle = document.createElement('h5');
|
||||
customTestsTitle.textContent = 'Saját számonkérések:';
|
||||
customTestsTitle.style.fontSize = '14px';
|
||||
@@ -1280,10 +1412,10 @@
|
||||
customTestsTitle.style.color = 'var(--warning-accent)';
|
||||
customTestsTitle.style.marginBottom = '0.5rem';
|
||||
customTestsDiv.appendChild(customTestsTitle);
|
||||
|
||||
|
||||
const customTestsList = document.createElement('div');
|
||||
customTestsList.className = 'custom-tests-list-integrated';
|
||||
|
||||
|
||||
customTestItems.forEach(test => {
|
||||
const testItem = document.createElement('div');
|
||||
testItem.className = `custom-test-item-integrated ${test.completed ? 'completed' : ''}`;
|
||||
@@ -1295,7 +1427,7 @@
|
||||
testItem.style.background = 'var(--background)';
|
||||
testItem.style.borderRadius = '6px';
|
||||
testItem.style.border = '1px solid var(--background-0)';
|
||||
|
||||
|
||||
const testText = document.createElement('span');
|
||||
testText.className = 'test-text-integrated';
|
||||
testText.textContent = test.text;
|
||||
@@ -1305,12 +1437,12 @@
|
||||
testText.style.textDecoration = 'line-through';
|
||||
testText.style.opacity = '0.6';
|
||||
}
|
||||
|
||||
|
||||
const testActions = document.createElement('div');
|
||||
testActions.className = 'test-actions-integrated';
|
||||
testActions.style.display = 'flex';
|
||||
testActions.style.gap = '0.5rem';
|
||||
|
||||
|
||||
const completeBtn = document.createElement('button');
|
||||
completeBtn.className = 'test-complete-btn-integrated';
|
||||
completeBtn.title = test.completed ? 'Megoldva - kattints a visszavonáshoz' : 'Megoldottként jelöl';
|
||||
@@ -1322,7 +1454,7 @@
|
||||
completeBtn.style.display = 'flex';
|
||||
completeBtn.style.alignItems = 'center';
|
||||
completeBtn.style.justifyContent = 'center';
|
||||
|
||||
|
||||
const completeIcon = document.createElement('img');
|
||||
completeIcon.src = chrome.runtime.getURL('icons/pipa.svg');
|
||||
completeIcon.alt = 'Megoldva';
|
||||
@@ -1335,7 +1467,7 @@
|
||||
completeIcon.style.opacity = '0.5';
|
||||
}
|
||||
completeBtn.appendChild(completeIcon);
|
||||
|
||||
|
||||
const deleteBtn = document.createElement('button');
|
||||
deleteBtn.className = 'test-delete-btn-integrated';
|
||||
deleteBtn.title = 'Törlés';
|
||||
@@ -1347,7 +1479,7 @@
|
||||
deleteBtn.style.display = 'flex';
|
||||
deleteBtn.style.alignItems = 'center';
|
||||
deleteBtn.style.justifyContent = 'center';
|
||||
|
||||
|
||||
const deleteIcon = document.createElement('img');
|
||||
deleteIcon.src = chrome.runtime.getURL('icons/delete.svg');
|
||||
deleteIcon.alt = 'Törlés';
|
||||
@@ -1355,7 +1487,7 @@
|
||||
deleteIcon.style.height = '16px';
|
||||
deleteIcon.style.opacity = '0.5';
|
||||
deleteBtn.appendChild(deleteIcon);
|
||||
|
||||
|
||||
completeBtn.addEventListener('click', async () => {
|
||||
const newCompleted = await toggleCustomTestCompletion(lessonKey, test.id);
|
||||
if (newCompleted) {
|
||||
@@ -1372,30 +1504,30 @@
|
||||
completeBtn.title = 'Megoldottként jelöl';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
deleteBtn.addEventListener('click', async () => {
|
||||
if (confirm('Biztosan törölni szeretnéd ezt a számonkérést?')) {
|
||||
await removeCustomTest(lessonKey, test.id);
|
||||
testItem.remove();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
testActions.appendChild(completeBtn);
|
||||
testActions.appendChild(deleteBtn);
|
||||
testItem.appendChild(testText);
|
||||
testItem.appendChild(testActions);
|
||||
customTestsList.appendChild(testItem);
|
||||
});
|
||||
|
||||
|
||||
customTestsDiv.appendChild(customTestsList);
|
||||
testContent.appendChild(customTestsDiv);
|
||||
}
|
||||
|
||||
|
||||
testSection.appendChild(testH4);
|
||||
testSection.appendChild(testContent);
|
||||
body.appendChild(testSection);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const lessonKey = getLessonKey(lesson);
|
||||
const customHomework = await getCustomHomework();
|
||||
@@ -1890,6 +2022,24 @@
|
||||
const lessonData = JSON.parse(card.dataset.lesson);
|
||||
await showLessonModal(lessonData);
|
||||
});
|
||||
|
||||
card.addEventListener("mouseenter", () => {
|
||||
const groupId = card.dataset.lessonGroup;
|
||||
if (groupId) {
|
||||
document.querySelectorAll(`[data-lesson-group="${groupId}"]`).forEach(relatedCard => {
|
||||
relatedCard.classList.add('group-hover');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
card.addEventListener("mouseleave", () => {
|
||||
const groupId = card.dataset.lessonGroup;
|
||||
if (groupId) {
|
||||
document.querySelectorAll(`[data-lesson-group="${groupId}"]`).forEach(relatedCard => {
|
||||
relatedCard.classList.remove('group-hover');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,24 +1,3 @@
|
||||
const SENTRY_DSN = 'https://c7d88b71f550a276f973885a44b6536d@o4510511576055808.ingest.de.sentry.io/4510511935193168';
|
||||
|
||||
async function initSentry() {
|
||||
try {
|
||||
const result = await chrome.storage.sync.get('firka_errorReporting');
|
||||
const enabled = result.firka_errorReporting !== false;
|
||||
|
||||
if (enabled) {
|
||||
self.addEventListener('error', (event) => {
|
||||
console.error('[Background Error]', event.error || event);
|
||||
});
|
||||
|
||||
self.addEventListener('unhandledrejection', (event) => {
|
||||
console.error('[Background Unhandled Rejection]', event.reason);
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Sentry] Nem sikerült inicializálni:', error);
|
||||
}
|
||||
}
|
||||
|
||||
chrome.runtime.onInstalled.addListener(async (details) => {
|
||||
if (details.reason === 'install') {
|
||||
const setupCompleted = await chrome.storage.sync.get('firka_setupCompleted');
|
||||
@@ -29,8 +8,6 @@ chrome.runtime.onInstalled.addListener(async (details) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await initSentry();
|
||||
});
|
||||
|
||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
@@ -57,6 +34,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
case 'download_attachment':
|
||||
const downloadResult = await handleDownloadAttachment(request.azonosito, request.fileName);
|
||||
sendResponse(downloadResult);
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('[Background] Unknown action:', request.action);
|
||||
sendResponse({ success: false, error: 'Unknown action' });
|
||||
@@ -102,7 +84,7 @@ async function handleStorageClear() {
|
||||
try {
|
||||
const allData = await chrome.storage.sync.get(null);
|
||||
const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
|
||||
|
||||
|
||||
if (firkaKeys.length > 0) {
|
||||
await chrome.storage.sync.remove(firkaKeys);
|
||||
}
|
||||
@@ -112,6 +94,82 @@ async function handleStorageClear() {
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDownloadAttachment(azonosito, fileName) {
|
||||
try {
|
||||
const apiUrl = `https://eugyintezes.e-kreta.hu/api/v1/dokumentumok/uzenetek/${azonosito}`;
|
||||
|
||||
const redirectResponse = await fetch(apiUrl, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase',
|
||||
'x-uzenet-lokalizacio': 'hu-HU',
|
||||
'x-uzenet-verzio-szam': '1.2.3'
|
||||
},
|
||||
redirect: 'manual'
|
||||
});
|
||||
|
||||
let fileUrl;
|
||||
if (redirectResponse.type === 'opaqueredirect' || redirectResponse.status === 0) {
|
||||
const followResponse = await fetch(apiUrl, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase',
|
||||
'x-uzenet-lokalizacio': 'hu-HU',
|
||||
'x-uzenet-verzio-szam': '1.2.3'
|
||||
},
|
||||
redirect: 'follow'
|
||||
});
|
||||
|
||||
if (followResponse.ok) {
|
||||
const blob = await followResponse.blob();
|
||||
const base64 = await blobToBase64(blob);
|
||||
return { success: true, data: base64, fileName: fileName };
|
||||
}
|
||||
} else if (redirectResponse.status === 302 || redirectResponse.status === 301) {
|
||||
fileUrl = redirectResponse.headers.get('location');
|
||||
}
|
||||
|
||||
if (fileUrl) {
|
||||
const fileResponse = await fetch(fileUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'x-csrf': '1',
|
||||
'x-uzenet-json-formatum': 'CamelCase',
|
||||
'x-uzenet-lokalizacio': 'hu-HU',
|
||||
'x-uzenet-verzio-szam': '1.2.3'
|
||||
}
|
||||
});
|
||||
|
||||
if (fileResponse.ok) {
|
||||
const blob = await fileResponse.blob();
|
||||
const base64 = await blobToBase64(blob);
|
||||
return { success: true, data: base64, fileName: fileName };
|
||||
}
|
||||
}
|
||||
|
||||
return { success: false, error: 'Nem sikerült letölteni a mellékletet.' };
|
||||
} catch (error) {
|
||||
console.error('[Background] Attachment download error:', error);
|
||||
return { success: false, error: error.message };
|
||||
}
|
||||
}
|
||||
|
||||
function blobToBase64(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => resolve(reader.result);
|
||||
reader.onerror = reject;
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||
if (namespace === 'sync') {
|
||||
const firkaChanges = Object.keys(changes).filter(key => key.startsWith('firka_'));
|
||||
|
||||
3
tools/sentry-browser.min.js
vendored
127
tools/sentry.js
@@ -1,127 +0,0 @@
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const SENTRY_DSN = 'https://c7d88b71f550a276f973885a44b6536d@o4510511576055808.ingest.de.sentry.io/4510511935193168';
|
||||
let sentryInitialized = false;
|
||||
|
||||
async function isErrorReportingEnabled() {
|
||||
try {
|
||||
const result = await chrome.storage.sync.get('firka_errorReporting');
|
||||
return result.firka_errorReporting !== false;
|
||||
} catch (error) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
async function initSentry() {
|
||||
if (sentryInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
const enabled = await isErrorReportingEnabled();
|
||||
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
configureSentry();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function configureSentry() {
|
||||
try {
|
||||
const SentrySDK = window.Sentry || (typeof Sentry !== 'undefined' ? Sentry : null);
|
||||
|
||||
if (!SentrySDK) {
|
||||
setTimeout(configureSentry, 500);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SentrySDK.init) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
|
||||
SentrySDK.init({
|
||||
dsn: SENTRY_DSN,
|
||||
release: `firka-extension@${manifest.version}`,
|
||||
environment: 'production',
|
||||
integrations: [],
|
||||
beforeSend(event, hint) {
|
||||
if (event.request) {
|
||||
delete event.request.cookies;
|
||||
delete event.request.headers;
|
||||
}
|
||||
return event;
|
||||
},
|
||||
});
|
||||
|
||||
sentryInitialized = true;
|
||||
} catch (error) {
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('error', function(event) {
|
||||
if (sentryInitialized) {
|
||||
const SentrySDK = window.Sentry || (typeof Sentry !== 'undefined' ? Sentry : null);
|
||||
if (SentrySDK && SentrySDK.captureException) {
|
||||
SentrySDK.captureException(event.error || new Error(event.message));
|
||||
} else {
|
||||
console.warn('[Sentry] SDK not available for capturing');
|
||||
}
|
||||
} else {
|
||||
console.warn('[Sentry] Not initialized yet, cannot capture error');
|
||||
}
|
||||
}, true);
|
||||
|
||||
window.addEventListener('unhandledrejection', function(event) {
|
||||
if (sentryInitialized) {
|
||||
const SentrySDK = window.Sentry || (typeof Sentry !== 'undefined' ? Sentry : null);
|
||||
if (SentrySDK && SentrySDK.captureException) {
|
||||
SentrySDK.captureException(event.reason);
|
||||
}
|
||||
}
|
||||
}, true);
|
||||
|
||||
if (typeof chrome !== 'undefined' && chrome.storage) {
|
||||
chrome.storage.onChanged.addListener(function(changes, namespace) {
|
||||
if (namespace === 'sync' && changes.firka_errorReporting) {
|
||||
const newValue = changes.firka_errorReporting.newValue;
|
||||
|
||||
if (newValue === false && sentryInitialized) {
|
||||
if (typeof Sentry !== 'undefined' && Sentry.close) {
|
||||
Sentry.close();
|
||||
sentryInitialized = false;
|
||||
}
|
||||
} else if (newValue !== false && !sentryInitialized) {
|
||||
initSentry();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.FirkaSentry = {
|
||||
init: initSentry,
|
||||
isEnabled: isErrorReportingEnabled,
|
||||
captureException: function(error) {
|
||||
if (sentryInitialized) {
|
||||
const SentrySDK = window.Sentry || (typeof Sentry !== 'undefined' ? Sentry : null);
|
||||
if (SentrySDK && SentrySDK.captureException) {
|
||||
SentrySDK.captureException(error);
|
||||
}
|
||||
}
|
||||
},
|
||||
captureMessage: function(message, level = 'info') {
|
||||
if (sentryInitialized) {
|
||||
const SentrySDK = window.Sentry || (typeof Sentry !== 'undefined' ? Sentry : null);
|
||||
if (SentrySDK && SentrySDK.captureMessage) {
|
||||
SentrySDK.captureMessage(message, level);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
initSentry();
|
||||
})();
|
||||