mirror of
https://github.com/QwIT-Development/firka-extension.git
synced 2026-06-12 03:41:39 +02:00
450 lines
15 KiB
JavaScript
450 lines
15 KiB
JavaScript
const DashboardUtils = {
|
|
formatGradeValue(value) {
|
|
const trimmedValue = value?.trim() || '';
|
|
if (trimmedValue.toLowerCase() === 'szöveges') {
|
|
return 'Sz';
|
|
}
|
|
return trimmedValue;
|
|
},
|
|
|
|
parseDate(dateStr) {
|
|
return dateStr?.trim() || '';
|
|
},
|
|
|
|
formatHungarianDate(dateStr) {
|
|
if (!dateStr) return '';
|
|
|
|
const dateParts = dateStr.trim().split('.');
|
|
if (dateParts.length < 3) return dateStr;
|
|
|
|
const month = parseInt(dateParts[1], 10);
|
|
const day = parseInt(dateParts[2], 10);
|
|
|
|
if (isNaN(month) || month < 1 || month > 12) return dateStr;
|
|
|
|
if (typeof window.LanguageManager !== 'undefined') {
|
|
const monthKeys = [
|
|
'months.january', 'months.february', 'months.march', 'months.april',
|
|
'months.may', 'months.june', 'months.july', 'months.august',
|
|
'months.september', 'months.october', 'months.november', 'months.december'
|
|
];
|
|
const monthName = window.LanguageManager.t(monthKeys[month - 1]);
|
|
return `${monthName} ${day}.`;
|
|
}
|
|
|
|
const monthKeys = [
|
|
'months.january', 'months.february', 'months.march', 'months.april', 'months.may', 'months.june',
|
|
'months.july', 'months.august', 'months.september', 'months.october', 'months.november', 'months.december'
|
|
];
|
|
|
|
return `${LanguageManager.t(monthKeys[month - 1])} ${day}.`;
|
|
}
|
|
};
|
|
|
|
class DashboardDataManager {
|
|
constructor() {
|
|
this.dashboardData = {
|
|
grades: [],
|
|
absences: [],
|
|
notes: [],
|
|
upcomingExams: [],
|
|
news: []
|
|
};
|
|
}
|
|
|
|
extractGradeData() {
|
|
const gradeRows = document.querySelectorAll('#legutobbiErtekelesek tr:not(:first-child)');
|
|
|
|
this.dashboardData.grades = Array.from(gradeRows).map(row => {
|
|
const gradeValue = row.querySelector('span[style*="font-size: 200%"]')?.textContent;
|
|
const gradeInfo = row.querySelector('span[style*="float: right"]')?.textContent;
|
|
|
|
if (!gradeValue || !gradeInfo) return null;
|
|
|
|
const [fullSubject, date] = gradeInfo.split('\n').map(str => str.trim());
|
|
const { subject, type, dateInSubject } = this.parseSubjectInformation(fullSubject);
|
|
|
|
return {
|
|
value: DashboardUtils.formatGradeValue(gradeValue),
|
|
subject,
|
|
date: DashboardUtils.parseDate(date),
|
|
type: type || LanguageManager.t('dashboard.evaluation'),
|
|
dateInSubject: dateInSubject || null
|
|
};
|
|
}).filter(Boolean);
|
|
}
|
|
|
|
parseSubjectInformation(fullSubject) {
|
|
const hungarianMonths = ['január', 'február', 'március', 'április', 'május', 'június',
|
|
'július', 'augusztus', 'szeptember', 'október', 'november', 'december'];
|
|
const monthPattern = hungarianMonths.join('|');
|
|
const datePattern = new RegExp(`(${monthPattern})\\s+(\\d{1,2})\\.?$`, 'i');
|
|
const dateMatch = fullSubject.match(datePattern);
|
|
|
|
if (dateMatch) {
|
|
const subjectPart = fullSubject.substring(0, dateMatch.index).trim();
|
|
const datePart = dateMatch[0].trim();
|
|
return {
|
|
subject: subjectPart,
|
|
type: '',
|
|
dateInSubject: datePart
|
|
};
|
|
}
|
|
|
|
const months = [
|
|
LanguageManager.t('months.january'), LanguageManager.t('months.february'), LanguageManager.t('months.march'),
|
|
LanguageManager.t('months.april'), LanguageManager.t('months.may'), LanguageManager.t('months.june'),
|
|
LanguageManager.t('months.july'), LanguageManager.t('months.august'), LanguageManager.t('months.september'),
|
|
LanguageManager.t('months.october'), LanguageManager.t('months.november'), LanguageManager.t('months.december')
|
|
];
|
|
const fallbackMonthPattern = new RegExp(months.join('|'), 'i');
|
|
const monthMatch = fullSubject.match(fallbackMonthPattern);
|
|
|
|
if (monthMatch) {
|
|
const monthIndex = fullSubject.lastIndexOf(monthMatch[0]);
|
|
return {
|
|
subject: fullSubject.substring(0, monthIndex).trim(),
|
|
type: fullSubject.substring(monthIndex).trim()
|
|
};
|
|
}
|
|
|
|
return { subject: fullSubject, type: '' };
|
|
}
|
|
|
|
extractAbsenceData() {
|
|
const absenceRows = document.querySelectorAll('#legutobbiMulasztasok tr:not(:first-child)');
|
|
|
|
this.dashboardData.absences = Array.from(absenceRows).map(row => {
|
|
const spans = row.querySelectorAll('span');
|
|
if (spans.length < 4) return null;
|
|
|
|
return {
|
|
date: spans[0]?.textContent?.trim() || '',
|
|
day: spans[2]?.textContent?.trim() || '',
|
|
type: spans[1]?.textContent?.trim() || '',
|
|
count: spans[3]?.textContent?.trim() || ''
|
|
};
|
|
}).filter(Boolean);
|
|
}
|
|
|
|
extractNoteData() {
|
|
const noteRows = document.querySelectorAll('#legutobbiFeljegyzesek tr:not(:first-child)');
|
|
|
|
this.dashboardData.notes = Array.from(noteRows).map(row => {
|
|
const spans = row.querySelectorAll('span');
|
|
if (spans.length < 3) return null;
|
|
|
|
return {
|
|
title: spans[0]?.textContent?.trim() || '',
|
|
author: spans[1]?.textContent?.trim() || '',
|
|
date: spans[2]?.textContent?.trim() || ''
|
|
};
|
|
}).filter(Boolean);
|
|
}
|
|
|
|
extractExamData() {
|
|
const examRows = document.querySelectorAll('#legutobbiBejelentettSzamonkeres tr:not(:first-child)');
|
|
|
|
this.dashboardData.upcomingExams = Array.from(examRows).map(row => {
|
|
const spans = row.querySelectorAll('span');
|
|
if (spans.length < 4) return null;
|
|
|
|
return {
|
|
date: spans[0]?.textContent?.trim() || '',
|
|
subject: spans[1]?.textContent?.trim() || '',
|
|
day: spans[2]?.textContent?.trim() || '',
|
|
type: spans[3]?.textContent?.trim() || ''
|
|
};
|
|
}).filter(Boolean);
|
|
}
|
|
|
|
async extractNewsData() {
|
|
|
|
try {
|
|
const timestamp = Date.now();
|
|
const apiUrl = `https://${window.location.hostname}/Intezmeny/Faliujsag/GetMoreEntries?startindex=0&range=10&_=${timestamp}`;
|
|
|
|
const response = await fetch(apiUrl, {
|
|
method: 'GET',
|
|
credentials: 'include',
|
|
headers: {
|
|
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
'X-Requested-With': 'XMLHttpRequest'
|
|
}
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`API request failed with status: ${response.status}`);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (!data.FaliujsagElemek || !Array.isArray(data.FaliujsagElemek)) {
|
|
return;
|
|
}
|
|
|
|
data.FaliujsagElemek.forEach((item, index) => {
|
|
let formattedDate = '';
|
|
if (item.DatumNap && item.DatumHonap && item.DatumEv) {
|
|
formattedDate = `${item.DatumEv}. ${item.DatumHonap} ${item.DatumNap}.`;
|
|
} else if (item.Idopont) {
|
|
const match = item.Idopont.match(/\/Date\((\d+)\)\//);
|
|
if (match) {
|
|
const timestamp = parseInt(match[1]);
|
|
const date = new Date(timestamp);
|
|
formattedDate = date.toLocaleDateString('hu-HU');
|
|
}
|
|
}
|
|
|
|
if (!formattedDate) {
|
|
formattedDate = new Date().toLocaleDateString('hu-HU');
|
|
}
|
|
|
|
let cleanContent = item.EsemenySzovege || '';
|
|
cleanContent = cleanContent.replace(/<[^>]*>/g, '');
|
|
cleanContent = cleanContent.replace(/\r\n/g, ' ');
|
|
cleanContent = cleanContent.replace(/\s+/g, ' ').trim();
|
|
|
|
const newsItem = {
|
|
title: item.EsemenyCime || `Hír ${index + 1}`,
|
|
content: cleanContent || 'Nincs elérhető tartalom',
|
|
date: formattedDate,
|
|
author: `${item.Nev || 'Ismeretlen'} (${item.Munkakor || 'Ismeretlen'})`
|
|
};
|
|
|
|
this.dashboardData.news.push(newsItem);
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error fetching news from API:', error);
|
|
}
|
|
}
|
|
|
|
async extractAllData() {
|
|
this.extractGradeData();
|
|
this.extractAbsenceData();
|
|
this.extractNoteData();
|
|
this.extractExamData();
|
|
await this.extractNewsData();
|
|
return this.dashboardData;
|
|
}
|
|
}
|
|
|
|
class DashboardRenderer {
|
|
constructor(data) {
|
|
this.data = {
|
|
...data,
|
|
schoolInfo: {
|
|
name: cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
|
id: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || ''
|
|
},
|
|
userData: {
|
|
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
|
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
|
}
|
|
};
|
|
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
|
|
this.shortenedSchoolName = helper.shortenSchoolName(this.schoolNameFull);
|
|
}
|
|
|
|
generateMainContent() {
|
|
return `
|
|
<main class="kreta-main">
|
|
<div class="grid-container">
|
|
${this.createGradeCard()}
|
|
${this.createAbsenceCard()}
|
|
${this.createNoteCard()}
|
|
${this.createExamCard()}
|
|
${this.createNewsCard()}
|
|
</div>
|
|
</main>
|
|
`;
|
|
}
|
|
createNewsCard() {
|
|
const newsItems = this.data.news.map(news => `
|
|
<div class="widget-item news-item">
|
|
<div class="widget-row">
|
|
<div class="widget-details news-details">
|
|
<div class="widget-title news-title">${news.title}</div>
|
|
<div class="widget-content news-content">${news.content}</div>
|
|
</div>
|
|
<div class="widget-meta">
|
|
${news.date ? `<div class="widget-date news-date">${news.date}</div>` : ''}
|
|
${news.author ? `<div class="widget-author news-author">${news.author}</div>` : ''}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
return this.createCard(LanguageManager.t('dashboard.news'), newsItems || LanguageManager.t('dashboard.not_supported'), '/Intezmeny/Faliujsag', LanguageManager.t('dashboard.all_news'));
|
|
}
|
|
|
|
createGradeCard() {
|
|
const gradeItems = this.data.grades.map(grade => `
|
|
<div class="widget-item grade-item">
|
|
<div class="widget-row grade-row">
|
|
<div class="grade grade-${grade.value}">${grade.value}</div>
|
|
<div class="widget-details grade-details">
|
|
<div class="widget-title subject-name">${grade.subject}</div>
|
|
<div class="grade-type-with-date">
|
|
<div class="widget-subtitle grade-type">${grade.type}</div>
|
|
${grade.dateInSubject || grade.date ? `<div class="widget-subtitle grade-date">${grade.dateInSubject || grade.date}</div>` : ''}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
return this.createCard(LanguageManager.t('dashboard.grades'), gradeItems, '/TanuloErtekeles/Osztalyzatok', LanguageManager.t('dashboard.all_grades'));
|
|
}
|
|
|
|
createAbsenceCard() {
|
|
const absenceItems = this.data.absences.map(absence => `
|
|
<div class="widget-item absence-item">
|
|
<div class="widget-row">
|
|
<div class="widget-details absence-details">
|
|
<div class="widget-title absence-type">${absence.type}</div>
|
|
<div class="widget-subtitle absence-date">${absence.date}</div>
|
|
</div>
|
|
${absence.day ? `<div class="widget-date">${absence.day}</div>` : ''}
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
return this.createCard(LanguageManager.t('dashboard.absences'), absenceItems, '/Hianyzas/Hianyzasok', LanguageManager.t('dashboard.all_absences'));
|
|
}
|
|
|
|
createNoteCard() {
|
|
const noteItems = this.data.notes.map(note => `
|
|
<div class="widget-item note-item">
|
|
<div class="widget-row">
|
|
<div class="widget-details note-details">
|
|
<div class="widget-title note-title">${note.title}</div>
|
|
<div class="widget-subtitle note-date">${note.date}</div>
|
|
</div>
|
|
${note.author ? `<div class="widget-author note-author">${note.author}</div>` : ''}
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
return this.createCard(LanguageManager.t('dashboard.notes'), noteItems, '/TanuloErtekeles/InformaciokFeljegyzesek', LanguageManager.t('dashboard.all_messages'));
|
|
}
|
|
|
|
createExamCard() {
|
|
const examItems = this.data.upcomingExams.map(exam => `
|
|
<div class="widget-item exam-item">
|
|
<div class="widget-row">
|
|
<div class="widget-details exam-details">
|
|
<div class="widget-title exam-subject">${exam.subject}</div>
|
|
<div class="widget-subtitle exam-type">${exam.type || ''}</div>
|
|
</div>
|
|
<div class="widget-date exam-date">${DashboardUtils.formatHungarianDate(exam.date)}</div>
|
|
</div>
|
|
</div>
|
|
`).join('');
|
|
|
|
return this.createCard(LanguageManager.t('dashboard.exams'), examItems, '/Tanulo/TanuloBejelentettSzamonkeresek', LanguageManager.t('dashboard.all_exams'));
|
|
}
|
|
|
|
createCard(title, content, linkHref, linkText) {
|
|
return `
|
|
<div class="widget-card card">
|
|
<div class="widget-header">
|
|
<h2 class="widget-card-title">${title}</h2>
|
|
</div>
|
|
<div class="widget-content card-content">
|
|
${content || `<div class="widget-empty">${LanguageManager.t('dashboard.not_supported')}</div>`}
|
|
</div>
|
|
<div class="widget-footer">
|
|
<a href="${linkHref}" class="widget-link more-link">
|
|
${linkText}
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="17" viewBox="0 0 16 17" fill="none">
|
|
<path d="M11.2997 5.19947L5.64282 5.19947M11.2997 5.19947L11.2997 10.8563M11.2997 5.19947L4.70001 11.7991" stroke="var(--accent-accent)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
</svg>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
render() {
|
|
document.body.innerHTML = `
|
|
<div class="kreta-container">
|
|
${createTemplate.header()}
|
|
${this.generateMainContent()}
|
|
</div>
|
|
`;
|
|
setupUserDropdown();
|
|
}
|
|
}
|
|
|
|
class DashboardApplication {
|
|
constructor() {
|
|
this.init();
|
|
}
|
|
|
|
async init() {
|
|
if (!window.location.href.includes('/Intezmeny/Faliujsag')) {
|
|
return;
|
|
}
|
|
|
|
while (typeof window.LanguageManager === 'undefined' ||
|
|
!window.LanguageManager.t('dashboard.grades') ||
|
|
window.LanguageManager.t('dashboard.grades') === 'dashboard.grades') {
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
}
|
|
|
|
while (!document.querySelector('.faliujsag-lista, #faliujsagLista')) {
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
}
|
|
let newsItemsFound = false;
|
|
let attempts = 0;
|
|
const maxAttempts = 50;
|
|
|
|
while (!newsItemsFound && attempts < maxAttempts) {
|
|
const newsContainer = document.querySelector('.faliujsag-lista, #faliujsagLista');
|
|
if (newsContainer) {
|
|
const possibleSelectors = [
|
|
'.nb-item',
|
|
'.news-item',
|
|
'.faliujsag-item',
|
|
'.list-group-item',
|
|
'li',
|
|
'div[class*="item"]',
|
|
'div[class*="news"]'
|
|
];
|
|
|
|
for (const selector of possibleSelectors) {
|
|
const items = newsContainer.querySelectorAll(selector);
|
|
if (items.length > 0) {
|
|
newsItemsFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!newsItemsFound) {
|
|
if (newsContainer.children.length > 0 || newsContainer.textContent.trim().length > 0) {
|
|
newsItemsFound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!newsItemsFound) {
|
|
attempts++;
|
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
}
|
|
}
|
|
|
|
try {
|
|
const dataManager = new DashboardDataManager();
|
|
const dashboardData = await dataManager.extractAllData();
|
|
createTemplate.importFonts();
|
|
const renderer = new DashboardRenderer(dashboardData);
|
|
renderer.render();
|
|
} catch (error) {
|
|
console.error('Error initializing dashboard:', error);
|
|
}
|
|
}
|
|
}
|
|
|
|
new DashboardApplication(); |