Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86cab01fba | ||
|
|
eb3924f60f | ||
|
|
8c57152fe4 | ||
|
|
9d877a1d68 | ||
|
|
1ca8e24805 | ||
|
|
8a8d81b67f | ||
|
|
245142c833 | ||
|
|
7e1d4cd9a7 | ||
|
|
f29f7a2366 | ||
|
|
6e0d3b6b7f | ||
|
|
9fd0190ab8 | ||
|
|
94fbc472f6 | ||
|
|
96be6471f0 | ||
|
|
10cabc3889 | ||
|
|
6cddce142c | ||
|
|
f81d821c56 | ||
|
|
0a5439acfd | ||
|
|
dac927cf7d | ||
|
|
b4a270a8d2 | ||
|
|
110ba0d4fb | ||
|
|
1ba976e06e | ||
|
|
df8adf65de | ||
|
|
e96c9e1c83 | ||
|
|
a3631d749f | ||
|
|
fa7c773393 | ||
|
|
a39295ae68 | ||
|
|
d722740bdf | ||
|
|
1218d3b905 | ||
|
|
bbe8a4b2b3 |
@@ -1,436 +1,485 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}.kreta-container {
|
||||
min-height:100vh;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.kreta-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
display:grid;
|
||||
grid-template-columns:minmax(300px,400px) 1fr minmax(200px,300px);
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
@media (max-width:1200px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: minmax(250px, 350px) 1fr minmax(180px, 250px);
|
||||
}
|
||||
grid-template-columns:minmax(250px,350px) 1fr minmax(180px,250px);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
}@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
padding:1rem;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
margin: 0;
|
||||
}.school-info {
|
||||
margin:0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
grid-area:school;
|
||||
max-width:none;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}.logo-text {
|
||||
color:var(--text-primary);
|
||||
font-size:24px;
|
||||
font-weight:600;
|
||||
margin:0 0 0.5rem;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
margin:0;
|
||||
font-size:20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.5rem;
|
||||
}.logo {
|
||||
width:24px;
|
||||
border-radius:8px;
|
||||
margin-right:0.5rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.school-details span {
|
||||
display: block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
display:block;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
max-width:300px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.school-details span {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
}
|
||||
max-width:200px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
.school-details {
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
}.user-profile {
|
||||
position:relative;
|
||||
justify-self:flex-end;
|
||||
}
|
||||
@media (max-width:768px) {
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
grid-area:user;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
}.user-dropdown-btn {
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--card-card);
|
||||
background:var(--card-card);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
width: 200px;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
position:absolute;
|
||||
top:100%;
|
||||
right:0;
|
||||
margin-top:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
box-shadow:0 4px 6px -1px rgba(0,0,0,0.1);
|
||||
width:200px;
|
||||
display:none;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.user-dropdown.show {
|
||||
display: block;
|
||||
animation: dropdownShow 0.2s ease;
|
||||
display:block;
|
||||
animation:dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.75rem;
|
||||
padding:0.75rem 1rem;
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
background:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
flex:1;
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
max-width:1200px;
|
||||
margin:0 auto;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
|
||||
.filter-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
padding: 20px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
border-radius:24px;
|
||||
padding:20px;
|
||||
margin-bottom:24px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.filter-header {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.filter-header h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--card-card);
|
||||
font-size:18px;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--card-card);
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
display:grid;
|
||||
grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
|
||||
gap:16px;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.filter-group label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.filter-input {
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
background: var(--button-secondaryFill);
|
||||
color: var(--text-primary);
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
transition: all 0.2s ease;
|
||||
padding:10px;
|
||||
border:none;
|
||||
border-radius:8px;
|
||||
background:var(--button-secondaryFill);
|
||||
color:var(--text-primary);
|
||||
font-family:inherit;
|
||||
font-size:14px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
|
||||
.filter-input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px var(--accent-accent);
|
||||
outline:none;
|
||||
box-shadow:0 0 0 2px var(--accent-accent);
|
||||
}
|
||||
.stats-overview {
|
||||
display:grid;
|
||||
grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
|
||||
gap:16px;
|
||||
margin-bottom:24px;
|
||||
}
|
||||
.stat-card {
|
||||
background:var(--card-card);
|
||||
border-radius:16px;
|
||||
padding:20px;
|
||||
text-align:center;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
.stat-card:hover {
|
||||
transform:translateY(-2px);
|
||||
}
|
||||
.stat-number {
|
||||
font-size:32px;
|
||||
font-weight:700;
|
||||
color:var(--accent-accent);
|
||||
margin-bottom:8px;
|
||||
}
|
||||
.stat-label {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
|
||||
.absences-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
background:var(--card-card);
|
||||
border-radius:16px;
|
||||
overflow:hidden;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.absence-group {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 0.3s ease;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
.absences-table {
|
||||
width:100%;
|
||||
border-collapse:collapse;
|
||||
}
|
||||
|
||||
.absence-date {
|
||||
padding: 16px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
.table-header {
|
||||
background:var(--accent-15);
|
||||
border-bottom:1px solid var(--accent-30);
|
||||
}
|
||||
|
||||
.absence-count {
|
||||
margin-left: auto;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
.table-header th {
|
||||
padding:16px;
|
||||
text-align:left;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
font-size:14px;
|
||||
text-transform:uppercase;
|
||||
letter-spacing:0.5px;
|
||||
}
|
||||
|
||||
.absence-list {
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
.table-row {
|
||||
border-bottom:1px solid var(--accent-15);
|
||||
transition:background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.absence-item {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 12px;
|
||||
background: var(--accent-15);
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
.table-row:hover {
|
||||
background:var(--accent-10);
|
||||
}
|
||||
|
||||
.absence-item:hover {
|
||||
transform: translateX(4px);
|
||||
.table-row:last-child {
|
||||
border-bottom:none;
|
||||
}
|
||||
|
||||
.absence-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
.table-cell {
|
||||
padding:16px;
|
||||
color:var(--text-primary);
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
.absence-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
.date-cell {
|
||||
font-weight:600;
|
||||
color:var(--accent-accent);
|
||||
}
|
||||
.lesson-cell {
|
||||
text-align:center;
|
||||
font-weight:500;
|
||||
}
|
||||
.subject-cell {
|
||||
font-weight:600;
|
||||
}
|
||||
.topic-cell {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
max-width:200px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.status-cell {
|
||||
text-align:center;
|
||||
}
|
||||
.status-badge {
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:4px;
|
||||
padding:6px 12px;
|
||||
border-radius:20px;
|
||||
font-size:12px;
|
||||
font-weight:600;
|
||||
text-transform:uppercase;
|
||||
letter-spacing:0.5px;
|
||||
}
|
||||
.status-badge.justified {
|
||||
background:var(--grades-4-bg);
|
||||
color:var(--grades-4);
|
||||
}
|
||||
.status-badge.unjustified {
|
||||
background:var(--grades-1-bg);
|
||||
color:var(--grades-1);
|
||||
}
|
||||
.status-badge.pending {
|
||||
background:var(--grades-3-bg);
|
||||
color:var(--grades-3);
|
||||
}
|
||||
@media (max-width:768px) {
|
||||
.absences-table {
|
||||
font-size:14px;
|
||||
}
|
||||
.table-header th,.table-cell {
|
||||
padding:12px 8px;
|
||||
}
|
||||
.topic-cell {
|
||||
max-width:120px;
|
||||
}
|
||||
.stats-overview {
|
||||
grid-template-columns:repeat(2,1fr);
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.absences-table,.table-header,.table-row {
|
||||
display:block;
|
||||
}
|
||||
.table-header {
|
||||
display:none;
|
||||
}
|
||||
.date-group {
|
||||
margin-bottom:24px;
|
||||
}
|
||||
.date-group-header {
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
padding:12px 16px;
|
||||
border-radius:12px 12px 0 0;
|
||||
font-weight:600;
|
||||
font-size:16px;
|
||||
margin-bottom:0;
|
||||
}
|
||||
.date-group-content {
|
||||
background:var(--card-card);
|
||||
border:1px solid var(--accent-15);
|
||||
border-radius:0 0 12px 12px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.table-row {
|
||||
width:100%;
|
||||
margin-bottom:0;
|
||||
border:none;
|
||||
border-bottom:1px solid var(--accent-15);
|
||||
border-radius:0;
|
||||
padding:16px;
|
||||
background:transparent;
|
||||
}
|
||||
.table-row:last-child {
|
||||
border-bottom:none;
|
||||
}
|
||||
.table-cell {
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:flex-start;
|
||||
padding:6px 0;
|
||||
border-bottom:1px solid var(--accent-15);
|
||||
}
|
||||
.table-cell:last-child {
|
||||
border-bottom:none;
|
||||
}
|
||||
.table-cell::before {
|
||||
content:attr(data-label);
|
||||
font-weight:600;
|
||||
color:var(--text-secondary);
|
||||
font-size:12px;
|
||||
text-transform:uppercase;
|
||||
flex-shrink:0;
|
||||
}
|
||||
.topic-cell {
|
||||
max-width:none;
|
||||
white-space:normal;
|
||||
text-overflow:initial;
|
||||
overflow:visible;
|
||||
text-align:right;
|
||||
flex:1;
|
||||
}
|
||||
.stats-overview {
|
||||
grid-template-columns:1fr;
|
||||
}
|
||||
}.absence-details {
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:4px;
|
||||
}
|
||||
|
||||
.absence-subject {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
.absence-topic {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.absence-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:4px;
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
.absence-status.justified {
|
||||
color: var(--grades-4);
|
||||
color:var(--grades-4);
|
||||
}
|
||||
|
||||
.absence-status.unjustified {
|
||||
color: var(--grades-1);
|
||||
color:var(--grades-1);
|
||||
}
|
||||
|
||||
.absence-status.pending {
|
||||
color: var(--grades-3);
|
||||
color:var(--grades-3);
|
||||
}
|
||||
|
||||
|
||||
.loading-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: var(--background);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:var(--background);
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
z-index:9999;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
padding: 2rem;
|
||||
border-radius: 24px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
padding:2rem;
|
||||
border-radius:24px;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: var(--Text-Primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--Text-Primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.loading-text2 {
|
||||
align-self: stretch;
|
||||
color: var(--Text-Secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--Text-Secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-bottom: 1rem;
|
||||
border-radius: 8px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
margin-bottom:1rem;
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@keyframes spin {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
transform:rotate(360deg);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: clamp(4px, 1vw, 8px);
|
||||
height: clamp(4px, 1vw, 8px);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
}
|
||||
@@ -1,25 +1,30 @@
|
||||
async function collectAbsencesData() {
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get('schoolName') || 'Iskola',
|
||||
id: cookieManager.get('schoolCode') || ''
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get('userName') || 'Felhasználó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00'
|
||||
}
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const currentDomain = window.location.hostname;
|
||||
const response = await fetch(`https://${currentDomain}/api/HianyzasokApi/GetHianyzasGrid?sort=MulasztasDatum-desc&page=1&pageSize=100&group=&filter=&data=%7B%7D&_=${Date.now()}`, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
const response = await fetch(
|
||||
`https://${currentDomain}/api/HianyzasokApi/GetHianyzasGrid?sort=MulasztasDatum-desc&page=1&pageSize=100&group=&filter=&data=%7B%7D&_=${Date.now()}`,
|
||||
{
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json, text/javascript, */*; q=0.01",
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
@@ -29,33 +34,33 @@ async function collectAbsencesData() {
|
||||
const absences = [];
|
||||
|
||||
if (apiData.Data && Array.isArray(apiData.Data)) {
|
||||
apiData.Data.forEach(item => {
|
||||
apiData.Data.forEach((item) => {
|
||||
const date = new Date(item.MulasztasDatum);
|
||||
const formattedDate = `${date.getFullYear()}.${(date.getMonth() + 1).toString().padStart(2, '0')}.${date.getDate().toString().padStart(2, '0')}.`;
|
||||
const formattedDate = `${date.getFullYear()}.${(date.getMonth() + 1).toString().padStart(2, "0")}.${date.getDate().toString().padStart(2, "0")}.`;
|
||||
|
||||
let justificationStatus = 'pending';
|
||||
let justificationStatus = "pending";
|
||||
if (item.Igazolt_BOOL === true) {
|
||||
justificationStatus = 'justified';
|
||||
justificationStatus = "justified";
|
||||
} else if (item.Igazolt_BOOL === false && item.IgazolasTipus !== null) {
|
||||
justificationStatus = 'unjustified';
|
||||
justificationStatus = "unjustified";
|
||||
}
|
||||
|
||||
absences.push({
|
||||
date: formattedDate,
|
||||
lesson: item.Oraszam?.toString() || '',
|
||||
subject: item.Targy || '',
|
||||
topic: item.Tema || '',
|
||||
type: item.MulasztasTipus_DNAME || '',
|
||||
lesson: item.Oraszam?.toString() || "",
|
||||
subject: item.Targy || "",
|
||||
topic: item.Tema || "",
|
||||
type: item.MulasztasTipus_DNAME || "",
|
||||
justified: item.Igazolt_BOOL === true,
|
||||
justificationStatus: justificationStatus,
|
||||
purposeful: item.TanoraiCeluMulasztas_BNAME || '',
|
||||
justificationType: item.IgazolasTipus_DNAME || ''
|
||||
purposeful: item.TanoraiCeluMulasztas_BNAME || "",
|
||||
justificationType: item.IgazolasTipus_DNAME || "",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const groupedAbsences = {};
|
||||
absences.forEach(absence => {
|
||||
absences.forEach((absence) => {
|
||||
if (!groupedAbsences[absence.date]) {
|
||||
groupedAbsences[absence.date] = [];
|
||||
}
|
||||
@@ -64,120 +69,446 @@ async function collectAbsencesData() {
|
||||
|
||||
return { basicData, absences, groupedAbsences };
|
||||
} catch (error) {
|
||||
console.error('Hiba az API hívás során:', error);
|
||||
console.error("Hiba az API hívás során:", error);
|
||||
return { basicData, absences: [], groupedAbsences: {} };
|
||||
}
|
||||
}
|
||||
|
||||
function createFilterCard(absences) {
|
||||
const filterCard = document.createElement('div');
|
||||
filterCard.className = 'filter-card';
|
||||
|
||||
const filterHeader = document.createElement('div');
|
||||
filterHeader.className = 'filter-header';
|
||||
const h2 = document.createElement('h2');
|
||||
h2.textContent = LanguageManager.t('absences.filter_title');
|
||||
filterHeader.appendChild(h2);
|
||||
|
||||
const filterContent = document.createElement('div');
|
||||
filterContent.className = 'filter-content';
|
||||
|
||||
const dateGroup = createFilterGroup(
|
||||
'Calendar.svg',
|
||||
'Dátum',
|
||||
LanguageManager.t('absences.date'),
|
||||
'input',
|
||||
{ type: 'date', id: 'dateFilter', className: 'filter-input' }
|
||||
);
|
||||
filterContent.appendChild(dateGroup);
|
||||
|
||||
const subjectGroup = createSubjectFilterGroup(absences);
|
||||
filterContent.appendChild(subjectGroup);
|
||||
|
||||
const justificationGroup = createJustificationFilterGroup();
|
||||
filterContent.appendChild(justificationGroup);
|
||||
|
||||
filterCard.appendChild(filterHeader);
|
||||
filterCard.appendChild(filterContent);
|
||||
|
||||
return filterCard;
|
||||
}
|
||||
|
||||
function createFilterGroup(iconName, altText, labelText, elementType, attributes) {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL(`icons/${iconName}`);
|
||||
img.alt = altText;
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + labelText));
|
||||
|
||||
const element = document.createElement(elementType);
|
||||
Object.assign(element, attributes);
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(element);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createSubjectFilterGroup(absences) {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/Subject.svg');
|
||||
img.alt = 'Tantárgy';
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.subject')));
|
||||
|
||||
const select = document.createElement('select');
|
||||
select.id = 'subjectFilter';
|
||||
select.className = 'filter-input';
|
||||
|
||||
const defaultOption = document.createElement('option');
|
||||
defaultOption.value = '';
|
||||
defaultOption.textContent = LanguageManager.t('absences.all_subjects');
|
||||
select.appendChild(defaultOption);
|
||||
|
||||
const subjects = [...new Set(absences.map(a => a.subject))].sort();
|
||||
subjects.forEach(subject => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject;
|
||||
option.textContent = subject;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(select);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createJustificationFilterGroup() {
|
||||
const group = document.createElement('div');
|
||||
group.className = 'filter-group';
|
||||
|
||||
const label = document.createElement('label');
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/BadgeCheck.svg');
|
||||
img.alt = 'Igazolás';
|
||||
img.style.width = '24px';
|
||||
img.style.height = '24px';
|
||||
|
||||
label.appendChild(img);
|
||||
label.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.justification')));
|
||||
|
||||
const select = document.createElement('select');
|
||||
select.id = 'justificationFilter';
|
||||
select.className = 'filter-input';
|
||||
|
||||
const options = [
|
||||
{ value: '', text: LanguageManager.t('absences.all_types') },
|
||||
{ value: 'justified', text: LanguageManager.t('absences.justified') },
|
||||
{ value: 'unjustified', text: LanguageManager.t('absences.unjustified') },
|
||||
{ value: 'pending', text: LanguageManager.t('absences.pending') }
|
||||
];
|
||||
|
||||
options.forEach(optionData => {
|
||||
const option = document.createElement('option');
|
||||
option.value = optionData.value;
|
||||
option.textContent = optionData.text;
|
||||
select.appendChild(option);
|
||||
});
|
||||
|
||||
group.appendChild(label);
|
||||
group.appendChild(select);
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
function createStatsOverview(absences) {
|
||||
const statsOverview = document.createElement('div');
|
||||
statsOverview.className = 'stats-overview';
|
||||
|
||||
const stats = [
|
||||
{ number: absences.length, label: LanguageManager.t('absences.total_absences') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'justified').length, label: LanguageManager.t('absences.justified') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'unjustified').length, label: LanguageManager.t('absences.unjustified') },
|
||||
{ number: absences.filter(a => a.justificationStatus === 'pending').length, label: LanguageManager.t('absences.pending') }
|
||||
];
|
||||
|
||||
stats.forEach(stat => {
|
||||
const statCard = document.createElement('div');
|
||||
statCard.className = 'stat-card';
|
||||
|
||||
const statNumber = document.createElement('div');
|
||||
statNumber.className = 'stat-number';
|
||||
statNumber.textContent = stat.number;
|
||||
|
||||
const statLabel = document.createElement('div');
|
||||
statLabel.className = 'stat-label';
|
||||
statLabel.textContent = stat.label;
|
||||
|
||||
statCard.appendChild(statNumber);
|
||||
statCard.appendChild(statLabel);
|
||||
statsOverview.appendChild(statCard);
|
||||
});
|
||||
|
||||
return statsOverview;
|
||||
}
|
||||
|
||||
function createAbsencesContainer(absences) {
|
||||
const container = document.createElement('div');
|
||||
container.className = 'absences-container';
|
||||
|
||||
const table = document.createElement('table');
|
||||
table.className = 'absences-table';
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
thead.className = 'table-header';
|
||||
|
||||
const headerRow = document.createElement('tr');
|
||||
const headers = [
|
||||
LanguageManager.t('absences.date'),
|
||||
LanguageManager.t('absences.lesson'),
|
||||
LanguageManager.t('absences.subject'),
|
||||
LanguageManager.t('absences.topic'),
|
||||
LanguageManager.t('absences.status')
|
||||
];
|
||||
|
||||
headers.forEach(headerText => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = headerText;
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
||||
thead.appendChild(headerRow);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
generateAbsencesRows(absences, tbody);
|
||||
|
||||
table.appendChild(thead);
|
||||
table.appendChild(tbody);
|
||||
container.appendChild(table);
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
async function transformAbsencesPage() {
|
||||
const { basicData, absences, groupedAbsences } = await collectAbsencesData();
|
||||
document.body.textContent = '';
|
||||
const container = document.createElement('div');
|
||||
container.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
headerDiv.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
container.appendChild(headerDiv);
|
||||
const main = document.createElement('main');
|
||||
main.className = 'kreta-main';
|
||||
const filterCard = createFilterCard(absences);
|
||||
main.appendChild(filterCard);
|
||||
const statsOverview = createStatsOverview(absences);
|
||||
main.appendChild(statsOverview);
|
||||
const absencesContainer = createAbsencesContainer(absences);
|
||||
main.appendChild(absencesContainer);
|
||||
|
||||
container.appendChild(main);
|
||||
document.body.appendChild(container);
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>${LanguageManager.t('absences.filter_title')}</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">date_range</span>
|
||||
${LanguageManager.t('absences.date')}
|
||||
</label>
|
||||
<input type="date" id="dateFilter" class="filter-input">
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">school</span>
|
||||
${LanguageManager.t('absences.subject')}
|
||||
</label>
|
||||
<select id="subjectFilter" class="filter-input">
|
||||
<option value="">${LanguageManager.t('absences.all_subjects')}</option>
|
||||
${[...new Set(absences.map(a => a.subject))].sort().map(subject =>
|
||||
`<option value="${subject}">${subject}</option>`
|
||||
).join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<span class="material-icons-round">check_circle</span>
|
||||
${LanguageManager.t('absences.justification')}
|
||||
</label>
|
||||
<select id="justificationFilter" class="filter-input">
|
||||
<option value="">${LanguageManager.t('absences.all_types')}</option>
|
||||
<option value="justified">${LanguageManager.t('absences.justified')}</option>
|
||||
<option value="unjustified">${LanguageManager.t('absences.unjustified')}</option>
|
||||
<option value="pending">${LanguageManager.t('absences.pending')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absences-container">
|
||||
${Object.entries(groupedAbsences).map(([date, dayAbsences]) => `
|
||||
<div class="absence-group" data-date="${date}">
|
||||
<div class="absence-date">
|
||||
<span class="material-icons-round">event</span>
|
||||
${date}
|
||||
<span class="absence-count">${dayAbsences.length} ${LanguageManager.t('absences.hours')}</span>
|
||||
</div>
|
||||
<div class="absence-list">
|
||||
${dayAbsences.map(absence => `
|
||||
<div class="absence-item"
|
||||
data-subject="${absence.subject}"
|
||||
data-justified="${absence.justified}">
|
||||
<div class="absence-time">
|
||||
<span class="material-icons-round">schedule</span>
|
||||
${absence.lesson}. ${LanguageManager.t('absences.lesson').toLowerCase()}
|
||||
</div>
|
||||
<div class="absence-details">
|
||||
<div class="absence-subject">${absence.subject}</div>
|
||||
<div class="absence-topic">${absence.topic}</div>
|
||||
</div>
|
||||
<div class="absence-status ${absence.justificationStatus}">
|
||||
${absence.justificationStatus === 'justified' ?
|
||||
`${LanguageManager.t('absences.justified')} <span class="material-icons-round">check_circle</span>` :
|
||||
absence.justificationStatus === 'unjustified' ?
|
||||
`${LanguageManager.t('absences.unjustified')} <span class="material-icons-round">cancel</span>` :
|
||||
`${LanguageManager.t('absences.pending')} <span class="material-icons-round">pending</span>`}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
|
||||
setupEventListeners();
|
||||
setupFilters();
|
||||
|
||||
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function generateAbsencesRows(absences, tbody) {
|
||||
const groupedByDate = absences.reduce((groups, absence) => {
|
||||
const date = absence.date;
|
||||
if (!groups[date]) {
|
||||
groups[date] = [];
|
||||
}
|
||||
groups[date].push(absence);
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
const sortedDates = Object.keys(groupedByDate).sort(
|
||||
(a, b) => new Date(b) - new Date(a),
|
||||
);
|
||||
|
||||
sortedDates.forEach((date) => {
|
||||
const dateAbsences = groupedByDate[date];
|
||||
const divider = document.createElement('tr');
|
||||
divider.className = 'date-group-divider';
|
||||
divider.style.display = 'none';
|
||||
tbody.appendChild(divider);
|
||||
|
||||
dateAbsences.forEach((absence) => {
|
||||
const row = document.createElement('tr');
|
||||
row.className = 'table-row';
|
||||
row.dataset.subject = absence.subject;
|
||||
row.dataset.justified = absence.justified;
|
||||
row.dataset.date = absence.date;
|
||||
row.dataset.dateGroup = date;
|
||||
|
||||
const dateCell = document.createElement('td');
|
||||
dateCell.className = 'table-cell date-cell';
|
||||
dateCell.dataset.label = LanguageManager.t('absences.date');
|
||||
dateCell.textContent = absence.date;
|
||||
row.appendChild(dateCell);
|
||||
|
||||
const lessonCell = document.createElement('td');
|
||||
lessonCell.className = 'table-cell lesson-cell';
|
||||
lessonCell.dataset.label = LanguageManager.t('absences.lesson');
|
||||
lessonCell.textContent = absence.lesson + '.';
|
||||
row.appendChild(lessonCell);
|
||||
|
||||
const subjectCell = document.createElement('td');
|
||||
subjectCell.className = 'table-cell subject-cell';
|
||||
subjectCell.dataset.label = LanguageManager.t('absences.subject');
|
||||
subjectCell.textContent = absence.subject;
|
||||
row.appendChild(subjectCell);
|
||||
|
||||
const topicCell = document.createElement('td');
|
||||
topicCell.className = 'table-cell topic-cell';
|
||||
topicCell.dataset.label = LanguageManager.t('absences.topic');
|
||||
topicCell.title = absence.topic;
|
||||
topicCell.textContent = absence.topic;
|
||||
row.appendChild(topicCell);
|
||||
|
||||
const statusCell = document.createElement('td');
|
||||
statusCell.className = 'table-cell status-cell';
|
||||
statusCell.dataset.label = LanguageManager.t('absences.status');
|
||||
|
||||
const statusBadge = document.createElement('span');
|
||||
statusBadge.className = `status-badge ${absence.justificationStatus}`;
|
||||
|
||||
if (absence.justificationStatus === 'justified') {
|
||||
const img = document.createElement('img');
|
||||
img.src = chrome.runtime.getURL('icons/BadgeCheck.svg');
|
||||
img.alt = 'Igazolt';
|
||||
img.style.width = '16px';
|
||||
img.style.height = '16px';
|
||||
statusBadge.appendChild(img);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.justified')));
|
||||
} else if (absence.justificationStatus === 'unjustified') {
|
||||
const span = document.createElement('span');
|
||||
span.className = 'material-icons-round';
|
||||
span.textContent = 'cancel';
|
||||
statusBadge.appendChild(span);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.unjustified')));
|
||||
} else {
|
||||
const span = document.createElement('span');
|
||||
span.className = 'material-icons-round';
|
||||
span.textContent = 'pending';
|
||||
statusBadge.appendChild(span);
|
||||
statusBadge.appendChild(document.createTextNode(' ' + LanguageManager.t('absences.pending')));
|
||||
}
|
||||
|
||||
statusCell.appendChild(statusBadge);
|
||||
row.appendChild(statusCell);
|
||||
|
||||
tbody.appendChild(row);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
function setupMobileGrouping() {
|
||||
if (window.innerWidth <= 480) {
|
||||
createMobileGroups();
|
||||
} else {
|
||||
removeMobileGroups();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", setupMobileGrouping);
|
||||
|
||||
setupMobileGrouping();
|
||||
}
|
||||
|
||||
function createMobileGroups() {
|
||||
const tbody = document.querySelector(".absences-table tbody");
|
||||
if (!tbody) return;
|
||||
|
||||
removeMobileGroups();
|
||||
|
||||
const rows = Array.from(tbody.querySelectorAll(".table-row"));
|
||||
const groupedRows = {};
|
||||
|
||||
rows.forEach((row) => {
|
||||
const date = row.dataset.date;
|
||||
if (!groupedRows[date]) {
|
||||
groupedRows[date] = [];
|
||||
}
|
||||
groupedRows[date].push(row);
|
||||
});
|
||||
|
||||
const sortedDates = Object.keys(groupedRows).sort(
|
||||
(a, b) => new Date(b) - new Date(a),
|
||||
);
|
||||
|
||||
while (tbody.firstChild) {
|
||||
tbody.removeChild(tbody.firstChild);
|
||||
}
|
||||
|
||||
sortedDates.forEach((date) => {
|
||||
const dateRows = groupedRows[date];
|
||||
|
||||
const dateGroup = document.createElement("div");
|
||||
dateGroup.className = "date-group";
|
||||
|
||||
const dateHeader = document.createElement("div");
|
||||
dateHeader.className = "date-group-header";
|
||||
dateHeader.textContent = date;
|
||||
|
||||
const dateContent = document.createElement("div");
|
||||
dateContent.className = "date-group-content";
|
||||
|
||||
dateRows.forEach((row) => {
|
||||
dateContent.appendChild(row);
|
||||
});
|
||||
|
||||
dateGroup.appendChild(dateHeader);
|
||||
dateGroup.appendChild(dateContent);
|
||||
tbody.appendChild(dateGroup);
|
||||
});
|
||||
}
|
||||
|
||||
function removeMobileGroups() {
|
||||
const tbody = document.querySelector(".absences-table tbody");
|
||||
if (!tbody) return;
|
||||
|
||||
const dateGroups = tbody.querySelectorAll(".date-group");
|
||||
if (dateGroups.length === 0) return;
|
||||
|
||||
const allRows = [];
|
||||
dateGroups.forEach((group) => {
|
||||
const rows = group.querySelectorAll(".table-row");
|
||||
rows.forEach((row) => allRows.push(row));
|
||||
});
|
||||
|
||||
while (tbody.firstChild) {
|
||||
tbody.removeChild(tbody.firstChild);
|
||||
}
|
||||
allRows.forEach((row) => tbody.appendChild(row));
|
||||
}
|
||||
|
||||
function updateDateGroupsVisibility() {
|
||||
if (window.innerWidth > 480) return;
|
||||
|
||||
const dateGroups = document.querySelectorAll(".date-group");
|
||||
|
||||
dateGroups.forEach((group) => {
|
||||
const visibleRows = group.querySelectorAll(
|
||||
'.table-row[style=""], .table-row:not([style])',
|
||||
);
|
||||
|
||||
if (visibleRows.length > 0) {
|
||||
group.style.display = "";
|
||||
} else {
|
||||
group.style.display = "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setupFilters() {
|
||||
try {
|
||||
const filters = {
|
||||
dateFilter: document.getElementById('dateFilter'),
|
||||
subject: document.getElementById('subjectFilter'),
|
||||
justified: document.getElementById('justificationFilter')
|
||||
dateFilter: document.getElementById("dateFilter"),
|
||||
subject: document.getElementById("subjectFilter"),
|
||||
justified: document.getElementById("justificationFilter"),
|
||||
};
|
||||
|
||||
|
||||
if (!filters.dateFilter || !filters.subject || !filters.justified) {
|
||||
console.warn('Some filter elements were not found in the DOM');
|
||||
console.warn("Some filter elements were not found in the DOM");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,91 +519,120 @@ function setupFilters() {
|
||||
const justified = filters.justified.value;
|
||||
const selectedDate = dateFilterValue ? new Date(dateFilterValue) : null;
|
||||
|
||||
document.querySelectorAll('.absence-group').forEach(group => {
|
||||
const dateStr = group.dataset.date;
|
||||
const dateParts = dateStr.split('.');
|
||||
|
||||
document.querySelectorAll(".table-row").forEach((row) => {
|
||||
const dateStr = row.dataset.date;
|
||||
const dateParts = dateStr.split(".");
|
||||
|
||||
if (dateParts.length < 3) {
|
||||
console.error(`Invalid date format: ${dateStr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const parsedYear = parseInt(dateParts[0].trim(), 10);
|
||||
const parsedMonth = parseInt(dateParts[1].trim(), 10) - 1;
|
||||
const parsedDay = parseInt(dateParts[2].trim(), 10);
|
||||
|
||||
|
||||
if (isNaN(parsedDay) || isNaN(parsedMonth) || isNaN(parsedYear)) {
|
||||
console.error(`Invalid date components: ${dateStr}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const groupDate = new Date(parsedYear, parsedMonth, parsedDay);
|
||||
|
||||
let showGroup = true;
|
||||
|
||||
const rowDate = new Date(parsedYear, parsedMonth, parsedDay);
|
||||
|
||||
let showRow = true;
|
||||
|
||||
if (selectedDate) {
|
||||
if (groupDate.getFullYear() !== selectedDate.getFullYear() ||
|
||||
groupDate.getMonth() !== selectedDate.getMonth() ||
|
||||
groupDate.getDate() !== selectedDate.getDate()) {
|
||||
showGroup = false;
|
||||
if (
|
||||
rowDate.getFullYear() !== selectedDate.getFullYear() ||
|
||||
rowDate.getMonth() !== selectedDate.getMonth() ||
|
||||
rowDate.getDate() !== selectedDate.getDate()
|
||||
) {
|
||||
showRow = false;
|
||||
}
|
||||
}
|
||||
|
||||
const absenceItems = group.querySelectorAll('.absence-item');
|
||||
let visibleItems = 0;
|
||||
if (subject && row.dataset.subject !== subject) {
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
absenceItems.forEach(item => {
|
||||
let showItem = true;
|
||||
if (subject && item.dataset.subject !== subject) showItem = false;
|
||||
|
||||
if (justified) {
|
||||
const statusElement = item.querySelector('.absence-status');
|
||||
const hasStatus = statusElement.classList.contains(justified);
|
||||
if (!hasStatus) showItem = false;
|
||||
}
|
||||
if (justified) {
|
||||
const statusElement = row.querySelector(".status-badge");
|
||||
const hasStatus = statusElement.classList.contains(justified);
|
||||
if (!hasStatus) showRow = false;
|
||||
}
|
||||
|
||||
item.style.display = showItem ? '' : 'none';
|
||||
if (showItem) visibleItems++;
|
||||
});
|
||||
|
||||
group.style.display = (showGroup && visibleItems > 0) ? '' : 'none';
|
||||
row.style.display = showRow ? "" : "none";
|
||||
});
|
||||
|
||||
updateDateGroupsVisibility();
|
||||
updateStatistics();
|
||||
} catch (err) {
|
||||
|
||||
console.error('Error during filtering absences:', err);
|
||||
console.error("Error during filtering absences:", err);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Object.values(filters).forEach(filter => {
|
||||
|
||||
Object.values(filters).forEach((filter) => {
|
||||
try {
|
||||
if (filter) {
|
||||
filter.addEventListener('change', filterAbsences);
|
||||
filter.addEventListener("change", filterAbsences);
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.message && err.message.includes('Extension context invalidated')) {
|
||||
console.warn('Extension context invalidated during event listener setup');
|
||||
if (
|
||||
err.message &&
|
||||
err.message.includes("Extension context invalidated")
|
||||
) {
|
||||
console.warn(
|
||||
"Extension context invalidated during event listener setup",
|
||||
);
|
||||
} else {
|
||||
console.error('Error setting up filter event listener:', err);
|
||||
console.error("Error setting up filter event listener:", err);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
filterAbsences();
|
||||
} catch (err) {
|
||||
|
||||
if (err.message && err.message.includes('Extension context invalidated')) {
|
||||
console.warn('Extension context invalidated during filter setup');
|
||||
if (err.message && err.message.includes("Extension context invalidated")) {
|
||||
console.warn("Extension context invalidated during filter setup");
|
||||
} else {
|
||||
console.error('Error setting up filters:', err);
|
||||
console.error("Error setting up filters:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateStatistics() {
|
||||
try {
|
||||
const visibleRows = document.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
const totalVisible = visibleRows.length;
|
||||
const justifiedVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.justified"),
|
||||
).length;
|
||||
const unjustifiedVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.unjustified"),
|
||||
).length;
|
||||
const pendingVisible = Array.from(visibleRows).filter((row) =>
|
||||
row.querySelector(".status-badge.pending"),
|
||||
).length;
|
||||
|
||||
if (window.location.href.includes('/Hianyzas/Hianyzasok')) {
|
||||
transformAbsencesPage().catch(error => {
|
||||
console.error(LanguageManager.t('absences.page_transform_error'), error);
|
||||
const statCards = document.querySelectorAll(".stat-card");
|
||||
if (statCards[0])
|
||||
statCards[0].querySelector(".stat-number").textContent = totalVisible;
|
||||
if (statCards[1])
|
||||
statCards[1].querySelector(".stat-number").textContent = justifiedVisible;
|
||||
if (statCards[2])
|
||||
statCards[2].querySelector(".stat-number").textContent =
|
||||
unjustifiedVisible;
|
||||
if (statCards[3])
|
||||
statCards[3].querySelector(".stat-number").textContent = pendingVisible;
|
||||
} catch (err) {
|
||||
console.error("Error updating statistics:", err);
|
||||
}
|
||||
}
|
||||
|
||||
if (window.location.href.includes("/Hianyzas/Hianyzasok")) {
|
||||
transformAbsencesPage().catch((error) => {
|
||||
console.error(LanguageManager.t("absences.page_transform_error"), error);
|
||||
});
|
||||
}
|
||||
@@ -140,9 +140,10 @@ h2 {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
line-height: 1.3;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.widget-subtitle {
|
||||
@@ -150,6 +151,8 @@ h2 {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 1.2;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.widget-content {
|
||||
@@ -186,6 +189,8 @@ h2 {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
margin-top: 4px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.grade-date {
|
||||
@@ -196,20 +201,69 @@ h2 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.widget-author {
|
||||
color: var(--text-tertiary);
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.widget-meta {
|
||||
.news-author {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
text-align: right;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
/* Mobile view: author below content */
|
||||
@media (max-width: 768px) {
|
||||
.news-item .widget-row {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.news-item .widget-meta {
|
||||
order: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.news-item .widget-details {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.news-author {
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.widget-date {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
.news-author {
|
||||
order: 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Desktop view: limit author width and wrap text */
|
||||
@media (min-width: 769px) {
|
||||
.news-author {
|
||||
max-width: 180px;
|
||||
white-space: normal;
|
||||
line-height: 1.3;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-empty {
|
||||
@@ -236,21 +290,27 @@ h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 8px;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.news-content {
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
.exam-type {
|
||||
color: var(--accent-accent);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
display: inline-flex;
|
||||
@@ -331,6 +391,7 @@ h2 {
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--accent-15);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.dropdown-item svg {
|
||||
@@ -349,14 +410,6 @@ h2 {
|
||||
line-height: 1.4;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.exam-type {
|
||||
color: var(--accent-accent);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.more-link {
|
||||
margin-top: auto;
|
||||
display: inline-flex;
|
||||
|
||||
@@ -1,44 +1,63 @@
|
||||
const DashboardUtils = {
|
||||
formatGradeValue(value) {
|
||||
const trimmedValue = value?.trim() || '';
|
||||
if (trimmedValue.toLowerCase() === 'szöveges') {
|
||||
return 'Sz';
|
||||
const trimmedValue = value?.trim() || "";
|
||||
if (trimmedValue.toLowerCase() === "szöveges") {
|
||||
return "Sz";
|
||||
}
|
||||
return trimmedValue;
|
||||
},
|
||||
|
||||
parseDate(dateStr) {
|
||||
return dateStr?.trim() || '';
|
||||
return dateStr?.trim() || "";
|
||||
},
|
||||
|
||||
formatHungarianDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
|
||||
const dateParts = dateStr.trim().split('.');
|
||||
if (!dateStr) return "";
|
||||
|
||||
const dateParts = dateStr.trim().split(".");
|
||||
if (dateParts.length < 3) return dateStr;
|
||||
|
||||
|
||||
const month = parseInt(dateParts[1], 10);
|
||||
const day = parseInt(dateParts[2], 10);
|
||||
|
||||
|
||||
if (isNaN(month) || month < 1 || month > 12) return dateStr;
|
||||
|
||||
if (typeof window.LanguageManager !== 'undefined') {
|
||||
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'
|
||||
"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'
|
||||
"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 {
|
||||
@@ -48,175 +67,216 @@ class DashboardDataManager {
|
||||
absences: [],
|
||||
notes: [],
|
||||
upcomingExams: [],
|
||||
news: []
|
||||
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 gradeRows = document.querySelectorAll(
|
||||
"#legutobbiErtekelesek tr:not(:first-child)",
|
||||
);
|
||||
|
||||
const [fullSubject, date] = gradeInfo.split('\n').map(str => str.trim());
|
||||
const { subject, type, dateInSubject } = this.parseSubjectInformation(fullSubject);
|
||||
this.dashboardData.grades = Array.from(gradeRows)
|
||||
.map((row) => {
|
||||
const gradeValue = row.querySelector(
|
||||
'span[style*="font-size: 200%"]',
|
||||
)?.textContent;
|
||||
const gradeInfo = row.querySelector(
|
||||
'span[style*="float: right"]',
|
||||
)?.textContent;
|
||||
|
||||
return {
|
||||
value: DashboardUtils.formatGradeValue(gradeValue),
|
||||
subject,
|
||||
date: DashboardUtils.parseDate(date),
|
||||
type: type || LanguageManager.t('dashboard.evaluation'),
|
||||
dateInSubject: dateInSubject || null
|
||||
};
|
||||
}).filter(Boolean);
|
||||
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 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
|
||||
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')
|
||||
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 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()
|
||||
type: fullSubject.substring(monthIndex).trim(),
|
||||
};
|
||||
}
|
||||
|
||||
return { subject: fullSubject, type: '' };
|
||||
|
||||
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;
|
||||
const absenceRows = document.querySelectorAll(
|
||||
"#legutobbiMulasztasok tr:not(:first-child)",
|
||||
);
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || '',
|
||||
day: spans[2]?.textContent?.trim() || '',
|
||||
type: spans[1]?.textContent?.trim() || '',
|
||||
count: spans[3]?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(Boolean);
|
||||
this.dashboardData.absences = Array.from(absenceRows)
|
||||
.map((row) => {
|
||||
const spans = row.querySelectorAll("span");
|
||||
if (spans.length < 4) return null;
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || "",
|
||||
day: spans[2]?.textContent?.trim() || "",
|
||||
type: spans[1]?.textContent?.trim() || "",
|
||||
count: spans[3]?.textContent?.trim() || "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
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;
|
||||
const noteRows = document.querySelectorAll(
|
||||
"#legutobbiFeljegyzesek tr:not(:first-child)",
|
||||
);
|
||||
|
||||
return {
|
||||
title: spans[0]?.textContent?.trim() || '',
|
||||
author: spans[1]?.textContent?.trim() || '',
|
||||
date: spans[2]?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(Boolean);
|
||||
this.dashboardData.notes = Array.from(noteRows)
|
||||
.map((row) => {
|
||||
const spans = row.querySelectorAll("span");
|
||||
if (spans.length < 3) return null;
|
||||
|
||||
return {
|
||||
title: spans[0]?.textContent?.trim() || "",
|
||||
author: spans[1]?.textContent?.trim() || "",
|
||||
date: spans[2]?.textContent?.trim() || "",
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
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;
|
||||
const examRows = document.querySelectorAll(
|
||||
"#legutobbiBejelentettSzamonkeres tr:not(:first-child)",
|
||||
);
|
||||
|
||||
return {
|
||||
date: spans[0]?.textContent?.trim() || '',
|
||||
subject: spans[1]?.textContent?.trim() || '',
|
||||
day: spans[2]?.textContent?.trim() || '',
|
||||
type: spans[3]?.textContent?.trim() || ''
|
||||
};
|
||||
}).filter(Boolean);
|
||||
this.dashboardData.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',
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
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 = '';
|
||||
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+)\)\//);
|
||||
const match = item.Idopont.match(/\/Date\((\d+)\)\//);
|
||||
if (match) {
|
||||
const timestamp = parseInt(match[1]);
|
||||
const date = new Date(timestamp);
|
||||
formattedDate = date.toLocaleDateString('hu-HU');
|
||||
formattedDate = date.toLocaleDateString("hu-HU");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!formattedDate) {
|
||||
formattedDate = new Date().toLocaleDateString('hu-HU');
|
||||
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();
|
||||
|
||||
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',
|
||||
content: cleanContent || "Nincs elérhető tartalom",
|
||||
date: formattedDate,
|
||||
author: `${item.Nev || 'Ismeretlen'} (${item.Munkakor || 'Ismeretlen'})`
|
||||
author: `${item.Nev || "Ismeretlen"} (${item.Munkakor || "Ismeretlen"})`,
|
||||
};
|
||||
|
||||
|
||||
this.dashboardData.news.push(newsItem);
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error fetching news from API:', error);
|
||||
console.error("❌ Error fetching news from API:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,16 +292,23 @@ class DashboardDataManager {
|
||||
|
||||
class DashboardRenderer {
|
||||
constructor(data) {
|
||||
this.baseData = data;
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.data = {
|
||||
...data,
|
||||
...this.baseData,
|
||||
schoolInfo: {
|
||||
name: cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
id: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || ''
|
||||
name:
|
||||
await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
||||
}
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
this.schoolNameFull = `${this.data.schoolInfo.id} - ${this.data.schoolInfo.name}`;
|
||||
this.shortenedSchoolName = helper.shortenSchoolName(this.schoolNameFull);
|
||||
@@ -261,7 +328,9 @@ class DashboardRenderer {
|
||||
`;
|
||||
}
|
||||
createNewsCard() {
|
||||
const newsItems = this.data.news.map(news => `
|
||||
const newsItems = this.data.news
|
||||
.map(
|
||||
(news) => `
|
||||
<div class="widget-item news-item">
|
||||
<div class="widget-row">
|
||||
<div class="widget-details news-details">
|
||||
@@ -269,18 +338,27 @@ class DashboardRenderer {
|
||||
<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>` : ''}
|
||||
${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('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.news'), newsItems || LanguageManager.t('dashboard.not_supported'), '/Intezmeny/Faliujsag', LanguageManager.t('dashboard.all_news'));
|
||||
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 => `
|
||||
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>
|
||||
@@ -288,62 +366,96 @@ class DashboardRenderer {
|
||||
<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>` : ''}
|
||||
${grade.dateInSubject || grade.date ? `<div class="widget-subtitle grade-date">${grade.dateInSubject || grade.date}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.grades'), gradeItems, '/TanuloErtekeles/Osztalyzatok', LanguageManager.t('dashboard.all_grades'));
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.grades"),
|
||||
gradeItems,
|
||||
"/TanuloErtekeles/Osztalyzatok",
|
||||
LanguageManager.t("dashboard.all_grades"),
|
||||
);
|
||||
}
|
||||
|
||||
createAbsenceCard() {
|
||||
const absenceItems = this.data.absences.map(absence => `
|
||||
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>` : ''}
|
||||
${absence.day ? `<div class="widget-date">${absence.day}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.absences'), absenceItems, '/Hianyzas/Hianyzasok', LanguageManager.t('dashboard.all_absences'));
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.absences"),
|
||||
absenceItems,
|
||||
"/Hianyzas/Hianyzasok",
|
||||
LanguageManager.t("dashboard.all_absences"),
|
||||
);
|
||||
}
|
||||
|
||||
createNoteCard() {
|
||||
const noteItems = this.data.notes.map(note => `
|
||||
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>` : ''}
|
||||
${note.author ? `<div class="widget-author note-author">${note.author}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.notes'), noteItems, '/TanuloErtekeles/InformaciokFeljegyzesek', LanguageManager.t('dashboard.all_messages'));
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.notes"),
|
||||
noteItems,
|
||||
"/TanuloErtekeles/InformaciokFeljegyzesek",
|
||||
LanguageManager.t("dashboard.all_messages"),
|
||||
);
|
||||
}
|
||||
|
||||
createExamCard() {
|
||||
const examItems = this.data.upcomingExams.map(exam => `
|
||||
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 class="widget-subtitle exam-type">${exam.type || ""}</div>
|
||||
</div>
|
||||
<div class="widget-date exam-date">${DashboardUtils.formatHungarianDate(exam.date)}</div>
|
||||
</div>
|
||||
</div>
|
||||
`).join('');
|
||||
`,
|
||||
)
|
||||
.join("");
|
||||
|
||||
return this.createCard(LanguageManager.t('dashboard.exams'), examItems, '/Tanulo/TanuloBejelentettSzamonkeresek', LanguageManager.t('dashboard.all_exams'));
|
||||
return this.createCard(
|
||||
LanguageManager.t("dashboard.exams"),
|
||||
examItems,
|
||||
"/Tanulo/TanuloBejelentettSzamonkeresek",
|
||||
LanguageManager.t("dashboard.all_exams"),
|
||||
);
|
||||
}
|
||||
|
||||
createCard(title, content, linkHref, linkText) {
|
||||
@@ -353,7 +465,7 @@ class DashboardRenderer {
|
||||
<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>`}
|
||||
${content || `<div class="widget-empty">${LanguageManager.t("dashboard.not_supported")}</div>`}
|
||||
</div>
|
||||
<div class="widget-footer">
|
||||
<a href="${linkHref}" class="widget-link more-link">
|
||||
@@ -367,13 +479,31 @@ class DashboardRenderer {
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
${this.generateMainContent()}
|
||||
</div>
|
||||
`;
|
||||
async render() {
|
||||
await this.init();
|
||||
document.body.innerHTML = '';
|
||||
|
||||
const kretaContainer = document.createElement('div');
|
||||
kretaContainer.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(headerDiv);
|
||||
const mainContentDiv = document.createElement('div');
|
||||
const parser2 = new DOMParser();
|
||||
const mainDoc = parser2.parseFromString(this.generateMainContent(), 'text/html');
|
||||
const mainContent = mainDoc.body;
|
||||
while (mainContent.firstChild) {
|
||||
mainContentDiv.appendChild(mainContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(mainContentDiv);
|
||||
|
||||
document.body.appendChild(kretaContainer);
|
||||
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
}
|
||||
@@ -385,36 +515,40 @@ class DashboardApplication {
|
||||
}
|
||||
|
||||
async init() {
|
||||
if (!window.location.href.includes('/Intezmeny/Faliujsag')) {
|
||||
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 (
|
||||
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));
|
||||
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');
|
||||
const newsContainer = document.querySelector(
|
||||
".faliujsag-lista, #faliujsagLista",
|
||||
);
|
||||
if (newsContainer) {
|
||||
const possibleSelectors = [
|
||||
'.nb-item',
|
||||
'.news-item',
|
||||
'.faliujsag-item',
|
||||
'.list-group-item',
|
||||
'li',
|
||||
".nb-item",
|
||||
".news-item",
|
||||
".faliujsag-item",
|
||||
".list-group-item",
|
||||
"li",
|
||||
'div[class*="item"]',
|
||||
'div[class*="news"]'
|
||||
'div[class*="news"]',
|
||||
];
|
||||
|
||||
|
||||
for (const selector of possibleSelectors) {
|
||||
const items = newsContainer.querySelectorAll(selector);
|
||||
if (items.length > 0) {
|
||||
@@ -422,30 +556,33 @@ class DashboardApplication {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!newsItemsFound) {
|
||||
if (newsContainer.children.length > 0 || newsContainer.textContent.trim().length > 0) {
|
||||
if (
|
||||
newsContainer.children.length > 0 ||
|
||||
newsContainer.textContent.trim().length > 0
|
||||
) {
|
||||
newsItemsFound = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!newsItemsFound) {
|
||||
attempts++;
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
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();
|
||||
await renderer.render();
|
||||
} catch (error) {
|
||||
console.error('Error initializing dashboard:', error);
|
||||
console.error("Error initializing dashboard:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new DashboardApplication();
|
||||
new DashboardApplication();
|
||||
|
||||
BIN
fonts/Icons.woff2
Normal file
@@ -1,292 +1,57 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
body.maintenance-mode {
|
||||
margin:0;
|
||||
padding:0;
|
||||
height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
background-color:var(--background);
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color:var(--background) !important;
|
||||
}
|
||||
|
||||
.forgot-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
.maintenance-container {
|
||||
text-align:center;
|
||||
padding:2rem;
|
||||
border-radius:8px;
|
||||
background-color:var(--card-card);
|
||||
box-shadow:0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width:600px;
|
||||
width:90%;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
.maintenance-logo {
|
||||
width:128px;
|
||||
height:128px;
|
||||
margin:0 auto 2rem;
|
||||
}
|
||||
|
||||
.forgot-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0;
|
||||
background: var(--card-card) !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0) !important;
|
||||
.maintenance-title {
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
margin-bottom:1rem;
|
||||
color:var(--accent-accent);
|
||||
font-family:'Montserrat',sans-serif;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
.maintenance-message {
|
||||
font-size:1rem;
|
||||
line-height:1.5;
|
||||
margin-bottom:1.5rem;
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
.maintenance-footer {
|
||||
font-size:0.875rem;
|
||||
color:var(--text-secondary);
|
||||
margin-top:2rem;
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
.forgot-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
margin-bottom: 24px;
|
||||
.maintenance-cactus {
|
||||
position:fixed;
|
||||
bottom:0px;
|
||||
right:20px;
|
||||
width:120px;
|
||||
height:120px;
|
||||
opacity:1;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.forgot-form {
|
||||
width: 100%;
|
||||
=======
|
||||
.forgot-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--icon);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
background: var(--card);
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.forgot-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--primary);
|
||||
margin-bottom: 24px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: var(--text-primary);
|
||||
font-family: Montserrat;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 14px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-15) !important;
|
||||
border: 0px solid var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
transition: border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
border-color: var(--error-accent) !important;
|
||||
background: var(--error-card) !important;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: var(--error-text);
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.help-link:hover {
|
||||
color: var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-family: "Montserrat", serif;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn-submit:hover {
|
||||
background: var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-submit:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.message {
|
||||
padding: 12px 16px;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 16px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
animation: fadeIn 0.3s ease;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.message.success {
|
||||
background: var(--success-card);
|
||||
color: var(--success-text);
|
||||
border: 1px solid var(--success-accent);
|
||||
}
|
||||
|
||||
.message.error {
|
||||
background: var(--error-card);
|
||||
color: var(--error-text);
|
||||
border: 1px solid var(--error-accent);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.forgot-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.forgot-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.forgot-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
height: 44px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.forgot-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.forgot-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: stretch;
|
||||
}
|
||||
}
|
||||
@@ -1,53 +1,17 @@
|
||||
(() => {
|
||||
const renderRecaptcha = () => {
|
||||
const container = document.getElementById('recaptcha-container');
|
||||
if (container && typeof grecaptcha !== 'undefined' && grecaptcha.render) {
|
||||
try {
|
||||
grecaptcha.render('recaptcha-container', {
|
||||
'sitekey': '6LfKURIqAAAAAD5bF2evQ-_Sf6MRrOkUEBwb_mMy',
|
||||
'theme': 'light'
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error rendering reCAPTCHA:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
// reCAPTCHA functionality removed for security compliance
|
||||
|
||||
const loadDependencies = async () => {
|
||||
if (typeof cookieManager === 'undefined') {
|
||||
const cookieScript = document.createElement('script');
|
||||
cookieScript.src = chrome.runtime.getURL('tools/cookieManager.js');
|
||||
document.head.appendChild(cookieScript);
|
||||
|
||||
await new Promise(resolve => {
|
||||
cookieScript.onload = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof LanguageManager === 'undefined') {
|
||||
const langScript = document.createElement('script');
|
||||
langScript.src = chrome.runtime.getURL('global/language.js');
|
||||
document.head.appendChild(langScript);
|
||||
|
||||
await new Promise(resolve => {
|
||||
langScript.onload = resolve;
|
||||
});
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
}
|
||||
|
||||
if (!document.querySelector('script[src*="recaptcha"]')) {
|
||||
await new Promise((resolve) => {
|
||||
window.onRecaptchaLoad = resolve;
|
||||
const script = document.createElement('script');
|
||||
script.src = 'https://www.google.com/recaptcha/api.js?hl=hu&onload=onRecaptchaLoad&render=explicit';
|
||||
document.head.appendChild(script);
|
||||
});
|
||||
}
|
||||
// reCAPTCHA functionality removed for security compliance
|
||||
// Extension now works without external script dependencies
|
||||
};
|
||||
|
||||
const createPageStructure = () => {
|
||||
document.body.innerHTML = `
|
||||
// Biztonságos DOM létrehozás innerHTML helyett
|
||||
document.body.innerHTML = '';
|
||||
// Biztonságos HTML parsing DOMParser használatával
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(`
|
||||
<div class="forgot-container">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
@@ -64,7 +28,7 @@
|
||||
<div class="forgot-card">
|
||||
<header class="forgot-header">
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
<img src="${chrome.runtime.getURL("images/firka_logo.png")}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
</header>
|
||||
@@ -88,7 +52,7 @@
|
||||
<div class="error-message" data-i18n="forgotpassword.email_required">Az e-mail cím megadása kötelező</div>
|
||||
</div>
|
||||
|
||||
<div id="recaptcha-container"></div>
|
||||
<!-- reCAPTCHA container removed for security compliance -->
|
||||
|
||||
<div class="form-actions">
|
||||
<a href="/Adminisztracio/Login" class="help-link" data-i18n="forgotpassword.back_to_login">
|
||||
@@ -101,19 +65,31 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
`, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
|
||||
// Biztonságos DOM hozzáadás
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
const transformForgotPasswordPage = async () => {
|
||||
await loadDependencies();
|
||||
|
||||
const isDarkMode = localStorage.getItem('darkMode') === 'true';
|
||||
document.documentElement.setAttribute('data-theme', isDarkMode ? 'dark' : 'light');
|
||||
|
||||
|
||||
const isDarkMode = localStorage.getItem("darkMode") === "true";
|
||||
document.documentElement.setAttribute(
|
||||
"data-theme",
|
||||
isDarkMode ? "dark" : "light",
|
||||
);
|
||||
|
||||
chrome.runtime.onMessage.addListener((message) => {
|
||||
if (message.action === 'toggleTheme') {
|
||||
document.documentElement.setAttribute('data-theme', message.darkMode ? 'dark' : 'light');
|
||||
localStorage.setItem('darkMode', message.darkMode);
|
||||
if (message.action === "toggleTheme") {
|
||||
document.documentElement.setAttribute(
|
||||
"data-theme",
|
||||
message.darkMode ? "dark" : "light",
|
||||
);
|
||||
localStorage.setItem("darkMode", message.darkMode);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -121,34 +97,34 @@
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 50;
|
||||
|
||||
|
||||
const waitForLanguageManager = () => {
|
||||
return new Promise((resolve) => {
|
||||
const checkLanguageManager = () => {
|
||||
attempts++;
|
||||
if (typeof LanguageManager !== 'undefined' && LanguageManager.t) {
|
||||
if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
|
||||
setTimeout(resolve, 200);
|
||||
} else if (attempts < maxAttempts) {
|
||||
setTimeout(checkLanguageManager, 100);
|
||||
} else {
|
||||
console.warn('LanguageManager not available, using fallback texts');
|
||||
console.warn("LanguageManager not available, using fallback texts");
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
checkLanguageManager();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
await waitForLanguageManager();
|
||||
|
||||
if (typeof LanguageManager !== 'undefined' && LanguageManager.t) {
|
||||
const elements = document.querySelectorAll('[data-i18n]');
|
||||
elements.forEach(element => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
if (typeof LanguageManager !== "undefined" && LanguageManager.t) {
|
||||
const elements = document.querySelectorAll("[data-i18n]");
|
||||
elements.forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const translation = LanguageManager.t(key);
|
||||
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute('data-i18n-attr');
|
||||
const attr = element.getAttribute("data-i18n-attr");
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
@@ -157,172 +133,158 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
renderRecaptcha();
|
||||
}, 500);
|
||||
|
||||
|
||||
// reCAPTCHA rendering removed for security compliance
|
||||
|
||||
setupFormValidation();
|
||||
};
|
||||
|
||||
const setupFormValidation = () => {
|
||||
const form = document.getElementById('forgotForm');
|
||||
const inputs = form.querySelectorAll('.form-control');
|
||||
|
||||
inputs.forEach(input => {
|
||||
|
||||
input.addEventListener('input', () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener('submit', handleSubmit);
|
||||
};
|
||||
|
||||
const validateInput = (input, showError = false) => {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
}
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
const showMessage = (message, isError = false) => {
|
||||
const existingMessage = document.querySelector('.message');
|
||||
if (existingMessage) {
|
||||
existingMessage.remove();
|
||||
}
|
||||
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = `message ${isError ? 'error' : 'success'}`;
|
||||
messageDiv.textContent = message;
|
||||
|
||||
const form = document.getElementById('forgotForm');
|
||||
form.insertBefore(messageDiv, form.firstChild);
|
||||
const setupFormValidation = () => {
|
||||
const form = document.getElementById("forgotForm");
|
||||
const inputs = form.querySelectorAll(".form-control");
|
||||
|
||||
setTimeout(() => {
|
||||
if (messageDiv.parentNode) {
|
||||
messageDiv.remove();
|
||||
}
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
const validateEmail = (email) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
let isValid = true;
|
||||
|
||||
inputs.forEach(input => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
inputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
const emailInput = form.querySelector('#EmailCim');
|
||||
if (emailInput.value && !validateEmail(emailInput.value)) {
|
||||
emailInput.classList.add('error');
|
||||
const errorElement = emailInput.nextElementSibling;
|
||||
if (errorElement) {
|
||||
errorElement.textContent = LanguageManager.t('forgotpassword.invalid_email');
|
||||
errorElement.classList.add('show');
|
||||
}
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
form.addEventListener("submit", handleSubmit);
|
||||
};
|
||||
|
||||
const validateInput = (input, showError = false) => {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
return isValid;
|
||||
};
|
||||
|
||||
const showMessage = (message, isError = false) => {
|
||||
const existingMessage = document.querySelector(".message");
|
||||
if (existingMessage) {
|
||||
existingMessage.remove();
|
||||
}
|
||||
|
||||
const messageDiv = document.createElement("div");
|
||||
messageDiv.className = `message ${isError ? "error" : "success"}`;
|
||||
messageDiv.textContent = message;
|
||||
|
||||
const form = document.getElementById("forgotForm");
|
||||
form.insertBefore(messageDiv, form.firstChild);
|
||||
|
||||
setTimeout(() => {
|
||||
if (messageDiv.parentNode) {
|
||||
messageDiv.remove();
|
||||
}
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
const validateEmail = (email) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
const handleSubmit = async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
let recaptchaResponse = '';
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
recaptchaResponse = grecaptcha.getResponse();
|
||||
if (!recaptchaResponse) {
|
||||
showMessage(LanguageManager.t('forgotpassword.recaptcha_required'), true);
|
||||
isValid = false;
|
||||
}
|
||||
} else {
|
||||
showMessage('reCAPTCHA nem töltődött be. Kérjük, frissítse az oldalt!', true);
|
||||
isValid = false;
|
||||
const emailInput = form.querySelector("#EmailCim");
|
||||
if (emailInput.value && !validateEmail(emailInput.value)) {
|
||||
emailInput.classList.add("error");
|
||||
const errorElement = emailInput.nextElementSibling;
|
||||
if (errorElement) {
|
||||
errorElement.textContent = LanguageManager.t(
|
||||
"forgotpassword.invalid_email",
|
||||
);
|
||||
errorElement.classList.add("show");
|
||||
}
|
||||
isValid = false;
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
// reCAPTCHA validation removed for security compliance
|
||||
|
||||
const submitButton = form.querySelector('.btn-submit');
|
||||
const originalText = submitButton.textContent;
|
||||
submitButton.disabled = true;
|
||||
submitButton.textContent = LanguageManager.t('loading.text') || 'Küldés...';
|
||||
if (!isValid) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
const submitButton = form.querySelector(".btn-submit");
|
||||
const originalText = submitButton.textContent;
|
||||
submitButton.disabled = true;
|
||||
submitButton.textContent = LanguageManager.t("loading.text") || "Küldés...";
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
formData.append('ReCaptcha', grecaptcha.getResponse());
|
||||
}
|
||||
|
||||
const response = await fetch('/Adminisztracio/ElfelejtettJelszo/LinkKuldes', {
|
||||
method: 'POST',
|
||||
try {
|
||||
const formData = new FormData(form);
|
||||
|
||||
// reCAPTCHA data removed for security compliance
|
||||
|
||||
const response = await fetch(
|
||||
"/Adminisztracio/ElfelejtettJelszo/LinkKuldes",
|
||||
{
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
});
|
||||
"X-Requested-With": "XMLHttpRequest",
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.Success) {
|
||||
showMessage(LanguageManager.t('forgotpassword.success_message'));
|
||||
|
||||
form.reset();
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = '/Adminisztracio/Login';
|
||||
}, 3000);
|
||||
} else {
|
||||
showMessage(result.Message || LanguageManager.t('forgotpassword.error_message'), true);
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Password reset error:', error);
|
||||
showMessage(LanguageManager.t('forgotpassword.error_message'), true);
|
||||
|
||||
if (typeof grecaptcha !== 'undefined') {
|
||||
grecaptcha.reset();
|
||||
}
|
||||
} finally {
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = originalText;
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
};
|
||||
|
||||
if (window.location.href.includes('/Adminisztracio/ElfelejtettJelszo')) {
|
||||
transformForgotPasswordPage().catch(console.error);
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.Success) {
|
||||
showMessage(LanguageManager.t("forgotpassword.success_message"));
|
||||
|
||||
form.reset();
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
|
||||
setTimeout(() => {
|
||||
window.location.href = "/Adminisztracio/Login";
|
||||
}, 3000);
|
||||
} else {
|
||||
showMessage(
|
||||
result.Message || LanguageManager.t("forgotpassword.error_message"),
|
||||
true,
|
||||
);
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Password reset error:", error);
|
||||
showMessage(LanguageManager.t("forgotpassword.error_message"), true);
|
||||
|
||||
// reCAPTCHA reset removed
|
||||
} finally {
|
||||
submitButton.disabled = false;
|
||||
submitButton.textContent = originalText;
|
||||
}
|
||||
})();
|
||||
};
|
||||
|
||||
if (window.location.href.includes("/Adminisztracio/ElfelejtettJelszo")) {
|
||||
transformForgotPasswordPage().catch(console.error);
|
||||
}
|
||||
})();
|
||||
|
||||
@@ -1,131 +1,189 @@
|
||||
(function() {
|
||||
let currentLanguage = 'hu';
|
||||
let translations = {};
|
||||
|
||||
async function setLanguage(language) {
|
||||
(function () {
|
||||
let currentLanguage = "hu";
|
||||
let translations = {};
|
||||
|
||||
async function setLanguage(language) {
|
||||
try {
|
||||
currentLanguage = language;
|
||||
|
||||
await storageManager.set("languagePreference", language);
|
||||
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
await loadTranslations(language);
|
||||
applyTranslations();
|
||||
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("languageChanged", {
|
||||
detail: { language: language },
|
||||
}),
|
||||
);
|
||||
|
||||
chrome.runtime
|
||||
.sendMessage({
|
||||
action: "languageChanged",
|
||||
language: language,
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
async function loadTranslations(language) {
|
||||
try {
|
||||
const url = chrome.runtime.getURL(`i18n/${language}.json`);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to load ${language}.json - Status: ${response.status}`,
|
||||
);
|
||||
}
|
||||
translations = await response.json();
|
||||
} catch (error) {
|
||||
if (language !== "hu") {
|
||||
try {
|
||||
currentLanguage = language;
|
||||
|
||||
cookieManager.set('languagePreference', language);
|
||||
localStorage.setItem('languagePreference', language);
|
||||
|
||||
await loadTranslations(language);
|
||||
applyTranslations();
|
||||
|
||||
|
||||
window.dispatchEvent(new CustomEvent('languageChanged', {
|
||||
detail: { language: language }
|
||||
}));
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'languageChanged',
|
||||
language: language
|
||||
}).catch(() => {});
|
||||
} catch (error) {}
|
||||
const fallbackUrl = chrome.runtime.getURL("i18n/hu.json");
|
||||
const response = await fetch(fallbackUrl);
|
||||
translations = await response.json();
|
||||
} catch (fallbackError) {}
|
||||
}
|
||||
}
|
||||
|
||||
async function loadTranslations(language) {
|
||||
try {
|
||||
const url = chrome.runtime.getURL(`i18n/${language}.json`);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to load ${language}.json - Status: ${response.status}`);
|
||||
}
|
||||
translations = await response.json();
|
||||
} catch (error) {
|
||||
if (language !== 'hu') {
|
||||
try {
|
||||
const fallbackUrl = chrome.runtime.getURL('i18n/hu.json');
|
||||
const response = await fetch(fallbackUrl);
|
||||
translations = await response.json();
|
||||
} catch (fallbackError) {}
|
||||
}
|
||||
}
|
||||
|
||||
function applyTranslations() {
|
||||
const elements = document.querySelectorAll("[data-i18n]");
|
||||
|
||||
elements.forEach((element) => {
|
||||
const key = element.getAttribute("data-i18n");
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute("data-i18n-attr");
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
|
||||
function applyTranslations() {
|
||||
const elements = document.querySelectorAll('[data-i18n]');
|
||||
|
||||
elements.forEach(element => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
|
||||
const attr = element.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getTranslation(keyPath, fallback = '') {
|
||||
const keys = keyPath.split('.');
|
||||
let value = translations;
|
||||
|
||||
for (const key of keys) {
|
||||
if (value && typeof value === 'object' && key in value) {
|
||||
value = value[key];
|
||||
} else {
|
||||
|
||||
return fallback || keyPath;
|
||||
}
|
||||
}
|
||||
|
||||
return typeof value === 'string' ? value : fallback || keyPath;
|
||||
}
|
||||
|
||||
async function initializeLanguage() {
|
||||
const cookieLanguage = cookieManager.get('languagePreference');
|
||||
const localStorageLanguage = localStorage.getItem('languagePreference');
|
||||
|
||||
const language = cookieLanguage || localStorageLanguage || 'hu';
|
||||
|
||||
await setLanguage(language);
|
||||
|
||||
|
||||
if (cookieLanguage !== localStorageLanguage) {
|
||||
if (cookieLanguage) {
|
||||
localStorage.setItem('languagePreference', cookieLanguage);
|
||||
} else if (localStorageLanguage) {
|
||||
cookieManager.set('languagePreference', localStorageLanguage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initializeLanguage);
|
||||
} else {
|
||||
initializeLanguage();
|
||||
}
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'changeLanguage') {
|
||||
setLanguage(message.language);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
if (message.action === 'getLanguage') {
|
||||
sendResponse({ language: currentLanguage });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
window.LanguageManager = {
|
||||
getCurrentLanguage: () => currentLanguage,
|
||||
changeLanguage: setLanguage,
|
||||
t: getTranslation,
|
||||
getAvailableLanguages: () => [
|
||||
{ code: 'hu', name: 'Magyar' },
|
||||
{ code: 'en', name: 'English' }
|
||||
]
|
||||
};
|
||||
|
||||
})();
|
||||
function getTranslation(keyPath, fallback = "") {
|
||||
const keys = keyPath.split(".");
|
||||
let value = translations;
|
||||
|
||||
for (const key of keys) {
|
||||
if (value && typeof value === "object" && key in value) {
|
||||
value = value[key];
|
||||
} else {
|
||||
return fallback || keyPath;
|
||||
}
|
||||
}
|
||||
|
||||
return typeof value === "string" ? value : fallback || keyPath;
|
||||
}
|
||||
|
||||
async function initializeLanguage() {
|
||||
try {
|
||||
const storageLanguage = await storageManager.get("languagePreference");
|
||||
const localStorageLanguage = localStorage.getItem("languagePreference");
|
||||
const language = storageLanguage || localStorageLanguage || "hu";
|
||||
|
||||
await setLanguage(language);
|
||||
loadTranslationsForPage();
|
||||
|
||||
if (storageLanguage !== localStorageLanguage) {
|
||||
if (storageLanguage) {
|
||||
localStorage.setItem("languagePreference", storageLanguage);
|
||||
} else if (localStorageLanguage) {
|
||||
await storageManager.set("languagePreference", localStorageLanguage);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error initializing language:", error);
|
||||
await setLanguage("hu");
|
||||
loadTranslationsForPage();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", initializeLanguage);
|
||||
} else {
|
||||
initializeLanguage();
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === "changeLanguage") {
|
||||
setLanguage(message.language);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
if (message.action === "getLanguage") {
|
||||
sendResponse({ language: currentLanguage });
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
function loadTranslationsForPage() {
|
||||
try {
|
||||
applyTranslations();
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'childList') {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
const elementsWithI18n = node.querySelectorAll ? node.querySelectorAll('[data-i18n]') : [];
|
||||
elementsWithI18n.forEach((element) => {
|
||||
const key = element.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = element.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
element.setAttribute(attr, translation);
|
||||
} else {
|
||||
element.textContent = translation;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (node.hasAttribute && node.hasAttribute('data-i18n')) {
|
||||
const key = node.getAttribute('data-i18n');
|
||||
const translation = getTranslation(key);
|
||||
|
||||
if (translation && translation !== key) {
|
||||
const attr = node.getAttribute('data-i18n-attr');
|
||||
if (attr) {
|
||||
node.setAttribute(attr, translation);
|
||||
} else {
|
||||
node.textContent = translation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error loading translations for page:', error);
|
||||
}
|
||||
}
|
||||
|
||||
window.LanguageManager = {
|
||||
getCurrentLanguage: () => currentLanguage,
|
||||
changeLanguage: setLanguage,
|
||||
t: getTranslation,
|
||||
loadTranslationsForPage: loadTranslationsForPage,
|
||||
getAvailableLanguages: () => [
|
||||
{ code: "hu", name: "Magyar" },
|
||||
{ code: "en", name: "English" },
|
||||
],
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1,89 +1,57 @@
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-Medium.woff2') format('woff2');
|
||||
font-weight: 500;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Montserrat-SemiBold.woff2') format('woff2');
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
src: url('chrome-extension://__MSG_@@extension_id__/fonts/Figtree-Regular.woff2') format('woff2');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
body.maintenance-mode {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--background);
|
||||
color: var(--text-primary);
|
||||
font-family: 'Figtree', sans-serif;
|
||||
margin:0;
|
||||
padding:0;
|
||||
height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
background-color:var(--background);
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background) !important;
|
||||
background-color:var(--background) !important;
|
||||
}
|
||||
|
||||
.maintenance-container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
border-radius: 8px;
|
||||
background-color: var(--card-card);
|
||||
box-shadow: 0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
text-align:center;
|
||||
padding:2rem;
|
||||
border-radius:8px;
|
||||
background-color:var(--card-card);
|
||||
box-shadow:0 var(--shadow-blur) 6px var(--accent-shadow);
|
||||
max-width:600px;
|
||||
width:90%;
|
||||
}
|
||||
|
||||
.maintenance-logo {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
margin: 0 auto 2rem;
|
||||
width:128px;
|
||||
height:128px;
|
||||
margin:0 auto 2rem;
|
||||
}
|
||||
|
||||
.maintenance-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
color: var(--accent-accent);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
margin-bottom:1rem;
|
||||
color:var(--accent-accent);
|
||||
font-family:'Montserrat',sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-message {
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1.5rem;
|
||||
color: var(--text-primary);
|
||||
font-family: 'Figtree', sans-serif;
|
||||
font-size:1rem;
|
||||
line-height:1.5;
|
||||
margin-bottom:1.5rem;
|
||||
color:var(--text-primary);
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-footer {
|
||||
font-size: 0.875rem;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 2rem;
|
||||
font-family: 'Figtree', sans-serif;
|
||||
font-size:0.875rem;
|
||||
color:var(--text-secondary);
|
||||
margin-top:2rem;
|
||||
font-family:'Figtree',sans-serif;
|
||||
}
|
||||
|
||||
.maintenance-cactus {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
right: 20px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
opacity: 1;
|
||||
z-index: 1000;
|
||||
}
|
||||
position:fixed;
|
||||
bottom:0px;
|
||||
right:20px;
|
||||
width:120px;
|
||||
height:120px;
|
||||
opacity:1;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
@@ -1,99 +1,106 @@
|
||||
function loadMaintenanceCSS() {
|
||||
const maintenanceCSS = document.createElement('link');
|
||||
maintenanceCSS.rel = 'stylesheet';
|
||||
maintenanceCSS.href = chrome.runtime.getURL('global/maintenance.css');
|
||||
document.head.appendChild(maintenanceCSS);
|
||||
const maintenanceCSS = document.createElement("link");
|
||||
maintenanceCSS.rel = "stylesheet";
|
||||
maintenanceCSS.href = chrome.runtime.getURL("global/maintenance.css");
|
||||
document.head.appendChild(maintenanceCSS);
|
||||
}
|
||||
|
||||
function checkMaintenancePage() {
|
||||
const maintenanceContent = document.querySelector('.login_content');
|
||||
const bodyText = document.body ? document.body.textContent : '';
|
||||
const maintenanceContent = document.querySelector(".login_content");
|
||||
const bodyText = document.body ? document.body.textContent : "";
|
||||
|
||||
const specificMaintenanceMessage = 'Kedves Felhasználók! A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik. Köszönjük türelmüket és megértésüket! KRÉTA Csapat';
|
||||
const hasSpecificMessage = bodyText.includes('Kedves Felhasználók!') &&
|
||||
bodyText.includes('A KRÉTA rendszer jelenleg frissítés alatt van') &&
|
||||
bodyText.includes('KRÉTA Csapat');
|
||||
const hasSpecificMessage = bodyText.includes("A KRÉTA rendszer jelenleg frissítés alatt van");
|
||||
|
||||
const hasGeneralMaintenance = maintenanceContent &&
|
||||
(maintenanceContent.textContent.includes('frissítés alatt') ||
|
||||
maintenanceContent.textContent.includes('under maintenance'));
|
||||
|
||||
if (hasSpecificMessage || hasGeneralMaintenance) {
|
||||
const body = document.body;
|
||||
const mainLogo = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
const cactusImage = chrome.runtime.getURL('images/cactus.png');
|
||||
const hasGeneralMaintenance =
|
||||
maintenanceContent &&
|
||||
(maintenanceContent.textContent.includes("frissítés alatt") ||
|
||||
maintenanceContent.textContent.includes("under maintenance"));
|
||||
|
||||
const removeLoadingElements = () => {
|
||||
const loadingScreen = document.querySelector('.loading-screen');
|
||||
if (loadingScreen) loadingScreen.remove();
|
||||
|
||||
const kretaProgressBar = document.querySelector('#KretaProgressBar');
|
||||
if (kretaProgressBar) kretaProgressBar.remove();
|
||||
|
||||
const modalBackground = document.querySelector('.modalBckgroundMain');
|
||||
if (modalBackground) modalBackground.remove();
|
||||
if (hasSpecificMessage || hasGeneralMaintenance) {
|
||||
const body = document.body;
|
||||
const mainLogo = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
const cactusImage = chrome.runtime.getURL("images/cactus.png");
|
||||
|
||||
const overlays = document.querySelectorAll('.modalBckgroundMain, .loading-screen, #KretaProgressBar');
|
||||
overlays.forEach(overlay => overlay.remove());
|
||||
};
|
||||
|
||||
removeLoadingElements();
|
||||
setTimeout(removeLoadingElements, 100);
|
||||
const removeLoadingElements = () => {
|
||||
const loadingScreen = document.querySelector(".loading-screen");
|
||||
if (loadingScreen) loadingScreen.remove();
|
||||
|
||||
const existingStyles = document.querySelectorAll('link[rel="stylesheet"], style');
|
||||
existingStyles.forEach(style => style.remove());
|
||||
const kretaProgressBar = document.querySelector("#KretaProgressBar");
|
||||
if (kretaProgressBar) kretaProgressBar.remove();
|
||||
|
||||
body.innerHTML = '';
|
||||
body.classList.add('maintenance-mode');
|
||||
body.classList.add('theme-enabled');
|
||||
body.classList.add('loaded');
|
||||
|
||||
|
||||
loadMaintenanceCSS();
|
||||
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.className = 'maintenance-container';
|
||||
|
||||
const logo = document.createElement('img');
|
||||
logo.src = mainLogo;
|
||||
logo.alt = 'Firka Logo';
|
||||
logo.className = 'maintenance-logo';
|
||||
|
||||
const title = document.createElement('h1');
|
||||
title.className = 'maintenance-title';
|
||||
title.textContent = window.LanguageManager ? window.LanguageManager.t('maintenance.title') : 'Karbantartás';
|
||||
|
||||
const messageDiv = document.createElement('div');
|
||||
messageDiv.className = 'maintenance-message';
|
||||
|
||||
const paragraph1 = document.createElement('p');
|
||||
paragraph1.textContent = window.LanguageManager ? window.LanguageManager.t('maintenance.message1') : 'A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.';
|
||||
|
||||
const paragraph2 = document.createElement('p');
|
||||
paragraph2.textContent = window.LanguageManager ? window.LanguageManager.t('maintenance.message2') : 'Köszönjük türelmüket és megértésüket!';
|
||||
|
||||
const footer = document.createElement('div');
|
||||
footer.className = 'maintenance-footer';
|
||||
footer.textContent = window.LanguageManager ? window.LanguageManager.t('maintenance.team') : 'KRÉTA Csapat';
|
||||
const modalBackground = document.querySelector(".modalBckgroundMain");
|
||||
if (modalBackground) modalBackground.remove();
|
||||
|
||||
const cactus = document.createElement('img');
|
||||
cactus.src = cactusImage;
|
||||
cactus.alt = 'Cactus';
|
||||
cactus.className = 'maintenance-cactus';
|
||||
|
||||
|
||||
messageDiv.appendChild(paragraph1);
|
||||
messageDiv.appendChild(paragraph2);
|
||||
|
||||
container.appendChild(logo);
|
||||
container.appendChild(title);
|
||||
container.appendChild(messageDiv);
|
||||
container.appendChild(footer);
|
||||
|
||||
body.appendChild(container);
|
||||
body.appendChild(cactus);
|
||||
}
|
||||
const overlays = document.querySelectorAll(
|
||||
".modalBckgroundMain, .loading-screen, #KretaProgressBar",
|
||||
);
|
||||
overlays.forEach((overlay) => overlay.remove());
|
||||
};
|
||||
|
||||
removeLoadingElements();
|
||||
setTimeout(removeLoadingElements, 100);
|
||||
|
||||
const existingStyles = document.querySelectorAll(
|
||||
'link[rel="stylesheet"], style',
|
||||
);
|
||||
existingStyles.forEach((style) => style.remove());
|
||||
|
||||
body.innerHTML = "";
|
||||
body.classList.add("maintenance-mode");
|
||||
body.classList.add("theme-enabled");
|
||||
body.classList.add("loaded");
|
||||
|
||||
loadMaintenanceCSS();
|
||||
|
||||
const container = document.createElement("div");
|
||||
container.className = "maintenance-container";
|
||||
|
||||
const logo = document.createElement("img");
|
||||
logo.src = mainLogo;
|
||||
logo.alt = "Firka Logo";
|
||||
logo.className = "maintenance-logo";
|
||||
|
||||
const title = document.createElement("h1");
|
||||
title.className = "maintenance-title";
|
||||
title.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.title")
|
||||
: "Karbantartás";
|
||||
|
||||
const messageDiv = document.createElement("div");
|
||||
messageDiv.className = "maintenance-message";
|
||||
|
||||
const paragraph1 = document.createElement("p");
|
||||
paragraph1.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.message1")
|
||||
: "A KRÉTA rendszer jelenleg frissítés alatt van, hamarosan újra elérhetővé válik.";
|
||||
|
||||
const paragraph2 = document.createElement("p");
|
||||
paragraph2.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.message2")
|
||||
: "Köszönjük türelmüket és megértésüket!";
|
||||
|
||||
const footer = document.createElement("div");
|
||||
footer.className = "maintenance-footer";
|
||||
footer.textContent = window.LanguageManager
|
||||
? window.LanguageManager.t("maintenance.team")
|
||||
: "KRÉTA Csapat";
|
||||
|
||||
const cactus = document.createElement("img");
|
||||
cactus.src = cactusImage;
|
||||
cactus.alt = "Cactus";
|
||||
cactus.className = "maintenance-cactus";
|
||||
|
||||
messageDiv.appendChild(paragraph1);
|
||||
messageDiv.appendChild(paragraph2);
|
||||
|
||||
container.appendChild(logo);
|
||||
container.appendChild(title);
|
||||
container.appendChild(messageDiv);
|
||||
container.appendChild(footer);
|
||||
|
||||
body.appendChild(container);
|
||||
body.appendChild(cactus);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', checkMaintenancePage);
|
||||
document.addEventListener("DOMContentLoaded", checkMaintenancePage);
|
||||
|
||||
@@ -1,401 +1,332 @@
|
||||
.kreta-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--background);
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
display:grid;
|
||||
grid-template-columns:minmax(300px,400px) 1fr minmax(200px,300px);
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background-color:var(--background);
|
||||
}
|
||||
|
||||
|
||||
.school-info {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin:0;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color:var(--text-primary);
|
||||
font-size:24px;
|
||||
font-weight:600;
|
||||
margin:0 0 0.5rem;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.5rem;
|
||||
width:24px;
|
||||
height:24px;
|
||||
border-radius:8px;
|
||||
margin-right:0.5rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.kreta-nav {
|
||||
padding: 0 clamp(0.5rem, 3vw, 1.5rem);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding:0 clamp(0.5rem,3vw,1.5rem);
|
||||
position:sticky;
|
||||
top:0;
|
||||
z-index:100;
|
||||
display:flex;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
display: flex;
|
||||
gap: clamp(0.5rem, 2vw, 1rem);
|
||||
padding: 0.25rem;
|
||||
align-items: center;
|
||||
display:flex;
|
||||
gap:clamp(0.5rem,2vw,1rem);
|
||||
padding:0.25rem;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: clamp(0.5rem, 1.5vw, 1rem) 0.5rem;
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s ease;
|
||||
gap: 0.5rem;
|
||||
text-decoration: none;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
padding:clamp(0.5rem,1.5vw,1rem) 0.5rem;
|
||||
color:var(--text-secondary);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
white-space:nowrap;
|
||||
border-radius:8px;
|
||||
transition:all 0.2s ease;
|
||||
gap:0.5rem;
|
||||
text-decoration:none;
|
||||
}
|
||||
.nav-item.active {
|
||||
display: flex;
|
||||
padding: 8px 14px 8px 12px;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 20px;
|
||||
background: var(--button-secondaryFill);
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
padding:8px 14px 8px 12px;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
border-radius:20px;
|
||||
background:var(--button-secondaryFill);
|
||||
box-shadow:0px 1px var(--shadow-blur,2px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--hover);
|
||||
border-radius: 8px;
|
||||
text-decoration: none;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--hover);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
.nav-item.active:hover {
|
||||
color: var(--accent-accent);
|
||||
background-color: var(--accent-hover);
|
||||
text-decoration: none;
|
||||
color:var(--accent-accent);
|
||||
background-color:var(--accent-hover);
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.nav-item img,
|
||||
.nav-item svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.nav-item img,.nav-item svg {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
|
||||
.nav-item.active svg path {
|
||||
fill: var(--accent-accent);
|
||||
fill:var(--accent-accent);
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
position:relative;
|
||||
justify-self:flex-end;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--hover);
|
||||
background:var(--hover);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
display: block;
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
display:block;
|
||||
color:var(--text-primary);
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
display:block;
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||
width: 200px;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
position:absolute;
|
||||
top:100%;
|
||||
right:0;
|
||||
margin-top:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
box-shadow:0 4px 6px -1px rgba(0,0,0,0.1);
|
||||
width:200px;
|
||||
display:none;
|
||||
z-index:1000;
|
||||
}
|
||||
|
||||
.user-dropdown.show {
|
||||
display: block;
|
||||
animation: dropdownShow 0.2s ease;
|
||||
display:block;
|
||||
animation:dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.75rem;
|
||||
padding:0.75rem 1rem;
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--hover);
|
||||
color: var(--accent-accent);
|
||||
border-radius: 8px;
|
||||
background:var(--hover);
|
||||
color:var(--accent-accent);
|
||||
border-radius:8px;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@media (max-width:1200px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: minmax(250px, 350px) 1fr minmax(180px, 250px);
|
||||
}
|
||||
grid-template-columns:minmax(250px,350px) 1fr minmax(180px,250px);
|
||||
}
|
||||
|
||||
/* Hamburger menu styles */
|
||||
}/* Hamburger menu styles */
|
||||
.nav-toggle {
|
||||
display: none;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
display:none;
|
||||
background:none;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
padding:0.5rem;
|
||||
border-radius:8px;
|
||||
transition:background-color 0.2s;
|
||||
}
|
||||
|
||||
.nav-toggle:hover {
|
||||
background: var(--hover);
|
||||
background:var(--hover);
|
||||
}
|
||||
|
||||
.nav-toggle svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
fill: var(--text-primary);
|
||||
width:24px;
|
||||
height:24px;
|
||||
fill:var(--text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
display: block;
|
||||
grid-area: toggle;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
max-width: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 11px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.kreta-nav {
|
||||
grid-area: nav;
|
||||
padding: 0;
|
||||
margin-top: 0.5rem;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.kreta-nav.show {
|
||||
display: flex;
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
padding: 0.75rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 11px;
|
||||
}
|
||||
padding:1rem;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.nav-toggle {
|
||||
display:block;
|
||||
grid-area:toggle;
|
||||
}
|
||||
.school-info {
|
||||
grid-area:school;
|
||||
max-width:none;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:0.5rem;
|
||||
}
|
||||
.logo-text {
|
||||
margin:0;
|
||||
font-size:18px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:11px;
|
||||
max-width:200px;
|
||||
}
|
||||
.kreta-nav {
|
||||
grid-area:nav;
|
||||
padding:0;
|
||||
margin-top:0.5rem;
|
||||
display:none;
|
||||
}
|
||||
.kreta-nav.show {
|
||||
display:flex;
|
||||
animation:slideDown 0.3s ease;
|
||||
}
|
||||
.kreta-nav::-webkit-scrollbar {
|
||||
display:none;
|
||||
}
|
||||
.nav-links {
|
||||
flex-direction:column;
|
||||
width:100%;
|
||||
gap:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
padding:1rem;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
.nav-item {
|
||||
width:100%;
|
||||
justify-content:flex-start;
|
||||
padding:0.75rem;
|
||||
font-size:14px;
|
||||
}
|
||||
.user-profile {
|
||||
grid-area:user;
|
||||
}
|
||||
.user-info {
|
||||
text-align:right;
|
||||
max-width:120px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:13px;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:11px;
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
grid-template-columns:1fr auto auto;
|
||||
grid-template-areas:"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 0.75rem;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 10px;
|
||||
max-width: 150px;
|
||||
}
|
||||
|
||||
.kreta-nav {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.kreta-nav.show {
|
||||
display: flex;
|
||||
animation: slideDown 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
padding: 1rem;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
padding: 0.75rem;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 10px;
|
||||
}
|
||||
padding:0.75rem;
|
||||
gap:0.25rem;
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.kreta-header {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 9px;
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
max-width: 80px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.nav-logout-timer {
|
||||
font-size: 9px;
|
||||
}
|
||||
.school-info {
|
||||
min-width:0;
|
||||
flex:1;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
.logo-text {
|
||||
font-size:16px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:10px;
|
||||
max-width:150px;
|
||||
}
|
||||
.kreta-nav {
|
||||
display:none;
|
||||
}
|
||||
.kreta-nav.show {
|
||||
display:flex;
|
||||
animation:slideDown 0.3s ease;
|
||||
}
|
||||
.nav-links {
|
||||
flex-direction:column;
|
||||
width:100%;
|
||||
gap:0.5rem;
|
||||
background:var(--card-card);
|
||||
border-radius:12px;
|
||||
padding:1rem;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
.nav-item {
|
||||
width:100%;
|
||||
justify-content:flex-start;
|
||||
padding:0.75rem;
|
||||
font-size:14px;
|
||||
}
|
||||
.user-info {
|
||||
max-width:100px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:12px;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:10px;
|
||||
}
|
||||
}@media (max-width:360px) {
|
||||
.kreta-header {
|
||||
padding:0.5rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:14px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:9px;
|
||||
max-width:120px;
|
||||
}
|
||||
.user-info {
|
||||
max-width:80px;
|
||||
}
|
||||
.user-name {
|
||||
font-size:11px;
|
||||
}
|
||||
.nav-logout-timer {
|
||||
font-size:9px;
|
||||
}
|
||||
}@keyframes slideDown {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}
|
||||
@@ -1,122 +1,177 @@
|
||||
const COOKIE_KEYS = {
|
||||
SCHOOL_NAME: 'schoolName',
|
||||
SCHOOL_CODE: 'schoolCode',
|
||||
USER_NAME: 'userName',
|
||||
SCHOOL_SUBDOMAIN: 'schoolSubdomain'
|
||||
SCHOOL_NAME: "schoolName",
|
||||
SCHOOL_CODE: "schoolCode",
|
||||
USER_NAME: "userName",
|
||||
SCHOOL_SUBDOMAIN: "schoolSubdomain",
|
||||
};
|
||||
|
||||
const DEFAULT_VALUES = {
|
||||
SCHOOL: LanguageManager.t('navigation.school_default'),
|
||||
USER: LanguageManager.t('navigation.user_default'),
|
||||
TIMER: '45:00'
|
||||
SCHOOL: LanguageManager.t("navigation.school_default"),
|
||||
USER: LanguageManager.t("navigation.user_default"),
|
||||
TIMER: "45:00",
|
||||
};
|
||||
|
||||
function updateHeaderInfo() {
|
||||
const schoolName = document.querySelector('.nav-school-name');
|
||||
const userName = document.querySelector('.nav-user-name');
|
||||
const logoutTimer = document.querySelector('.nav-logout-timer');
|
||||
|
||||
const userData = {
|
||||
schoolName: cookieManager.get(COOKIE_KEYS.SCHOOL_NAME) || DEFAULT_VALUES.SCHOOL,
|
||||
schoolId: cookieManager.get(COOKIE_KEYS.SCHOOL_CODE) || '',
|
||||
name: cookieManager.get(COOKIE_KEYS.USER_NAME) || DEFAULT_VALUES.USER,
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || DEFAULT_VALUES.TIMER
|
||||
};
|
||||
|
||||
if (schoolName) {
|
||||
schoolName.textContent = `${userData.schoolId} - ${userData.schoolName}`;
|
||||
}
|
||||
|
||||
if (userName) {
|
||||
userName.textContent = userData.name;
|
||||
}
|
||||
|
||||
if (logoutTimer) {
|
||||
startLogoutTimer(userData.time);
|
||||
}
|
||||
async function updateHeaderInfo() {
|
||||
const schoolName = document.querySelector(".nav-school-name");
|
||||
const userName = document.querySelector(".nav-user-name");
|
||||
const logoutTimer = document.querySelector(".nav-logout-timer");
|
||||
|
||||
const userData = {
|
||||
schoolName:
|
||||
await storageManager.get("schoolName", DEFAULT_VALUES.SCHOOL),
|
||||
schoolId: await storageManager.get("schoolCode", ""),
|
||||
name: await storageManager.get("userName", DEFAULT_VALUES.USER),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
DEFAULT_VALUES.TIMER,
|
||||
};
|
||||
|
||||
if (schoolName) {
|
||||
schoolName.textContent = `${userData.schoolId} - ${userData.schoolName}`;
|
||||
}
|
||||
|
||||
if (userName) {
|
||||
userName.textContent = userData.name;
|
||||
}
|
||||
|
||||
if (logoutTimer) {
|
||||
startLogoutTimer(userData.time);
|
||||
}
|
||||
}
|
||||
|
||||
function startLogoutTimer(timeString) {
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
const timerElement = document.querySelector('.nav-logout-timer');
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
}
|
||||
timeLeft--;
|
||||
};
|
||||
const startTime = parseInt(timeString?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
const timerElement = document.querySelector(".nav-logout-timer");
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = "/Home/Logout";
|
||||
}
|
||||
timeLeft--;
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
}
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateHeaderInfo();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
});
|
||||
|
||||
function setupUserDropdown() {
|
||||
const userBtn = document.querySelector('.user-dropdown-btn');
|
||||
const userDropdown = document.querySelector('.user-dropdown');
|
||||
|
||||
userBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle('show');
|
||||
});
|
||||
const userBtn = document.querySelector(".user-dropdown-btn");
|
||||
const userDropdown = document.querySelector(".user-dropdown");
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
userDropdown?.classList.remove('show');
|
||||
});
|
||||
userBtn?.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle("show");
|
||||
});
|
||||
|
||||
document.addEventListener("click", () => {
|
||||
userDropdown?.classList.remove("show");
|
||||
});
|
||||
}
|
||||
|
||||
function setupSettingsButton() {
|
||||
document.getElementById('settingsBtn')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
document.getElementById("settingsBtn")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL("settings/index.html");
|
||||
window.open(url, "_blank", "width=400,height=600");
|
||||
});
|
||||
}
|
||||
|
||||
function setupMobileNavigation() {
|
||||
setTimeout(() => {
|
||||
const navToggle = document.querySelector('.nav-toggle');
|
||||
const nav = document.querySelector('.kreta-nav');
|
||||
setTimeout(() => {
|
||||
const navToggle = document.querySelector(".nav-toggle");
|
||||
const nav = document.querySelector(".kreta-nav");
|
||||
|
||||
if (!navToggle || !nav) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
|
||||
|
||||
if (isFirefox) {
|
||||
let isNavOpen = false;
|
||||
|
||||
navToggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (!navToggle || !nav) {
|
||||
return;
|
||||
if (isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
} else {
|
||||
nav.style.display = "flex";
|
||||
nav.classList.add("show");
|
||||
isNavOpen = true;
|
||||
}
|
||||
});
|
||||
|
||||
navToggle.addEventListener("touchend", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
navToggle.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
nav.classList.toggle('show');
|
||||
if (isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
} else {
|
||||
nav.style.display = "flex";
|
||||
nav.classList.add("show");
|
||||
isNavOpen = true;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target) && isNavOpen) {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
}
|
||||
});
|
||||
|
||||
const navItems = document.querySelectorAll(".nav-item");
|
||||
navItems.forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
nav.style.display = "none";
|
||||
nav.classList.remove("show");
|
||||
isNavOpen = false;
|
||||
});
|
||||
});
|
||||
} else {
|
||||
navToggle.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
nav.classList.toggle("show");
|
||||
});
|
||||
|
||||
document.addEventListener('click', (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target)) {
|
||||
nav.classList.remove('show');
|
||||
}
|
||||
});
|
||||
document.addEventListener("click", (e) => {
|
||||
if (!nav.contains(e.target) && !navToggle.contains(e.target)) {
|
||||
nav.classList.remove("show");
|
||||
}
|
||||
});
|
||||
|
||||
const navItems = document.querySelectorAll('.nav-item');
|
||||
navItems.forEach(item => {
|
||||
item.addEventListener('click', () => {
|
||||
nav.classList.remove('show');
|
||||
});
|
||||
const navItems = document.querySelectorAll(".nav-item");
|
||||
navItems.forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
nav.classList.remove("show");
|
||||
});
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await updateHeaderInfo();
|
||||
setupUserDropdown();
|
||||
setupSettingsButton();
|
||||
setupMobileNavigation();
|
||||
});
|
||||
|
||||
297
global/theme.css
@@ -1,160 +1,163 @@
|
||||
:root {
|
||||
--background: #DAE4F7;
|
||||
--background-0: #dae4f700;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 2px;
|
||||
--text-primary: #050B15;
|
||||
--text-secondary: #050b15cc;
|
||||
--text-teritary: #050b1580;
|
||||
--card-card: #EDF3FF;
|
||||
--card-translucent: #edf3ff80;
|
||||
--button-secondaryFill: #FBFCFF;
|
||||
--accent-accent: #3673EE;
|
||||
--accent-secondary: #1C469A;
|
||||
--accent-shadow: #1c469a26;
|
||||
--accent-15: #3673ee26;
|
||||
--warning-accent: var(--grades-2);
|
||||
--warning-text: #8F531B;
|
||||
--warning-15: #ffa04626;
|
||||
--warning-card: #FAEBDC;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #8F1B4F;
|
||||
--error-15: #FF54A126;
|
||||
--error-card: #FADCE9;
|
||||
--grades-1: #FF54A1;
|
||||
--grades-2: #FFA046;
|
||||
--grades-3: #F9CF00;
|
||||
--grades-4: #92EA3B;
|
||||
--grades-5: #22CCAD;
|
||||
--grades-background-1: #FF54A126;
|
||||
--grades-background-2: #FFA04626;
|
||||
--grades-background-3: #F9CF0026;
|
||||
--grades-background-4: #92EA3B26;
|
||||
--grades-background-5: #22CCAD26;
|
||||
--background:#DAE4F7;
|
||||
--background-0:#dae4f700;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:2px;
|
||||
--text-primary:#050B15;
|
||||
--text-secondary:#050b15cc;
|
||||
--text-teritary:#050b1580;
|
||||
--card-card:#EDF3FF;
|
||||
--card-translucent:#edf3ff80;
|
||||
--button-secondaryFill:#FBFCFF;
|
||||
--accent-accent:#3673EE;
|
||||
--accent-secondary:#1C469A;
|
||||
--accent-shadow:#1c469a26;
|
||||
--accent-15:#3673ee26;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#8F531B;
|
||||
--warning-15:#ffa04626;
|
||||
--warning-card:#FAEBDC;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#8F1B4F;
|
||||
--error-15:#FF54A126;
|
||||
--error-card:#FADCE9;
|
||||
--grades-1:#FF54A1;
|
||||
--grades-2:#FFA046;
|
||||
--grades-3:#F9CF00;
|
||||
--grades-4:#92EA3B;
|
||||
--grades-5:#22CCAD;
|
||||
--grades-background-1:#FF54A126;
|
||||
--grades-background-2:#FFA04626;
|
||||
--grades-background-3:#F9CF0026;
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="light-green"] {
|
||||
--background: #FAFFF0;
|
||||
--background-0: #fafff000;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 2px;
|
||||
--text-primary: #394C0A;
|
||||
--text-secondary: #394c0acc;
|
||||
--text-teritary: #394c0a80;
|
||||
--card-card: #F3FBDE;
|
||||
--card-translucent: #f3fbde80;
|
||||
--button-secondaryFill: #FEFFFD;
|
||||
--accent-accent: #A7DC22;
|
||||
--accent-secondary: #6E8F1B;
|
||||
--accent-shadow: #647e2226;
|
||||
--accent-15: #a7dc2226;
|
||||
--warning-accent: var(--grades-2);
|
||||
--warning-text: #8F531B;
|
||||
--warning-15: #ffa04626;
|
||||
--warning-card: #FAEBDC;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #8F1B4F;
|
||||
--error-15: #FF54A126;
|
||||
--error-card: #FADCE9;
|
||||
--grades-1: #FF54A1;
|
||||
--grades-2: #FFA046;
|
||||
--grades-3: #F9CF00;
|
||||
--grades-4: #92EA3B;
|
||||
--grades-5: #22CCAD;
|
||||
--grades-background-1: #FF54A126;
|
||||
--grades-background-2: #FFA04626;
|
||||
--grades-background-3: #F9CF0026;
|
||||
--grades-background-4: #92EA3B26;
|
||||
--grades-background-5: #22CCAD26;
|
||||
--background:#FAFFF0;
|
||||
--background-0:#fafff000;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:2px;
|
||||
--text-primary:#394C0A;
|
||||
--text-secondary:#394c0acc;
|
||||
--text-teritary:#394c0a80;
|
||||
--card-card:#F3FBDE;
|
||||
--card-translucent:#f3fbde80;
|
||||
--button-secondaryFill:#FEFFFD;
|
||||
--accent-accent:#A7DC22;
|
||||
--accent-secondary:#6E8F1B;
|
||||
--accent-shadow:#647e2226;
|
||||
--accent-15:#a7dc2226;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#8F531B;
|
||||
--warning-15:#ffa04626;
|
||||
--warning-card:#FAEBDC;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#8F1B4F;
|
||||
--error-15:#FF54A126;
|
||||
--error-card:#FADCE9;
|
||||
--grades-1:#FF54A1;
|
||||
--grades-2:#FFA046;
|
||||
--grades-3:#F9CF00;
|
||||
--grades-4:#92EA3B;
|
||||
--grades-5:#22CCAD;
|
||||
--grades-background-1:#FF54A126;
|
||||
--grades-background-2:#FFA04626;
|
||||
--grades-background-3:#F9CF0026;
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="dark-blue"] {
|
||||
--background: #070A0E;
|
||||
--background-0: #070a0e00;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 0;
|
||||
--text-primary: #EBF1FD;
|
||||
--text-secondary: #ebf1fdcc;
|
||||
--text-teritary: #ebf1fd80;
|
||||
--card-card: #0F131B;
|
||||
--card-translucent: #0f131b80;
|
||||
--button-secondaryFill: #131822;
|
||||
--accent-accent: #3673EE;
|
||||
--accent-secondary: #AEC8FC;
|
||||
--accent-shadow: #0000;
|
||||
--accent-15: #3673ee26;
|
||||
--warning-accent: var(--grades-2);
|
||||
--warning-text: #f0b37a;
|
||||
--warning-15: #ffa04626;
|
||||
--warning-card: #201203;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #f59ec5;
|
||||
--error-15: #ff54a126;
|
||||
--error-card: #1e030f;
|
||||
--grades-1: #FF54A1;
|
||||
--grades-2: #FFA046;
|
||||
--grades-3: #F9CF00;
|
||||
--grades-4: #92EA3B;
|
||||
--grades-5: #22CCAD;
|
||||
--grades-background-1: #FF54A126;
|
||||
--grades-background-2: #FFA04626;
|
||||
--grades-background-3: #F9CF0026;
|
||||
--grades-background-4: #92EA3B26;
|
||||
--grades-background-5: #22CCAD26;
|
||||
--background:#070A0E;
|
||||
--background-0:#070a0e00;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:0;
|
||||
--text-primary:#EBF1FD;
|
||||
--text-secondary:#ebf1fdcc;
|
||||
--text-teritary:#ebf1fd80;
|
||||
--card-card:#0F131B;
|
||||
--card-translucent:#0f131b80;
|
||||
--button-secondaryFill:#131822;
|
||||
--accent-accent:#3673EE;
|
||||
--accent-secondary:#AEC8FC;
|
||||
--accent-shadow:#0000;
|
||||
--accent-15:#3673ee26;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#f0b37a;
|
||||
--warning-15:#ffa04626;
|
||||
--warning-card:#201203;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#f59ec5;
|
||||
--error-15:#ff54a126;
|
||||
--error-card:#1e030f;
|
||||
--grades-1:#FF54A1;
|
||||
--grades-2:#FFA046;
|
||||
--grades-3:#F9CF00;
|
||||
--grades-4:#92EA3B;
|
||||
--grades-5:#22CCAD;
|
||||
--grades-background-1:#FF54A126;
|
||||
--grades-background-2:#FFA04626;
|
||||
--grades-background-3:#F9CF0026;
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="dark-green"] {
|
||||
--background: #0D1202;
|
||||
--background-0: #0E130200;
|
||||
--success: var(--grades-4);
|
||||
--shadow-blur: 0;
|
||||
--text-primary: #EAF7CC;
|
||||
--text-secondary: #EAF7CCCC;
|
||||
--text-teritary: #EAF7CC80;
|
||||
--card-card: #141905;
|
||||
--card-translucent: #14190580;
|
||||
--button-secondaryFill: #20290b;
|
||||
--accent-accent: #A7DC22;
|
||||
--accent-secondary: #CBEE71;
|
||||
--accent-shadow: #0000;
|
||||
--accent-15: #a7dc2226;
|
||||
--warning-accent: var(--grades-2);
|
||||
--warning-text: #f0b37a;
|
||||
--warning-15: #ffa04626;
|
||||
--warning-card: #201203;
|
||||
--error-accent: var(--grades-1);
|
||||
--error-text: #f59ec5;
|
||||
--error-15: #ff54a126;
|
||||
--error-card: #1e030f;
|
||||
--grades-1: #FF54A1;
|
||||
--grades-2: #FFA046;
|
||||
--grades-3: #F9CF00;
|
||||
--grades-4: #92EA3B;
|
||||
--grades-5: #22CCAD;
|
||||
--grades-background-1: #FF54A126;
|
||||
--grades-background-2: #FFA04626;
|
||||
--grades-background-3: #F9CF0026;
|
||||
--grades-background-4: #92EA3B26;
|
||||
--grades-background-5: #22CCAD26;
|
||||
--background:#0D1202;
|
||||
--background-0:#0E130200;
|
||||
--success:var(--grades-4);
|
||||
--shadow-blur:0;
|
||||
--text-primary:#EAF7CC;
|
||||
--text-secondary:#EAF7CCCC;
|
||||
--text-teritary:#EAF7CC80;
|
||||
--card-card:#141905;
|
||||
--card-translucent:#14190580;
|
||||
--button-secondaryFill:#20290b;
|
||||
--accent-accent:#A7DC22;
|
||||
--accent-secondary:#CBEE71;
|
||||
--accent-shadow:#0000;
|
||||
--accent-15:#a7dc2226;
|
||||
--warning-accent:var(--grades-2);
|
||||
--warning-text:#f0b37a;
|
||||
--warning-15:#ffa04626;
|
||||
--warning-card:#201203;
|
||||
--error-accent:var(--grades-1);
|
||||
--error-text:#f59ec5;
|
||||
--error-15:#ff54a126;
|
||||
--error-card:#1e030f;
|
||||
--grades-1:#FF54A1;
|
||||
--grades-2:#FFA046;
|
||||
--grades-3:#F9CF00;
|
||||
--grades-4:#92EA3B;
|
||||
--grades-5:#22CCAD;
|
||||
--grades-background-1:#FF54A126;
|
||||
--grades-background-2:#FFA04626;
|
||||
--grades-background-3:#F9CF0026;
|
||||
--grades-background-4:#92EA3B26;
|
||||
--grades-background-5:#22CCAD26;
|
||||
}
|
||||
|
||||
|
||||
html {
|
||||
background-color: var(--background) !important;
|
||||
color: var(--text-primary) !important;
|
||||
background-color:var(--background) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background) !important;
|
||||
color: var(--text-primary) !important;
|
||||
transition: background-color 0.2s ease, color 0.2s ease;
|
||||
min-height: 100vh;
|
||||
background-color:var(--background) !important;
|
||||
color:var(--text-primary) !important;
|
||||
transition:background-color 0.2s ease,color 0.2s ease;
|
||||
min-height:100vh;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
||||
}
|
||||
transition:background-color 0.2s ease,color 0.2s ease,border-color 0.2s ease;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width:clamp(4px,1vw,8px);
|
||||
height:clamp(4px,1vw,8px);
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background:var(--background);
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background:var(--text-secondary);
|
||||
border-radius:4px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background:var(--text-primary);
|
||||
}
|
||||
|
||||
323
global/theme.js
@@ -1,132 +1,215 @@
|
||||
(() => {
|
||||
function setTheme(theme) {
|
||||
try {
|
||||
const actualTheme = theme === 'default' ? 'light-blue' : theme;
|
||||
|
||||
document.documentElement.setAttribute('data-theme', actualTheme);
|
||||
cookieManager.set('themePreference', actualTheme);
|
||||
localStorage.setItem('themePreference', actualTheme);
|
||||
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'themeChanged',
|
||||
theme: actualTheme
|
||||
}).catch(() => {
|
||||
async function setTheme(theme) {
|
||||
try {
|
||||
const actualTheme = theme === "default" ? "light-blue" : theme;
|
||||
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error setting theme:', error);
|
||||
}
|
||||
document.documentElement.setAttribute("data-theme", actualTheme);
|
||||
|
||||
await storageManager.set("themePreference", actualTheme);
|
||||
|
||||
localStorage.setItem("themePreference", actualTheme);
|
||||
|
||||
chrome.runtime
|
||||
.sendMessage({
|
||||
action: "themeChanged",
|
||||
theme: actualTheme,
|
||||
})
|
||||
.catch(() => {});
|
||||
} catch (error) {
|
||||
console.error("Error setting theme:", error);
|
||||
}
|
||||
|
||||
function setPageTitleAndFavicon() {
|
||||
try {
|
||||
document.title = 'Firka - KRÉTA';
|
||||
}
|
||||
|
||||
const existingFavicons = document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"]');
|
||||
existingFavicons.forEach(link => link.remove());
|
||||
|
||||
if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.getURL) {
|
||||
const favicon = document.createElement('link');
|
||||
favicon.rel = 'icon';
|
||||
favicon.type = 'image/png';
|
||||
favicon.href = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
document.head.appendChild(favicon);
|
||||
|
||||
const shortcutIcon = document.createElement('link');
|
||||
shortcutIcon.rel = 'shortcut icon';
|
||||
shortcutIcon.type = 'image/png';
|
||||
shortcutIcon.href = chrome.runtime.getURL('images/firka_logo_128.png');
|
||||
document.head.appendChild(shortcutIcon);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error setting page title and favicon:', error);
|
||||
function importFonts() {
|
||||
try {
|
||||
const fontFaces = `
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-Regular.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
}
|
||||
|
||||
function initializeTheme() {
|
||||
const cookieTheme = cookieManager.get('themePreference');
|
||||
const localStorageTheme = localStorage.getItem('themePreference');
|
||||
|
||||
const theme = cookieTheme || localStorageTheme || 'light-green';
|
||||
|
||||
setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
|
||||
if (cookieTheme !== localStorageTheme) {
|
||||
if (cookieTheme) {
|
||||
localStorage.setItem('themePreference', cookieTheme);
|
||||
} else if (localStorageTheme) {
|
||||
cookieManager.set('themePreference', localStorageTheme);
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-Medium.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Montserrat';
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
src: url('${chrome.runtime.getURL('fonts/Montserrat-SemiBold.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Figtree';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Figtree-Regular.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
`;
|
||||
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = fontFaces;
|
||||
document.head.appendChild(styleElement);
|
||||
|
||||
const iconFontFace = `
|
||||
@font-face {
|
||||
font-family: 'Material Icons Round';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url('${chrome.runtime.getURL('fonts/Icons.woff2')}') format('woff2');
|
||||
font-display: swap;
|
||||
}
|
||||
`;
|
||||
|
||||
const iconStyleElement = document.createElement('style');
|
||||
iconStyleElement.textContent = iconFontFace;
|
||||
document.head.appendChild(iconStyleElement);
|
||||
} catch (error) {
|
||||
console.error("Error importing fonts:", error);
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initializeTheme);
|
||||
} else {
|
||||
initializeTheme();
|
||||
}
|
||||
|
||||
function setPageTitleAndFavicon() {
|
||||
try {
|
||||
document.title = "Firka - KRÉTA";
|
||||
|
||||
const existingFavicons = document.querySelectorAll(
|
||||
'link[rel="icon"], link[rel="shortcut icon"]',
|
||||
);
|
||||
existingFavicons.forEach((link) => link.remove());
|
||||
|
||||
if (
|
||||
typeof chrome !== "undefined" &&
|
||||
chrome.runtime &&
|
||||
chrome.runtime.getURL
|
||||
) {
|
||||
const favicon = document.createElement("link");
|
||||
favicon.rel = "icon";
|
||||
favicon.type = "image/png";
|
||||
favicon.href = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
document.head.appendChild(favicon);
|
||||
|
||||
const shortcutIcon = document.createElement("link");
|
||||
shortcutIcon.rel = "shortcut icon";
|
||||
shortcutIcon.type = "image/png";
|
||||
shortcutIcon.href = chrome.runtime.getURL("images/firka_logo_128.png");
|
||||
document.head.appendChild(shortcutIcon);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error setting page title and favicon:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function initializeTheme() {
|
||||
try {
|
||||
const storageTheme = await storageManager.get("themePreference");
|
||||
const localStorageTheme = localStorage.getItem("themePreference");
|
||||
|
||||
const theme = storageTheme || localStorageTheme || "light-green";
|
||||
|
||||
await setTheme(theme);
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
|
||||
if (storageTheme !== localStorageTheme) {
|
||||
if (storageTheme) {
|
||||
localStorage.setItem("themePreference", storageTheme);
|
||||
} else if (localStorageTheme) {
|
||||
await storageManager.set("themePreference", localStorageTheme);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error initializing theme:", error);
|
||||
await setTheme("light-green");
|
||||
setPageTitleAndFavicon();
|
||||
importFonts();
|
||||
}
|
||||
}
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", initializeTheme);
|
||||
} else {
|
||||
initializeTheme();
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === "changeTheme") {
|
||||
setTheme(message.theme);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'changeTheme') {
|
||||
setTheme(message.theme);
|
||||
sendResponse({ success: true });
|
||||
}
|
||||
|
||||
if (message.action === 'getTheme') {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme') || 'light-green';
|
||||
sendResponse({ theme: currentTheme });
|
||||
}
|
||||
if (message.action === "getTheme") {
|
||||
const currentTheme =
|
||||
document.documentElement.getAttribute("data-theme") || "light-green";
|
||||
sendResponse({ theme: currentTheme });
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
});
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver(async (mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute("data-theme");
|
||||
|
||||
try {
|
||||
const savedTheme = await storageManager.get("themePreference") ||
|
||||
localStorage.getItem("themePreference");
|
||||
|
||||
if (
|
||||
(!currentTheme && savedTheme) ||
|
||||
(currentTheme !== savedTheme && savedTheme)
|
||||
) {
|
||||
await setTheme(savedTheme);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error checking theme in observer:", error);
|
||||
}
|
||||
|
||||
const titleChanged = mutations.some(
|
||||
(mutation) =>
|
||||
mutation.type === "childList" &&
|
||||
mutation.target === document.head &&
|
||||
Array.from(mutation.addedNodes).some(
|
||||
(node) => node.tagName === "TITLE",
|
||||
),
|
||||
);
|
||||
|
||||
if (titleChanged || document.title !== "Firka - KRÉTA") {
|
||||
clearTimeout(titleCheckTimeout);
|
||||
titleCheckTimeout = setTimeout(() => {
|
||||
if (document.title !== "Firka - KRÉTA") {
|
||||
setPageTitleAndFavicon();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-theme"],
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
});
|
||||
|
||||
let titleCheckTimeout;
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const currentTheme = document.documentElement.getAttribute('data-theme');
|
||||
const savedTheme = cookieManager.get('themePreference') || localStorage.getItem('themePreference');
|
||||
|
||||
if ((!currentTheme && savedTheme) || (currentTheme !== savedTheme && savedTheme)) {
|
||||
setTheme(savedTheme);
|
||||
}
|
||||
|
||||
const titleChanged = mutations.some(mutation =>
|
||||
mutation.type === 'childList' &&
|
||||
mutation.target === document.head &&
|
||||
Array.from(mutation.addedNodes).some(node => node.tagName === 'TITLE')
|
||||
);
|
||||
|
||||
if (titleChanged || document.title !== 'Firka - KRÉTA') {
|
||||
clearTimeout(titleCheckTimeout);
|
||||
titleCheckTimeout = setTimeout(() => {
|
||||
if (document.title !== 'Firka - KRÉTA') {
|
||||
setPageTitleAndFavicon();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
} else {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ["data-theme"],
|
||||
});
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['data-theme']
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
} else {
|
||||
observer.observe(document.documentElement, {
|
||||
attributes: true,
|
||||
attributeFilter: ['data-theme']
|
||||
});
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
})();
|
||||
observer.observe(document.head, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
1355
grades/grades.css
1217
grades/grades.js
@@ -169,6 +169,7 @@ body {
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--accent-15);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +201,108 @@ body {
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
/* Checkbox oszlop stílusai */
|
||||
.checkbox-header {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
padding: 8px !important;
|
||||
}
|
||||
|
||||
.homework-checkbox {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
cursor: pointer;
|
||||
appearance: none;
|
||||
border: 2px solid var(--accent-30);
|
||||
border-radius: 4px;
|
||||
background-color: var(--card-card);
|
||||
position: relative;
|
||||
transition: all 0.2s ease;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.homework-checkbox:hover {
|
||||
border-color: var(--accent);
|
||||
background-color: var(--accent-15);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.homework-checkbox:checked {
|
||||
background-color: var(--accent);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
.homework-checkbox:checked::after {
|
||||
content: '✓';
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.homework-checkbox:focus {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.homework-checkbox:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Megjelölt házi feladatok stílusai */
|
||||
.table-row.user-completed {
|
||||
opacity: 0.6;
|
||||
background-color: var(--accent-15) !important;
|
||||
}
|
||||
|
||||
.table-row.user-completed .table-cell {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.table-row.user-completed .status-badge.completed {
|
||||
background-color: var(--success);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Mobil nézet checkbox stílusai */
|
||||
@media (max-width: 768px) {
|
||||
.checkbox-header {
|
||||
width: 40px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.checkbox-cell {
|
||||
width: 40px;
|
||||
padding: 6px !important;
|
||||
}
|
||||
|
||||
.homework-checkbox {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.homework-checkbox:checked::after {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.table-row.user-completed {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-content {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
@@ -269,37 +372,145 @@ body {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
|
||||
.homework-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.stats-overview {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.homework-date-group {
|
||||
.stat-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition: transform 0.2s ease;
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: var(--accent-accent);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.stat-card.urgent .stat-number {
|
||||
color: #ff4757;
|
||||
}
|
||||
|
||||
.stat-card.completed .stat-number {
|
||||
color: #2ed573;
|
||||
}
|
||||
|
||||
.homework-container {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
animation: fadeIn 0.3s ease;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.date-header {
|
||||
padding: 16px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
.homework-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.homework-count {
|
||||
margin-left: auto;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
.table-header {
|
||||
background: var(--accent-15);
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
|
||||
.table-header th {
|
||||
padding: 16px;
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: var(--accent-15);
|
||||
}
|
||||
|
||||
.table-row.due-tomorrow {
|
||||
background-color: rgba(255, 71, 87, 0.1);
|
||||
}
|
||||
|
||||
.table-row.due-tomorrow:hover {
|
||||
background-color: rgba(255, 71, 87, 0.2);
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 16px;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.date-cell {
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.subject-cell {
|
||||
font-weight: 500;
|
||||
color: var(--accent-accent);
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: 300px;
|
||||
word-wrap: break-word;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.teacher-cell {
|
||||
color: var(--text-secondary);
|
||||
font-style: italic;
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.status-cell {
|
||||
text-align: center;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.status-badge.pending {
|
||||
background-color: rgba(255, 193, 7, 0.2);
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.status-badge.urgent {
|
||||
background-color: rgba(255, 71, 87, 0.2);
|
||||
color: #ff4757;
|
||||
}
|
||||
|
||||
.status-badge.completed {
|
||||
background-color: rgba(46, 213, 115, 0.2);
|
||||
color: #2ed573;
|
||||
}
|
||||
|
||||
.homework-list-items {
|
||||
@@ -398,6 +609,104 @@ body {
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
padding: 12px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.homework-container {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.homework-table,
|
||||
.table-header,
|
||||
.table-row,
|
||||
.table-cell {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.date-group {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.date-group-header {
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
padding: 12px 16px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
border-radius: 12px 12px 0 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.date-group-content {
|
||||
background: var(--card-card);
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 0 0 12px 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: block;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
padding: 16px;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.table-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.table-cell {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.table-cell:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.table-cell::before {
|
||||
content: attr(data-label);
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: none;
|
||||
white-space: normal;
|
||||
text-overflow: initial;
|
||||
overflow: visible;
|
||||
text-align: right;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stats-overview {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
|
||||
@@ -2,62 +2,64 @@ async function fetchHomeworkData() {
|
||||
try {
|
||||
const currentDomain = window.location.hostname;
|
||||
const apiUrl = `https://${currentDomain}/api/TanuloHaziFeladatApi/GetTanulotHaziFeladatGrid?sort=HaziFeladatHatarido-asc&page=1&pageSize=100&group=&filter=&data=%7B%22RegiHaziFeladatokElrejtese%22%3Afalse%7D&_=${Date.now()}`;
|
||||
|
||||
|
||||
const response = await fetch(apiUrl, {
|
||||
method: 'GET',
|
||||
credentials: 'include',
|
||||
method: "GET",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
throw new Error("Network response was not ok");
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error('Error fetching homework data:', error);
|
||||
console.error("Error fetching homework data:", error);
|
||||
return { Data: [], Total: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
async function collectHomeworkData() {
|
||||
const apiData = await fetchHomeworkData();
|
||||
|
||||
|
||||
const basicData = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get('schoolName') || 'Iskola',
|
||||
id: cookieManager.get('schoolCode') || ''
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get('userName') || 'Felhasználó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00'
|
||||
}
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
const homeworkItems = [];
|
||||
|
||||
|
||||
if (apiData.Data && Array.isArray(apiData.Data)) {
|
||||
apiData.Data.forEach(item => {
|
||||
apiData.Data.forEach((item) => {
|
||||
homeworkItems.push({
|
||||
id: item.ID,
|
||||
subject: item.TantargyNev || '',
|
||||
teacher: item.TanarNeve || '',
|
||||
description: item.HaziFeladatSzoveg || '',
|
||||
subject: item.TantargyNev || "",
|
||||
teacher: item.TanarNeve || "",
|
||||
description: item.HaziFeladatSzoveg || "",
|
||||
createdDate: formatApiDate(item.HaziFeladatRogzitesDatuma),
|
||||
deadline: formatApiDate(item.HaziFeladatHatarido),
|
||||
completed: item.MegoldottHF_BOOL || false,
|
||||
classGroup: item.OsztalyCsoport || ''
|
||||
classGroup: item.OsztalyCsoport || "",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const groupedHomework = {};
|
||||
homeworkItems.forEach(homework => {
|
||||
const deadlineDate = homework.deadline.split(' ')[0];
|
||||
homeworkItems.forEach((homework) => {
|
||||
const deadlineDate = homework.deadline.split(" ")[0];
|
||||
if (!groupedHomework[deadlineDate]) {
|
||||
groupedHomework[deadlineDate] = [];
|
||||
}
|
||||
@@ -68,24 +70,24 @@ async function collectHomeworkData() {
|
||||
}
|
||||
|
||||
function formatApiDate(dateString) {
|
||||
if (!dateString) return '';
|
||||
|
||||
if (!dateString) return "";
|
||||
|
||||
try {
|
||||
const date = new Date(dateString);
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
const dayNames = [
|
||||
LanguageManager.t('common.sunday'),
|
||||
LanguageManager.t('common.monday'),
|
||||
LanguageManager.t('common.tuesday'),
|
||||
LanguageManager.t('common.wednesday'),
|
||||
LanguageManager.t('common.thursday'),
|
||||
LanguageManager.t('common.friday'),
|
||||
LanguageManager.t('common.saturday')
|
||||
LanguageManager.t("common.sunday"),
|
||||
LanguageManager.t("common.monday"),
|
||||
LanguageManager.t("common.tuesday"),
|
||||
LanguageManager.t("common.wednesday"),
|
||||
LanguageManager.t("common.thursday"),
|
||||
LanguageManager.t("common.friday"),
|
||||
LanguageManager.t("common.saturday"),
|
||||
];
|
||||
const dayName = dayNames[date.getDay()];
|
||||
|
||||
|
||||
return `${month}.${day}. (${dayName})`;
|
||||
} catch (error) {
|
||||
return dateString;
|
||||
@@ -94,341 +96,617 @@ function formatApiDate(dateString) {
|
||||
|
||||
function isTomorrow(dateStr) {
|
||||
if (!dateStr) return false;
|
||||
|
||||
|
||||
const parts = dateStr.split('.');
|
||||
|
||||
const parts = dateStr.split(".");
|
||||
if (parts.length < 3) return false;
|
||||
|
||||
|
||||
const year = parseInt(parts[0].trim());
|
||||
const month = parseInt(parts[1].trim()) - 1;
|
||||
const day = parseInt(parts[2].trim());
|
||||
|
||||
|
||||
const homeworkDate = new Date(year, month, day);
|
||||
|
||||
|
||||
|
||||
const tomorrow = new Date();
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
tomorrow.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
|
||||
const dayAfterTomorrow = new Date(tomorrow);
|
||||
dayAfterTomorrow.setDate(dayAfterTomorrow.getDate() + 1);
|
||||
|
||||
|
||||
|
||||
return homeworkDate >= tomorrow && homeworkDate < dayAfterTomorrow;
|
||||
}
|
||||
|
||||
async function transformHomeworkPage() {
|
||||
const { basicData, homeworkItems, groupedHomework } = await collectHomeworkData();
|
||||
const { basicData, homeworkItems, groupedHomework } =
|
||||
await collectHomeworkData();
|
||||
document.body.innerHTML = '';
|
||||
const kretaContainer = document.createElement('div');
|
||||
kretaContainer.className = 'kreta-container';
|
||||
const headerDiv = document.createElement('div');
|
||||
const parser = new DOMParser();
|
||||
const headerDoc = parser.parseFromString(await createTemplate.header(), 'text/html');
|
||||
const headerContent = headerDoc.body;
|
||||
while (headerContent.firstChild) {
|
||||
headerDiv.appendChild(headerContent.firstChild);
|
||||
}
|
||||
kretaContainer.appendChild(headerDiv);
|
||||
const main = document.createElement('main');
|
||||
main.className = 'kreta-main';
|
||||
|
||||
document.body.innerHTML = `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
const filterCard = document.createElement('div');
|
||||
filterCard.className = 'filter-card';
|
||||
|
||||
const filterHeader = document.createElement('div');
|
||||
filterHeader.className = 'filter-header';
|
||||
const filterTitle = document.createElement('h2');
|
||||
filterTitle.textContent = LanguageManager.t('homework.filter_title');
|
||||
filterHeader.appendChild(filterTitle);
|
||||
|
||||
const filterContent = document.createElement('div');
|
||||
filterContent.className = 'filter-content';
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="filter-card">
|
||||
<div class="filter-header">
|
||||
<h2>${LanguageManager.t('homework.filter_title')}</h2>
|
||||
</div>
|
||||
<div class="filter-content">
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">subject</span>-->
|
||||
${LanguageManager.t('homework.subject')}
|
||||
</label>
|
||||
<select id="subjectFilter">
|
||||
<option value="">${LanguageManager.t('homework.all_subjects')}</option>
|
||||
${[...new Set(homeworkItems.map(item => item.subject))]
|
||||
.sort()
|
||||
.map(subject => `<option value="${subject}">${subject}</option>`)
|
||||
.join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">person</span>-->
|
||||
${LanguageManager.t('homework.teacher')}
|
||||
</label>
|
||||
<select id="teacherFilter">
|
||||
<option value="">${LanguageManager.t('homework.all_teachers')}</option>
|
||||
${[...new Set(homeworkItems.map(item => item.teacher))]
|
||||
.sort()
|
||||
.map(teacher => `<option value="${teacher}">${teacher}</option>`)
|
||||
.join('')}
|
||||
</select>
|
||||
</div>
|
||||
<div class="filter-group">
|
||||
<label>
|
||||
<!--<span class="material-icons-round">date_range</span>-->
|
||||
${LanguageManager.t('homework.due_date')}
|
||||
</label>
|
||||
<select id="deadlineFilter">
|
||||
<option value="">${LanguageManager.t('homework.all_deadlines')}</option>
|
||||
<option value="tomorrow">${LanguageManager.t('homework.tomorrow_deadline')}</option>
|
||||
<option value="thisWeek">${LanguageManager.t('homework.this_week')}</option>
|
||||
<option value="nextWeek">${LanguageManager.t('homework.next_week')}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
const subjectGroup = document.createElement('div');
|
||||
subjectGroup.className = 'filter-group';
|
||||
const subjectLabel = document.createElement('label');
|
||||
subjectLabel.textContent = LanguageManager.t('homework.subject');
|
||||
const subjectSelect = document.createElement('select');
|
||||
subjectSelect.id = 'subjectFilter';
|
||||
|
||||
const allSubjectsOption = document.createElement('option');
|
||||
allSubjectsOption.value = '';
|
||||
allSubjectsOption.textContent = LanguageManager.t('homework.all_subjects');
|
||||
subjectSelect.appendChild(allSubjectsOption);
|
||||
|
||||
[...new Set(homeworkItems.map((item) => item.subject))]
|
||||
.sort()
|
||||
.forEach((subject) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = subject;
|
||||
option.textContent = subject;
|
||||
subjectSelect.appendChild(option);
|
||||
});
|
||||
|
||||
subjectGroup.appendChild(subjectLabel);
|
||||
subjectGroup.appendChild(subjectSelect);
|
||||
|
||||
<div class="homework-list" id="homeworkList">
|
||||
${renderHomeworkList(groupedHomework)}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
const teacherGroup = document.createElement('div');
|
||||
teacherGroup.className = 'filter-group';
|
||||
const teacherLabel = document.createElement('label');
|
||||
teacherLabel.textContent = LanguageManager.t('homework.teacher');
|
||||
const teacherSelect = document.createElement('select');
|
||||
teacherSelect.id = 'teacherFilter';
|
||||
|
||||
const allTeachersOption = document.createElement('option');
|
||||
allTeachersOption.value = '';
|
||||
allTeachersOption.textContent = LanguageManager.t('homework.all_teachers');
|
||||
teacherSelect.appendChild(allTeachersOption);
|
||||
|
||||
[...new Set(homeworkItems.map((item) => item.teacher))]
|
||||
.sort()
|
||||
.forEach((teacher) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = teacher;
|
||||
option.textContent = teacher;
|
||||
teacherSelect.appendChild(option);
|
||||
});
|
||||
|
||||
teacherGroup.appendChild(teacherLabel);
|
||||
teacherGroup.appendChild(teacherSelect);
|
||||
|
||||
const deadlineGroup = document.createElement('div');
|
||||
deadlineGroup.className = 'filter-group';
|
||||
const deadlineLabel = document.createElement('label');
|
||||
deadlineLabel.textContent = LanguageManager.t('homework.due_date');
|
||||
const deadlineSelect = document.createElement('select');
|
||||
deadlineSelect.id = 'deadlineFilter';
|
||||
|
||||
const deadlineOptions = [
|
||||
{ value: '', text: LanguageManager.t('homework.all_deadlines') },
|
||||
{ value: 'tomorrow', text: LanguageManager.t('homework.tomorrow_deadline') },
|
||||
{ value: 'thisWeek', text: LanguageManager.t('homework.this_week') },
|
||||
{ value: 'nextWeek', text: LanguageManager.t('homework.next_week') }
|
||||
];
|
||||
|
||||
deadlineOptions.forEach(({ value, text }) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = value;
|
||||
option.textContent = text;
|
||||
deadlineSelect.appendChild(option);
|
||||
});
|
||||
|
||||
deadlineGroup.appendChild(deadlineLabel);
|
||||
deadlineGroup.appendChild(deadlineSelect);
|
||||
|
||||
filterContent.appendChild(subjectGroup);
|
||||
filterContent.appendChild(teacherGroup);
|
||||
filterContent.appendChild(deadlineGroup);
|
||||
|
||||
filterCard.appendChild(filterHeader);
|
||||
filterCard.appendChild(filterContent);
|
||||
|
||||
const statsOverview = document.createElement('div');
|
||||
statsOverview.className = 'stats-overview';
|
||||
statsOverview.id = 'statsOverview';
|
||||
|
||||
const statCards = [
|
||||
{ id: 'totalHomework', label: LanguageManager.t('homework.total_homework'), className: '' },
|
||||
{ id: 'urgentHomework', label: LanguageManager.t('homework.urgent_homework'), className: 'urgent' },
|
||||
{ id: 'completedHomework', label: LanguageManager.t('homework.completed_homework'), className: 'completed' },
|
||||
{ id: 'pendingHomework', label: LanguageManager.t('homework.pending_homework'), className: '' }
|
||||
];
|
||||
|
||||
statCards.forEach(({ id, label, className }) => {
|
||||
const statCard = document.createElement('div');
|
||||
statCard.className = `stat-card ${className}`.trim();
|
||||
|
||||
const statNumber = document.createElement('div');
|
||||
statNumber.className = 'stat-number';
|
||||
statNumber.id = id;
|
||||
statNumber.textContent = '0';
|
||||
|
||||
const statLabel = document.createElement('div');
|
||||
statLabel.className = 'stat-label';
|
||||
statLabel.textContent = label;
|
||||
|
||||
statCard.appendChild(statNumber);
|
||||
statCard.appendChild(statLabel);
|
||||
statsOverview.appendChild(statCard);
|
||||
});
|
||||
|
||||
const homeworkContainer = document.createElement('div');
|
||||
homeworkContainer.className = 'homework-container';
|
||||
|
||||
const homeworkTable = document.createElement('table');
|
||||
homeworkTable.className = 'homework-table';
|
||||
homeworkTable.id = 'homeworkTable';
|
||||
|
||||
const thead = document.createElement('thead');
|
||||
thead.className = 'table-header';
|
||||
const headerRow = document.createElement('tr');
|
||||
|
||||
const headers = [
|
||||
'✓',
|
||||
LanguageManager.t('homework.due_date'),
|
||||
LanguageManager.t('homework.subject'),
|
||||
LanguageManager.t('homework.description'),
|
||||
LanguageManager.t('homework.teacher'),
|
||||
LanguageManager.t('homework.status')
|
||||
];
|
||||
|
||||
headers.forEach((headerText, index) => {
|
||||
const th = document.createElement('th');
|
||||
th.textContent = headerText;
|
||||
if (index === 0) {
|
||||
th.className = 'checkbox-header';
|
||||
}
|
||||
headerRow.appendChild(th);
|
||||
});
|
||||
|
||||
thead.appendChild(headerRow);
|
||||
|
||||
const tbody = document.createElement('tbody');
|
||||
tbody.id = 'homeworkTableBody';
|
||||
const homeworkHTML = generateHomeworkHTML(homeworkItems);
|
||||
|
||||
if (homeworkHTML.trim()) {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(`<table><tbody>${homeworkHTML}</tbody></table>`, 'text/html');
|
||||
const tempTbody = doc.querySelector('tbody');
|
||||
while (tempTbody.firstChild) {
|
||||
tbody.appendChild(tempTbody.firstChild);
|
||||
}
|
||||
} else {
|
||||
const emptyRow = document.createElement('tr');
|
||||
const emptyCell = document.createElement('td');
|
||||
emptyCell.colSpan = 5;
|
||||
emptyCell.textContent = LanguageManager.t('homework.no_homework') || 'Nincs házi feladat';
|
||||
emptyCell.style.textAlign = 'center';
|
||||
emptyCell.style.padding = '20px';
|
||||
emptyRow.appendChild(emptyCell);
|
||||
tbody.appendChild(emptyRow);
|
||||
}
|
||||
|
||||
homeworkTable.appendChild(thead);
|
||||
homeworkTable.appendChild(tbody);
|
||||
homeworkContainer.appendChild(homeworkTable);
|
||||
|
||||
main.appendChild(filterCard);
|
||||
main.appendChild(statsOverview);
|
||||
main.appendChild(homeworkContainer);
|
||||
|
||||
kretaContainer.appendChild(main);
|
||||
document.body.appendChild(kretaContainer);
|
||||
|
||||
setupFilters(homeworkItems, groupedHomework);
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
setupMobileGrouping();
|
||||
updateStatistics();
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
function renderHomeworkList(groupedHomework) {
|
||||
const sortedDates = Object.keys(groupedHomework).sort((a, b) => {
|
||||
const partsA = a.split('.');
|
||||
const partsB = b.split('.');
|
||||
|
||||
const monthA = parseInt(partsA[0]) - 1;
|
||||
const dayA = parseInt(partsA[1]);
|
||||
const monthB = parseInt(partsB[0]) - 1;
|
||||
const dayB = parseInt(partsB[1]);
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const currentMonth = new Date().getMonth();
|
||||
|
||||
const yearA = monthA < currentMonth ? currentYear + 1 : currentYear;
|
||||
const yearB = monthB < currentMonth ? currentYear + 1 : currentYear;
|
||||
|
||||
const dateA = new Date(yearA, monthA, dayA);
|
||||
const dateB = new Date(yearB, monthB, dayB);
|
||||
|
||||
return dateB - dateA;
|
||||
function generateHomeworkHTML(homeworkItems) {
|
||||
const sortedHomework = homeworkItems.sort((a, b) => {
|
||||
const dateA = new Date(
|
||||
a.deadline.split(" ")[0].split(".").reverse().join("-"),
|
||||
);
|
||||
const dateB = new Date(
|
||||
b.deadline.split(" ")[0].split(".").reverse().join("-"),
|
||||
);
|
||||
return dateA - dateB;
|
||||
});
|
||||
|
||||
if (sortedDates.length === 0) {
|
||||
return `
|
||||
<div class="empty-state">
|
||||
<p>${LanguageManager.t('homework.no_homework')}</p>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
return sortedHomework
|
||||
.map((homework) => {
|
||||
const isUrgent = isTomorrow(homework.deadline);
|
||||
const isUserCompleted = getHomeworkCompletionStatus(homework.id);
|
||||
const status = homework.completed || isUserCompleted
|
||||
? "completed"
|
||||
: isUrgent
|
||||
? "urgent"
|
||||
: "pending";
|
||||
const statusText = homework.completed || isUserCompleted
|
||||
? LanguageManager.t("homework.completed")
|
||||
: isUrgent
|
||||
? LanguageManager.t("homework.urgent")
|
||||
: LanguageManager.t("homework.pending");
|
||||
|
||||
return sortedDates.map(date => {
|
||||
const homeworkItems = groupedHomework[date];
|
||||
return `
|
||||
<div class="homework-date-group" data-date="${date}">
|
||||
<div class="date-header">
|
||||
<h3>${formatDateHeader(date)}</h3>
|
||||
<span class="homework-count">${homeworkItems.length} ${LanguageManager.t('homework.items') || 'feladat'}</span>
|
||||
</div>
|
||||
<div class="homework-list-items">
|
||||
${homeworkItems.map(homework => {
|
||||
const isTomorrowClass = isTomorrow(homework.deadline) ? 'due-tomorrow' : '';
|
||||
const urgentClass = isTomorrow(homework.deadline) ? 'urgent' : '';
|
||||
|
||||
return `
|
||||
<div class="homework-item ${isTomorrowClass}" data-subject="${homework.subject}" data-teacher="${homework.teacher}">
|
||||
<div class="homework-details">
|
||||
<div class="homework-subject">${homework.subject}</div>
|
||||
<div class="homework-content">${homework.description}</div>
|
||||
<div class="homework-teacher">${homework.teacher}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('')}
|
||||
</div>
|
||||
</div>
|
||||
return `
|
||||
<tr class="table-row ${isUrgent ? "due-tomorrow" : ""} ${isUserCompleted ? "user-completed" : ""}"
|
||||
data-subject="${homework.subject}"
|
||||
data-teacher="${homework.teacher}"
|
||||
data-deadline="${homework.deadline}"
|
||||
data-homework-id="${homework.id}">
|
||||
<td class="table-cell checkbox-cell">
|
||||
<input type="checkbox" class="homework-checkbox"
|
||||
data-homework-id="${homework.id}"
|
||||
${isUserCompleted ? "checked" : ""}
|
||||
title="${isUserCompleted ? 'Megcsinált házi - kattints a visszaállításhoz' : 'Kattints a megjelöléshez'}">
|
||||
</td>
|
||||
<td class="table-cell date-cell" data-label="${LanguageManager.t("homework.due_date")}:">${homework.deadline}</td>
|
||||
<td class="table-cell subject-cell" data-label="${LanguageManager.t("homework.subject")}:">${homework.subject}</td>
|
||||
<td class="table-cell description-cell" data-label="${LanguageManager.t("homework.description")}:">${homework.description}</td>
|
||||
<td class="table-cell teacher-cell" data-label="${LanguageManager.t("homework.teacher")}:">${homework.teacher}</td>
|
||||
<td class="table-cell status-cell" data-label="${LanguageManager.t("homework.status")}:">
|
||||
<span class="status-badge ${status}">${statusText}</span>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join('');
|
||||
})
|
||||
.join("");
|
||||
}
|
||||
|
||||
function formatDateHeader(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
|
||||
if (!dateStr) return "";
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
const parts = dateStr.split('.');
|
||||
|
||||
const parts = dateStr.split(".");
|
||||
if (parts.length < 2) return dateStr;
|
||||
|
||||
|
||||
const month = parseInt(parts[0].trim()) - 1;
|
||||
const day = parseInt(parts[1].trim());
|
||||
const currentYear = today.getFullYear();
|
||||
|
||||
|
||||
const date = new Date(currentYear, month, day);
|
||||
|
||||
|
||||
if (date.toDateString() === today.toDateString()) {
|
||||
return LanguageManager.t('common.today') + ' - ' + dateStr;
|
||||
return LanguageManager.t("common.today") + " - " + dateStr;
|
||||
} else if (date.toDateString() === tomorrow.toDateString()) {
|
||||
return LanguageManager.t('common.tomorrow') + ' - ' + dateStr;
|
||||
return LanguageManager.t("common.tomorrow") + " - " + dateStr;
|
||||
}
|
||||
|
||||
|
||||
const weekdays = [
|
||||
LanguageManager.t('common.sunday'),
|
||||
LanguageManager.t('common.monday'),
|
||||
LanguageManager.t('common.tuesday'),
|
||||
LanguageManager.t('common.wednesday'),
|
||||
LanguageManager.t('common.thursday'),
|
||||
LanguageManager.t('common.friday'),
|
||||
LanguageManager.t('common.saturday')
|
||||
LanguageManager.t("common.sunday"),
|
||||
LanguageManager.t("common.monday"),
|
||||
LanguageManager.t("common.tuesday"),
|
||||
LanguageManager.t("common.wednesday"),
|
||||
LanguageManager.t("common.thursday"),
|
||||
LanguageManager.t("common.friday"),
|
||||
LanguageManager.t("common.saturday"),
|
||||
];
|
||||
return `${weekdays[date.getDay()]} - ${dateStr}`;
|
||||
}
|
||||
|
||||
function formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
if (!dateStr) return "";
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
function setupFilters(homeworkItems, groupedHomework) {
|
||||
const subjectFilter = document.getElementById('subjectFilter');
|
||||
const teacherFilter = document.getElementById('teacherFilter');
|
||||
const deadlineFilter = document.getElementById('deadlineFilter');
|
||||
const applyFilterBtn = document.getElementById('applyFilterBtn');
|
||||
const resetFilterBtn = document.getElementById('resetFilterBtn');
|
||||
|
||||
|
||||
const subjectFilter = document.getElementById("subjectFilter");
|
||||
const teacherFilter = document.getElementById("teacherFilter");
|
||||
const deadlineFilter = document.getElementById("deadlineFilter");
|
||||
|
||||
const applyFilters = () => {
|
||||
const selectedSubject = subjectFilter.value;
|
||||
const selectedTeacher = teacherFilter.value;
|
||||
const selectedDeadline = deadlineFilter.value;
|
||||
|
||||
|
||||
const homeworkElements = document.querySelectorAll('.homework-item');
|
||||
const dateGroups = document.querySelectorAll('.homework-date-group');
|
||||
|
||||
|
||||
dateGroups.forEach(group => {
|
||||
group.style.display = 'none';
|
||||
});
|
||||
|
||||
|
||||
homeworkElements.forEach(item => {
|
||||
const subject = item.getAttribute('data-subject');
|
||||
const teacher = item.getAttribute('data-teacher');
|
||||
const dateGroup = item.closest('.homework-date-group');
|
||||
const dateStr = dateGroup.getAttribute('data-date');
|
||||
|
||||
let showItem = true;
|
||||
|
||||
|
||||
|
||||
const tableRows = document.querySelectorAll(".table-row");
|
||||
|
||||
tableRows.forEach((row) => {
|
||||
const subject = row.getAttribute("data-subject");
|
||||
const teacher = row.getAttribute("data-teacher");
|
||||
const deadline = row.getAttribute("data-deadline");
|
||||
|
||||
let showRow = true;
|
||||
|
||||
if (selectedSubject && subject !== selectedSubject) {
|
||||
showItem = false;
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (selectedTeacher && teacher !== selectedTeacher) {
|
||||
showItem = false;
|
||||
showRow = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (selectedDeadline) {
|
||||
const parts = dateStr.split('.');
|
||||
if (parts.length >= 3) {
|
||||
const year = parseInt(parts[0].trim());
|
||||
const month = parseInt(parts[1].trim()) - 1;
|
||||
const day = parseInt(parts[2].trim());
|
||||
const date = new Date(year, month, day);
|
||||
|
||||
const parts = deadline.split(" ")[0].split(".");
|
||||
if (parts.length >= 2) {
|
||||
const month = parseInt(parts[0].trim()) - 1;
|
||||
const day = parseInt(parts[1].trim());
|
||||
const currentYear = new Date().getFullYear();
|
||||
const date = new Date(currentYear, month, day);
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
const tomorrow = new Date(today);
|
||||
tomorrow.setDate(tomorrow.getDate() + 1);
|
||||
|
||||
|
||||
|
||||
const startOfWeek = new Date(today);
|
||||
const dayOfWeek = today.getDay() || 7;
|
||||
startOfWeek.setDate(today.getDate() - dayOfWeek + 1);
|
||||
|
||||
|
||||
const endOfWeek = new Date(startOfWeek);
|
||||
endOfWeek.setDate(startOfWeek.getDate() + 6);
|
||||
|
||||
|
||||
|
||||
const startOfNextWeek = new Date(endOfWeek);
|
||||
startOfNextWeek.setDate(endOfWeek.getDate() + 1);
|
||||
|
||||
|
||||
const endOfNextWeek = new Date(startOfNextWeek);
|
||||
endOfNextWeek.setDate(startOfNextWeek.getDate() + 6);
|
||||
|
||||
if (selectedDeadline === 'tomorrow' && date.toDateString() !== tomorrow.toDateString()) {
|
||||
showItem = false;
|
||||
} else if (selectedDeadline === 'thisWeek' && (date < startOfWeek || date > endOfWeek)) {
|
||||
showItem = false;
|
||||
} else if (selectedDeadline === 'nextWeek' && (date < startOfNextWeek || date > endOfNextWeek)) {
|
||||
showItem = false;
|
||||
|
||||
if (
|
||||
selectedDeadline === "tomorrow" &&
|
||||
date.toDateString() !== tomorrow.toDateString()
|
||||
) {
|
||||
showRow = false;
|
||||
} else if (
|
||||
selectedDeadline === "thisWeek" &&
|
||||
(date < startOfWeek || date > endOfWeek)
|
||||
) {
|
||||
showRow = false;
|
||||
} else if (
|
||||
selectedDeadline === "nextWeek" &&
|
||||
(date < startOfNextWeek || date > endOfNextWeek)
|
||||
) {
|
||||
showRow = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
item.style.display = showItem ? 'block' : 'none';
|
||||
|
||||
|
||||
if (showItem) {
|
||||
dateGroup.style.display = 'block';
|
||||
}
|
||||
|
||||
row.style.display = showRow ? "" : "none";
|
||||
});
|
||||
|
||||
|
||||
const visibleItems = document.querySelectorAll('.homework-item[style="display: block"]');
|
||||
const homeworkList = document.getElementById('homeworkList');
|
||||
|
||||
|
||||
let emptyState = homeworkList.querySelector('.empty-state');
|
||||
if (!emptyState) {
|
||||
emptyState = document.createElement('div');
|
||||
emptyState.className = 'empty-state';
|
||||
emptyState.innerHTML = `<p>${LanguageManager.t('homework.no_matching_homework')}</p>`;
|
||||
homeworkList.appendChild(emptyState);
|
||||
}
|
||||
|
||||
|
||||
if (visibleItems.length === 0) {
|
||||
emptyState.style.display = 'block';
|
||||
} else {
|
||||
emptyState.style.display = 'none';
|
||||
}
|
||||
|
||||
updateDateGroupsVisibility();
|
||||
updateStatistics();
|
||||
setupHomeworkCheckboxes();
|
||||
};
|
||||
|
||||
|
||||
const resetFilters = () => {
|
||||
subjectFilter.value = '';
|
||||
teacherFilter.value = '';
|
||||
deadlineFilter.value = '';
|
||||
|
||||
|
||||
document.querySelectorAll('.homework-item').forEach(item => {
|
||||
item.style.display = 'block';
|
||||
});
|
||||
|
||||
document.querySelectorAll('.homework-date-group').forEach(group => {
|
||||
group.style.display = 'block';
|
||||
});
|
||||
|
||||
|
||||
const homeworkList = document.getElementById('homeworkList');
|
||||
const existingEmptyState = homeworkList.querySelector('.empty-state');
|
||||
if (existingEmptyState) {
|
||||
homeworkList.removeChild(existingEmptyState);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
subjectFilter.addEventListener('change', applyFilters);
|
||||
teacherFilter.addEventListener('change', applyFilters);
|
||||
deadlineFilter.addEventListener('change', applyFilters);
|
||||
|
||||
subjectFilter.addEventListener("change", applyFilters);
|
||||
teacherFilter.addEventListener("change", applyFilters);
|
||||
deadlineFilter.addEventListener("change", applyFilters);
|
||||
}
|
||||
|
||||
function updateStatistics() {
|
||||
const visibleRows = document.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
|
||||
let totalCount = 0;
|
||||
let urgentCount = 0;
|
||||
let completedCount = 0;
|
||||
let pendingCount = 0;
|
||||
|
||||
if (window.location.href.includes('/Tanulo/TanuloHaziFeladat')) {
|
||||
transformHomeworkPage().catch(error => {
|
||||
console.error('Error transforming homework page:', error);
|
||||
visibleRows.forEach((row) => {
|
||||
totalCount++;
|
||||
|
||||
if (row.classList.contains("due-tomorrow")) {
|
||||
urgentCount++;
|
||||
}
|
||||
|
||||
const statusBadge = row.querySelector(".status-badge");
|
||||
if (statusBadge) {
|
||||
if (statusBadge.classList.contains("completed")) {
|
||||
completedCount++;
|
||||
} else if (statusBadge.classList.contains("pending")) {
|
||||
pendingCount++;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
document.getElementById("totalHomework").textContent = totalCount;
|
||||
document.getElementById("urgentHomework").textContent = urgentCount;
|
||||
document.getElementById("completedHomework").textContent = completedCount;
|
||||
document.getElementById("pendingHomework").textContent = pendingCount;
|
||||
}
|
||||
|
||||
function setupMobileGrouping() {
|
||||
function handleResize() {
|
||||
if (window.innerWidth <= 480) {
|
||||
createMobileGroups();
|
||||
} else {
|
||||
removeMobileGroups();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("resize", handleResize);
|
||||
handleResize();
|
||||
}
|
||||
|
||||
function createMobileGroups() {
|
||||
const tableBody = document.getElementById("homeworkTableBody");
|
||||
const rows = Array.from(tableBody.querySelectorAll(".table-row"));
|
||||
|
||||
if (rows.length === 0) return;
|
||||
|
||||
const groupedByDate = {};
|
||||
|
||||
rows.forEach((row) => {
|
||||
const deadline = row.getAttribute("data-deadline");
|
||||
const dateKey = deadline.split(" ")[0];
|
||||
|
||||
if (!groupedByDate[dateKey]) {
|
||||
groupedByDate[dateKey] = [];
|
||||
}
|
||||
groupedByDate[dateKey].push(row);
|
||||
});
|
||||
|
||||
tableBody.innerHTML = "";
|
||||
|
||||
Object.keys(groupedByDate)
|
||||
.sort()
|
||||
.forEach((date) => {
|
||||
const dateGroup = document.createElement("div");
|
||||
dateGroup.className = "date-group";
|
||||
dateGroup.setAttribute("data-date", date);
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "date-group-header";
|
||||
header.textContent = formatDateHeader(date);
|
||||
|
||||
const content = document.createElement("div");
|
||||
content.className = "date-group-content";
|
||||
|
||||
groupedByDate[date].forEach((row) => {
|
||||
content.appendChild(row);
|
||||
});
|
||||
|
||||
dateGroup.appendChild(header);
|
||||
dateGroup.appendChild(content);
|
||||
tableBody.appendChild(dateGroup);
|
||||
});
|
||||
|
||||
setupHomeworkCheckboxes();
|
||||
}
|
||||
|
||||
function removeMobileGroups() {
|
||||
const tableBody = document.getElementById("homeworkTableBody");
|
||||
const dateGroups = tableBody.querySelectorAll(".date-group");
|
||||
|
||||
if (dateGroups.length === 0) return;
|
||||
|
||||
const allRows = [];
|
||||
dateGroups.forEach((group) => {
|
||||
const rows = group.querySelectorAll(".table-row");
|
||||
rows.forEach((row) => allRows.push(row));
|
||||
});
|
||||
|
||||
tableBody.innerHTML = "";
|
||||
allRows.forEach((row) => tableBody.appendChild(row));
|
||||
|
||||
setupHomeworkCheckboxes();
|
||||
}
|
||||
|
||||
function updateDateGroupsVisibility() {
|
||||
const dateGroups = document.querySelectorAll(".date-group");
|
||||
|
||||
dateGroups.forEach((group) => {
|
||||
const visibleRows = group.querySelectorAll(
|
||||
'.table-row:not([style*="display: none"])',
|
||||
);
|
||||
group.style.display = visibleRows.length > 0 ? "block" : "none";
|
||||
});
|
||||
}
|
||||
|
||||
async function getHomeworkCompletionStatus(homeworkId) {
|
||||
const completedHomework = await storageManager.get('completedHomework');
|
||||
if (!completedHomework) return false;
|
||||
|
||||
try {
|
||||
const completedList = JSON.parse(completedHomework);
|
||||
return completedList.includes(homeworkId.toString());
|
||||
} catch (error) {
|
||||
console.error('Error parsing completed homework storage:', error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function setHomeworkCompletionStatus(homeworkId, isCompleted) {
|
||||
let completedHomework = await storageManager.get('completedHomework');
|
||||
let completedList = [];
|
||||
|
||||
if (completedHomework) {
|
||||
try {
|
||||
completedList = JSON.parse(completedHomework);
|
||||
} catch (error) {
|
||||
console.error('Error parsing completed homework storage:', error);
|
||||
completedList = [];
|
||||
}
|
||||
}
|
||||
|
||||
const homeworkIdStr = homeworkId.toString();
|
||||
|
||||
if (isCompleted) {
|
||||
if (!completedList.includes(homeworkIdStr)) {
|
||||
completedList.push(homeworkIdStr);
|
||||
}
|
||||
} else {
|
||||
completedList = completedList.filter(id => id !== homeworkIdStr);
|
||||
}
|
||||
|
||||
await storageManager.set('completedHomework', JSON.stringify(completedList));
|
||||
}
|
||||
|
||||
function setupHomeworkCheckboxes() {
|
||||
const checkboxes = document.querySelectorAll('.homework-checkbox');
|
||||
|
||||
checkboxes.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', function() {
|
||||
const homeworkId = this.getAttribute('data-homework-id');
|
||||
const isChecked = this.checked;
|
||||
const row = this.closest('.table-row');
|
||||
setHomeworkCompletionStatus(homeworkId, isChecked);
|
||||
|
||||
if (isChecked) {
|
||||
row.classList.add('user-completed');
|
||||
this.title = 'Megcsinált házi - kattints a visszaállításhoz';
|
||||
} else {
|
||||
row.classList.remove('user-completed');
|
||||
this.title = 'Kattints a megjelöléshez';
|
||||
}
|
||||
|
||||
const statusBadge = row.querySelector('.status-badge');
|
||||
if (statusBadge) {
|
||||
if (isChecked) {
|
||||
statusBadge.className = 'status-badge completed';
|
||||
statusBadge.textContent = LanguageManager.t('homework.completed');
|
||||
} else {
|
||||
const isUrgent = row.classList.contains('due-tomorrow');
|
||||
if (isUrgent) {
|
||||
statusBadge.className = 'status-badge urgent';
|
||||
statusBadge.textContent = LanguageManager.t('homework.urgent');
|
||||
} else {
|
||||
statusBadge.className = 'status-badge pending';
|
||||
statusBadge.textContent = LanguageManager.t('homework.pending');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateStatistics();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (window.location.href.includes("/Tanulo/TanuloHaziFeladat")) {
|
||||
transformHomeworkPage().then(() => {
|
||||
setupHomeworkCheckboxes();
|
||||
}).catch((error) => {
|
||||
console.error("Error transforming homework page:", error);
|
||||
});
|
||||
}
|
||||
|
||||
70
i18n/en.json
@@ -76,6 +76,7 @@
|
||||
"average": "Average",
|
||||
"chart_title": "Grades",
|
||||
"semester_evaluations": "Semester evaluations",
|
||||
"year_end_evaluations": "End of year tickets",
|
||||
"semester_average": "Semester average",
|
||||
"no_grades": "No grades",
|
||||
"september": "September",
|
||||
@@ -114,7 +115,37 @@
|
||||
"wednesday": "Wednesday",
|
||||
"thursday": "Thursday",
|
||||
"friday": "Friday",
|
||||
"found_current_week": "Found current week"
|
||||
"found_current_week": "Found current week",
|
||||
"open_homework": "Open homework",
|
||||
"all_day": "All day",
|
||||
"special_day": "Special day",
|
||||
"unknown_subject": "Unknown subject",
|
||||
"lesson_topic": "Lesson topic",
|
||||
"homework_completed": "Completed homework",
|
||||
"homework_mark_completed": "Mark as completed",
|
||||
"homework_mark_uncompleted": "Completed - click to undo",
|
||||
"custom_homework": "Custom homework",
|
||||
"custom_test": "Custom test",
|
||||
"add_homework_test": "Add homework or test",
|
||||
"close": "Close",
|
||||
"add": "Add",
|
||||
"homework_details_loading": "Loading homework details...",
|
||||
"homework_details_error": "Error occurred while loading homework details.",
|
||||
"test_details_loading": "Loading details...",
|
||||
"test_details_error": "Failed to load test details.",
|
||||
"test_details_error_general": "Error occurred while loading test details.",
|
||||
"custom_homework_title": "Custom homework:",
|
||||
"custom_tests_title": "Custom tests:",
|
||||
"delete_homework_confirm": "Are you sure you want to delete this homework?",
|
||||
"delete_test_confirm": "Are you sure you want to delete this test?",
|
||||
"task_label": "Task:",
|
||||
"deadline_label": "Deadline:",
|
||||
"name_label": "Name:",
|
||||
"type_label": "Type:",
|
||||
"announce_date_label": "Announcement date:",
|
||||
"no_name": "No name",
|
||||
"no_type": "No type specified",
|
||||
"no_date": "No date"
|
||||
},
|
||||
"homework": {
|
||||
"title": "Homework",
|
||||
@@ -132,7 +163,15 @@
|
||||
"no_filtered_homework": "No homework matching the filter criteria.",
|
||||
"teacher": "Teacher",
|
||||
"no_matching_homework": "No homework matching the filter criteria.",
|
||||
"items": "items"
|
||||
"items": "items",
|
||||
"status": "Status",
|
||||
"total_homework": "Total homework",
|
||||
"urgent_homework": "Urgent homework",
|
||||
"completed_homework": "Completed homework",
|
||||
"pending_homework": "Pending homework",
|
||||
"completed": "Completed",
|
||||
"urgent": "Urgent",
|
||||
"pending": "Pending"
|
||||
},
|
||||
"absences": {
|
||||
"title": "Absences",
|
||||
@@ -154,7 +193,10 @@
|
||||
"current_month": "Current month",
|
||||
"last_month": "Last month",
|
||||
"current_semester": "Current semester",
|
||||
"last_30_days": "Last 30 days"
|
||||
"last_30_days": "Last 30 days",
|
||||
"total_absences": "Total absences",
|
||||
"topic": "Topic",
|
||||
"status": "Status"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profile",
|
||||
@@ -337,7 +379,27 @@
|
||||
"error_message": "An error occurred during password reset",
|
||||
"success_message": "Password reset link sent to your email address",
|
||||
"invalid_data": "Invalid data",
|
||||
"invalid_email": "Invalid email address format",
|
||||
"invalid_email": "Invalid email format",
|
||||
"recaptcha_required": "Please complete the reCAPTCHA"
|
||||
},
|
||||
"modal": {
|
||||
"add_item_title": "Add new item",
|
||||
"type_label": "Type:",
|
||||
"homework_option": "Homework",
|
||||
"test_option": "Test",
|
||||
"description_label": "Description:",
|
||||
"cancel": "Cancel",
|
||||
"save": "Save"
|
||||
},
|
||||
"grades": {
|
||||
"semester_evaluation": "Semester evaluation"
|
||||
},
|
||||
"search": {
|
||||
"choose_school": "Choose school",
|
||||
"privacy_policy": "Privacy policy"
|
||||
},
|
||||
"icons": {
|
||||
"cancel": "cancel",
|
||||
"pending": "pending"
|
||||
}
|
||||
}
|
||||
82
i18n/hu.json
@@ -75,7 +75,9 @@
|
||||
"teacher": "Tanár",
|
||||
"average": "Átlag",
|
||||
"chart_title": "Jegyek",
|
||||
"semester_evaluation": "Félévi értékelés",
|
||||
"semester_evaluations": "Félévi értékelések",
|
||||
"year_end_evaluations": "Év végi értékelések",
|
||||
"semester_average": "Félévi átlag",
|
||||
"no_grades": "Nincsenek jegyek",
|
||||
"september": "Szeptember",
|
||||
@@ -114,25 +116,63 @@
|
||||
"wednesday": "Szerda",
|
||||
"thursday": "Csütörtök",
|
||||
"friday": "Péntek",
|
||||
"found_current_week": "Megtalált jelenlegi hét"
|
||||
"found_current_week": "Megtalált jelenlegi hét",
|
||||
"open_homework": "Ugrás a házi feladatokhoz",
|
||||
"all_day": "Egész nap",
|
||||
"special_day": "Különleges nap",
|
||||
"unknown_subject": "Ismeretlen tantárgy",
|
||||
"lesson_topic": "Óra témája",
|
||||
"homework_completed": "Megoldott házi feladat",
|
||||
"homework_mark_completed": "Megoldottként jelöl",
|
||||
"homework_mark_uncompleted": "Megoldva - kattints a visszavonáshoz",
|
||||
"custom_homework": "Saját házi feladat",
|
||||
"custom_test": "Saját számonkérés",
|
||||
"add_homework_test": "Házi feladat vagy számonkérés hozzáadása",
|
||||
"close": "Bezárás",
|
||||
"add": "Hozzáadás",
|
||||
"homework_details_loading": "Házi feladat részletek betöltése...",
|
||||
"homework_details_error": "Hiba történt a házi feladat részletek betöltésekor.",
|
||||
"test_details_loading": "Részletek betöltése...",
|
||||
"test_details_error": "Nem sikerült betölteni a számonkérés részleteit.",
|
||||
"test_details_error_general": "Hiba történt a számonkérés részletek betöltése során.",
|
||||
"custom_homework_title": "Saját házi feladatok:",
|
||||
"custom_tests_title": "Saját számonkérések:",
|
||||
"delete_homework_confirm": "Biztosan törölni szeretnéd ezt a házi feladatot?",
|
||||
"delete_test_confirm": "Biztosan törölni szeretnéd ezt a számonkérést?",
|
||||
"task_label": "Feladat:",
|
||||
"deadline_label": "Határidő:",
|
||||
"name_label": "Megnevezés:",
|
||||
"type_label": "Típus:",
|
||||
"announce_date_label": "Bejelentés dátuma:",
|
||||
"no_name": "Nincs megnevezés",
|
||||
"no_type": "Nincs típus megadva",
|
||||
"no_date": "Nincs dátum"
|
||||
},
|
||||
"homework": {
|
||||
"title": "Házi feladatok",
|
||||
"due_date": "Határidő",
|
||||
"subject": "Tantárgy",
|
||||
"description": "Leírás",
|
||||
"filter_title": "Szűrés",
|
||||
"all_subjects": "Összes tantárgy",
|
||||
"all_teachers": "Összes tanár",
|
||||
"all_deadlines": "Összes határidő",
|
||||
"filter_title": "Szűrő",
|
||||
"all_subjects": "Minden tantárgy",
|
||||
"all_teachers": "Minden tanár",
|
||||
"all_deadlines": "Minden határidő",
|
||||
"tomorrow_deadline": "Holnapi határidő",
|
||||
"this_week": "Ezen a héten",
|
||||
"next_week": "Jövő héten",
|
||||
"next_week": "Következő héten",
|
||||
"no_homework": "Nincs megjeleníthető házi feladat.",
|
||||
"no_filtered_homework": "Nincs a szűrési feltételeknek megfelelő házi feladat.",
|
||||
"teacher": "Tanár",
|
||||
"no_matching_homework": "Nincs a szűrési feltételeknek megfelelő házi feladat.",
|
||||
"items": "feladat"
|
||||
"items": "elem",
|
||||
"status": "Állapot",
|
||||
"total_homework": "Összes feladat",
|
||||
"urgent_homework": "Sürgős feladat",
|
||||
"completed_homework": "Befejezett feladat",
|
||||
"pending_homework": "Függőben lévő feladat",
|
||||
"completed": "Befejezve",
|
||||
"urgent": "Sürgős",
|
||||
"pending": "Függőben"
|
||||
},
|
||||
"absences": {
|
||||
"title": "Hiányzások",
|
||||
@@ -154,7 +194,10 @@
|
||||
"current_month": "Aktuális hónap",
|
||||
"last_month": "Előző hónap",
|
||||
"current_semester": "Aktuális félév",
|
||||
"last_30_days": "Utolsó 30 nap"
|
||||
"last_30_days": "Utolsó 30 nap",
|
||||
"total_absences": "Összes hiányzás",
|
||||
"topic": "Téma",
|
||||
"status": "Állapot"
|
||||
},
|
||||
"profile": {
|
||||
"title": "Profil",
|
||||
@@ -294,10 +337,6 @@
|
||||
"november": "november",
|
||||
"december": "december"
|
||||
},
|
||||
"search": {
|
||||
"title": "Válassz iskolát",
|
||||
"select_institution": "Kérjük, válasszon egy intézményt a folytatáshoz!"
|
||||
},
|
||||
"roleselect": {
|
||||
"student_book": "Ellenőrzőkönyv",
|
||||
"student_description": "Jegyek, hiányzások, órarended és egyéb információk megtekintése.",
|
||||
@@ -339,5 +378,24 @@
|
||||
"invalid_data": "Hibás adatok",
|
||||
"invalid_email": "Érvénytelen e-mail cím formátum",
|
||||
"recaptcha_required": "Kérjük, töltse ki a reCAPTCHA-t"
|
||||
},
|
||||
"modal": {
|
||||
"add_item_title": "Új elem hozzáadása",
|
||||
"type_label": "Típus:",
|
||||
"homework_option": "Házi feladat",
|
||||
"test_option": "Számonkérés",
|
||||
"description_label": "Leírás:",
|
||||
"cancel": "Mégse",
|
||||
"save": "Mentés"
|
||||
},
|
||||
"search": {
|
||||
"choose_school": "Válassz iskolát",
|
||||
"privacy_policy": "Adatkezelési tájékoztató",
|
||||
"title": "Válassz iskolát",
|
||||
"select_institution": "Kérjük, válasszon egy intézményt a folytatáshoz!"
|
||||
},
|
||||
"icons": {
|
||||
"cancel": "cancel",
|
||||
"pending": "pending"
|
||||
}
|
||||
}
|
||||
1
icons/ArrowsExpandFull.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19h4m0 0v-4m0 4l-4-4M9 5H5m0 0v4m0-4l4 4m6-4h4m0 0v4m0-4l-4 4M9 19H5m0 0v-4m0 4l4-4"/></svg>
|
||||
|
After Width: | Height: | Size: 283 B |
1
icons/BadgeCheck.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.054 2.344a3 3 0 0 1 3.892 0l1.271 1.084a1 1 0 0 0 .57.236l1.665.133a3 3 0 0 1 2.751 2.751l.133 1.666a1 1 0 0 0 .236.569l1.084 1.271a3 3 0 0 1 0 3.892l-1.084 1.271a1 1 0 0 0-.236.57l-.133 1.665a3 3 0 0 1-2.751 2.751l-1.666.133a1 1 0 0 0-.569.236l-1.271 1.084a3 3 0 0 1-3.892 0l-1.271-1.084a1 1 0 0 0-.57-.236l-1.665-.133a3 3 0 0 1-2.751-2.751l-.133-1.666a1 1 0 0 0-.236-.569l-1.084-1.271a3 3 0 0 1 0-3.892l1.084-1.271a1 1 0 0 0 .236-.57l.133-1.665a3 3 0 0 1 2.751-2.751l1.666-.133a1 1 0 0 0 .569-.236l1.271-1.084zm5.653 8.363a1 1 0 0 0-1.414-1.414L11 12.586l-1.293-1.293a1 1 0 0 0-1.414 1.414l2 2a1 1 0 0 0 1.414 0l4-4z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 799 B |
1
icons/Calendar.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill="#A7DC22" d="M4 7v2h16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2"/><path stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 5h2a2 2 0 0 1 2 2v2H4V7a2 2 0 0 1 2-2h2m8 0V3m0 2H8m0-2v2M4 9.5V19a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9.5"/></g></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
1
icons/ChevronLeftCircle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#A7DC22" fill-rule="evenodd" d="M12 21a9 9 0 1 0 0-18a9 9 0 0 0 0 18m1.707-11.293a1 1 0 0 0-1.414-1.414l-3 3a1 1 0 0 0 0 1.414l3 3a1 1 0 0 0 1.414-1.414L11.414 12z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
icons/ChevronRightCircle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="#A7DC22" fill-rule="evenodd" d="M12 21a9 9 0 1 0 0-18a9 9 0 0 0 0 18M10.293 9.707a1 1 0 1 1 1.414-1.414l3 3a1 1 0 0 1 0 1.414l-3 3a1 1 0 0 1-1.414-1.414L12.586 12z" clip-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 289 B |
1
icons/CloseCircle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12zm8.207-3.207a1 1 0 0 0-1.414 1.414L10.586 12l-1.793 1.793a1 1 0 1 0 1.414 1.414L12 13.414l1.793 1.793a1 1 0 0 0 1.414-1.414L13.414 12l1.793-1.793a1 1 0 0 0-1.414-1.414L12 10.586l-1.793-1.793z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 440 B |
1
icons/Subject.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.514 3.126a1 1 0 0 1 .972 0l9 5A1 1 0 0 1 22 9v7a1 1 0 1 1-2 0v-5.3l-1 .555v.004l-6.067 3.016a2 2 0 0 1-1.848-.035L2.357 9.479a1 1 0 0 0-.284-.103a1 1 0 0 1 .441-1.25l9-5zM5 13.199V17a1 1 0 0 0 .553.894l6 3a1 1 0 0 0 .894 0l6-3A1 1 0 0 0 19 17v-3.256l-6.083 2.844a2 2 0 0 1-1.805-.056L5 13.2z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 472 B |
1
icons/assigment.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path stroke="#FFA046" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 8H9m2 4H9"/><path fill="#FFA046" d="M3 16h8c0 1.333.8 4 4 4a3 3 0 0 0 3-3V4h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1v7a3 3 0 0 1-3 3H5a2 2 0 0 1-2-2z"/><path stroke="#FFA046" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 20c-3.2 0-4-2.667-4-4H3v2a2 2 0 0 0 2 2zm0 0a3 3 0 0 0 3-3v-7m0-6H7a2 2 0 0 0-2 2v9.5M18 4h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1m0-6v6"/></g></svg>
|
||||
|
After Width: | Height: | Size: 578 B |
1
icons/delete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill="#A7DC22" d="M9 7h9v11a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2V7z"/><path stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7h-2M4 7h2m0 0h12M6 7v11a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7m-9-.5A2.5 2.5 0 0 1 11.5 4h1A2.5 2.5 0 0 1 15 6.5v0"/></g></svg>
|
||||
|
After Width: | Height: | Size: 384 B |
1
icons/homework.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M15.586 3a2 2 0 0 1 2.828 0L21 5.586a2 2 0 0 1 0 2.828L19.414 10L14 4.586L15.586 3zm-3 3l-9 9A2 2 0 0 0 3 16.414V19a2 2 0 0 0 2 2h2.586A2 2 0 0 0 9 20.414l9-9L12.586 6z" fill="#A7DC22"/></g></svg>
|
||||
|
After Width: | Height: | Size: 345 B |
1
icons/pipa.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><g fill="#A7DC22"><path d="M19.707 6.293a1 1 0 0 1 0 1.414l-10 10a1 1 0 0 1-1.414 0l-4-4a1 1 0 1 1 1.414-1.414L9 15.586l9.293-9.293a1 1 0 0 1 1.414 0z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 248 B |
1
icons/plus.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 24 24"><path fill="none" stroke="#A7DC22" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 12h7m7 0h-7m0 0V5m0 7v7"/></svg>
|
||||
|
After Width: | Height: | Size: 222 B |
507
login/login.css
@@ -1,360 +1,313 @@
|
||||
:root {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="light-green"] {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="dark-blue"] {
|
||||
--icon-invert: 0.9;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="dark-green"] {
|
||||
--icon-invert: 0.9;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
margin-bottom:16px;
|
||||
border-radius:24px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0;
|
||||
background: var(--card-card) !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0) !important;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:16px 0;
|
||||
background:var(--card-card) !important;
|
||||
border-bottom:1px solid rgba(0,0,0,0) !important;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
.school-name {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 14px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-15) !important;
|
||||
border: 0px solid var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 14px;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
align-self:stretch;
|
||||
border-radius:12px;
|
||||
background:var(--accent-15) !important;
|
||||
border:0px solid var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
outline:none;
|
||||
border-color:var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
color:var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.password-group {
|
||||
position: relative;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.show-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position:absolute;
|
||||
right:12px;
|
||||
top:50%;
|
||||
transform:translateY(-50%);
|
||||
background:none;
|
||||
border:none;
|
||||
padding:4px;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.icon-eye {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s ease;
|
||||
filter: invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
width:20px;
|
||||
height:20px;
|
||||
opacity:0.6;
|
||||
transition:opacity 0.2s ease;
|
||||
filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
}
|
||||
|
||||
.show-password:hover .icon-eye {
|
||||
opacity: 1;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 24px;
|
||||
margin-top:24px;
|
||||
}
|
||||
|
||||
.help-links {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-top:16px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease;
|
||||
color:var(--text-primary);
|
||||
font-size:14px;
|
||||
font-weight:500;
|
||||
text-decoration:none;
|
||||
transition:color 0.2s ease;
|
||||
}
|
||||
|
||||
.help-link:hover {
|
||||
color: var(--text-teritary);
|
||||
color:var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
font-family: "Montserrat", serif;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
position: relative;
|
||||
width:100%;
|
||||
padding:12px;
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
border:none;
|
||||
border-radius:12px;
|
||||
font-size:16px;
|
||||
font-weight:600;
|
||||
font-family:"Montserrat",serif;
|
||||
cursor:pointer;
|
||||
transition:background 0.2s ease;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.btn-login:hover {
|
||||
background: var(--text-teritary);
|
||||
background:var(--text-teritary);
|
||||
}
|
||||
|
||||
.btn-login:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
opacity:0.7;
|
||||
cursor:not-allowed;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 18px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
letter-spacing: -0.3px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:18px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
letter-spacing:-0.3px;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
display: flex;
|
||||
padding: 20px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
align-self: stretch;
|
||||
border-radius: 24px;
|
||||
background: var(--card-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
padding:20px;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:12px;
|
||||
align-self:stretch;
|
||||
border-radius:24px;
|
||||
background:var(--card-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.system-message h4 {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.system-message p {
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
text-decoration: none;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--text-teritary);
|
||||
color:var(--text-teritary);
|
||||
}
|
||||
|
||||
|
||||
.form-control.error {
|
||||
border-color: var(--error-accent) !important;
|
||||
background: var(--error-card) !important;
|
||||
border-color:var(--error-accent) !important;
|
||||
background:var(--error-card) !important;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
color: var(--error-text);
|
||||
font-size: 14px;
|
||||
margin-top: 4px;
|
||||
display: none;
|
||||
color:var(--error-text);
|
||||
font-size:14px;
|
||||
margin-top:4px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
animation: fadeIn 0.2s ease;
|
||||
display:block;
|
||||
animation:fadeIn 0.2s ease;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; transform: translateY(-4px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
from {
|
||||
opacity:0;
|
||||
transform:translateY(-4px);
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to { transform: translate(-50%, -50%) rotate(360deg); }
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
}@keyframes spin {
|
||||
to {
|
||||
transform:translate(-50%,-50%) rotate(360deg);
|
||||
}
|
||||
}@media (max-width:480px) {
|
||||
.login-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.school-name {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
height: 44px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
padding: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.help-link {
|
||||
font-size: 12px;
|
||||
}
|
||||
padding:16px;
|
||||
}
|
||||
.login-card {
|
||||
padding:20px;
|
||||
}
|
||||
.card-header {
|
||||
margin-bottom:20px;
|
||||
padding-bottom:16px;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:20px;
|
||||
}
|
||||
.school-name {
|
||||
font-size:16px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:12px;
|
||||
}
|
||||
.form-control {
|
||||
height:44px;
|
||||
font-size:14px;
|
||||
}
|
||||
.btn-login {
|
||||
padding:10px;
|
||||
font-size:14px;
|
||||
}
|
||||
.help-link {
|
||||
font-size:12px;
|
||||
}
|
||||
}
|
||||
190
login/login.js
@@ -1,50 +1,59 @@
|
||||
async function transformLoginPage() {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) => {
|
||||
window.addEventListener("load", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
const existingForm = document.querySelector('form');
|
||||
|
||||
const existingForm = document.querySelector("form");
|
||||
const formData = {
|
||||
action: existingForm?.getAttribute('action') || '',
|
||||
returnUrl: document.querySelector('#ReturnUrl')?.value || '',
|
||||
instituteCode: document.querySelector('#instituteCode')?.value || '',
|
||||
requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '',
|
||||
userName: document.querySelector('#UserName')?.value || '',
|
||||
password: document.querySelector('#Password')?.value || ''
|
||||
action: existingForm?.getAttribute("action") || "",
|
||||
returnUrl: document.querySelector("#ReturnUrl")?.value || "",
|
||||
instituteCode: document.querySelector("#instituteCode")?.value || "",
|
||||
requestToken:
|
||||
document.querySelector('input[name="__RequestVerificationToken"]')
|
||||
?.value || "",
|
||||
userName: document.querySelector("#UserName")?.value || "",
|
||||
password: document.querySelector("#Password")?.value || "",
|
||||
};
|
||||
|
||||
const titleElement = document.querySelector('.page-title');
|
||||
|
||||
const titleElement = document.querySelector(".page-title");
|
||||
const schoolInfo = {
|
||||
name: titleElement?.querySelector('b')?.textContent?.trim() || '',
|
||||
kretaId: '',
|
||||
omCode: ''
|
||||
name: titleElement?.querySelector("b")?.textContent?.trim() || "",
|
||||
kretaId: "",
|
||||
omCode: "",
|
||||
};
|
||||
|
||||
const spanElement = titleElement?.querySelector('span');
|
||||
|
||||
const spanElement = titleElement?.querySelector("span");
|
||||
if (spanElement) {
|
||||
const lines = spanElement.textContent?.split('\n').map(line => line.trim()) || [];
|
||||
schoolInfo.kretaId = lines[0] || '';
|
||||
schoolInfo.omCode = (lines[1] || '').replace(`${LanguageManager.t('login.kreta_id')}: `, '');
|
||||
const lines =
|
||||
spanElement.textContent?.split("\n").map((line) => line.trim()) || [];
|
||||
schoolInfo.kretaId = lines[0] || "";
|
||||
schoolInfo.omCode = (lines[1] || "").replace(
|
||||
`${LanguageManager.t("login.kreta_id")}: `,
|
||||
"",
|
||||
);
|
||||
}
|
||||
|
||||
const rawSystemMessage = document.querySelector('.alert-primary')?.textContent?.trim() || '';
|
||||
const systemMessage = rawSystemMessage.replace('Rendszerértesítés', '').trim();
|
||||
|
||||
|
||||
const rawSystemMessage =
|
||||
document.querySelector(".alert-primary")?.textContent?.trim() || "";
|
||||
const systemMessage = rawSystemMessage
|
||||
.replace("Rendszerértesítés", "")
|
||||
.trim();
|
||||
|
||||
const newHTML = `
|
||||
<div class="login-container">
|
||||
<div class="login-card">
|
||||
<div class="card-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="school-name">${schoolInfo.name}</h1>
|
||||
<div class="school-details">
|
||||
${schoolInfo.kretaId ? `<div>${schoolInfo.kretaId}</div>` : ''}
|
||||
${schoolInfo.omCode ? `<div>${LanguageManager.t('login.kreta_id')}: ${schoolInfo.omCode}</div>` : ''}
|
||||
${schoolInfo.kretaId ? `<div>${schoolInfo.kretaId}</div>` : ""}
|
||||
${schoolInfo.omCode ? `<div>${LanguageManager.t("login.kreta_id")}: ${schoolInfo.omCode}</div>` : ""}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -57,133 +66,136 @@ async function transformLoginPage() {
|
||||
|
||||
<div class="form-group">
|
||||
<input class="form-control" type="text" id="UserName" name="UserName"
|
||||
placeholder="${LanguageManager.t('login.username_placeholder')}" maxlength="256" autocomplete="username" required value="${formData.userName}">
|
||||
<div class="error-message">${LanguageManager.t('login.username_required')}</div>
|
||||
placeholder="${LanguageManager.t("login.username_placeholder")}" maxlength="256" autocomplete="username" required value="${formData.userName}">
|
||||
<div class="error-message">${LanguageManager.t("login.username_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group password-group">
|
||||
<input class="form-control" type="password" id="Password" name="Password"
|
||||
placeholder="${LanguageManager.t('login.password_placeholder')}" maxlength="256" autocomplete="current-password" required value="${formData.password}">
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t('login.show_password')}">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-off.svg')}" alt="Show password" class="icon-eye">
|
||||
placeholder="${LanguageManager.t("login.password_placeholder")}" maxlength="256" autocomplete="current-password" required value="${formData.password}">
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t("login.show_password")}">
|
||||
<img src="${chrome.runtime.getURL("icons/eye-off.svg")}" alt="Show password" class="icon-eye">
|
||||
</button>
|
||||
<div class="error-message">${LanguageManager.t('login.password_required')}</div>
|
||||
<div class="error-message">${LanguageManager.t("login.password_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn-login">
|
||||
<span class="spinner"></span>
|
||||
<span class="btn-text">${LanguageManager.t('login.login_button')}</span>
|
||||
<span class="btn-text">${LanguageManager.t("login.login_button")}</span>
|
||||
</button>
|
||||
<div class="help-links">
|
||||
<a href="https://${schoolInfo.omCode ? `${schoolInfo.omCode}` : ''}.e-kreta.hu/Adminisztracio/ElfelejtettJelszo" class="help-link">${LanguageManager.t('login.forgot_password')}</a>
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=2425086" target="_blank" class="help-link">${LanguageManager.t('login.help_link')}</a>
|
||||
<a href="https://${schoolInfo.omCode ? `${schoolInfo.omCode}` : ""}.e-kreta.hu/Adminisztracio/ElfelejtettJelszo" class="help-link">${LanguageManager.t("login.forgot_password")}</a>
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=2425086" target="_blank" class="help-link">${LanguageManager.t("login.help_link")}</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
${systemMessage ? `
|
||||
${
|
||||
systemMessage
|
||||
? `
|
||||
<div class="system-message">
|
||||
<h4>${LanguageManager.t('login.system_message')}</h4>
|
||||
<h4>${LanguageManager.t("login.system_message")}</h4>
|
||||
<p>${systemMessage}</p>
|
||||
</div>
|
||||
` : ''}
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
<footer class="login-footer">
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">${LanguageManager.t('login.privacy_policy')}</a>
|
||||
target="_blank" class="privacy-link">${LanguageManager.t("login.privacy_policy")}</a>
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
setupEventListeners();
|
||||
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
setupEventListeners();
|
||||
} catch (error) {
|
||||
console.error('Error transforming page:', error);
|
||||
console.error("Error transforming page:", error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
const loginForm = document.getElementById('loginForm');
|
||||
const passwordInput = document.getElementById('Password');
|
||||
const togglePasswordBtn = document.querySelector('.show-password');
|
||||
const formInputs = document.querySelectorAll('.form-control');
|
||||
|
||||
if (togglePasswordBtn && passwordInput) {
|
||||
togglePasswordBtn.addEventListener('click', () => {
|
||||
const isPassword = passwordInput.type === 'password';
|
||||
passwordInput.type = isPassword ? 'text' : 'password';
|
||||
const icon = togglePasswordBtn.querySelector('.icon-eye');
|
||||
icon.src = chrome.runtime.getURL(`icons/${isPassword ? 'eye-on' : 'eye-off'}.svg`);
|
||||
});
|
||||
}
|
||||
const loginForm = document.getElementById("loginForm");
|
||||
const passwordInput = document.getElementById("Password");
|
||||
const togglePasswordBtn = document.querySelector(".show-password");
|
||||
const formInputs = document.querySelectorAll(".form-control");
|
||||
|
||||
|
||||
formInputs.forEach(input => {
|
||||
|
||||
input.addEventListener('input', () => {
|
||||
if (togglePasswordBtn && passwordInput) {
|
||||
togglePasswordBtn.addEventListener("click", () => {
|
||||
const isPassword = passwordInput.type === "password";
|
||||
passwordInput.type = isPassword ? "text" : "password";
|
||||
const icon = togglePasswordBtn.querySelector(".icon-eye");
|
||||
icon.src = chrome.runtime.getURL(
|
||||
`icons/${isPassword ? "eye-on" : "eye-off"}.svg`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
formInputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
if (loginForm) {
|
||||
loginForm.addEventListener('submit', handleSubmit);
|
||||
loginForm.addEventListener("submit", handleSubmit);
|
||||
}
|
||||
}
|
||||
|
||||
function validateInput(input, showError = false) {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling;
|
||||
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
|
||||
|
||||
inputs.forEach(input => {
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
const submitButton = form.querySelector('.btn-login');
|
||||
const spinner = submitButton.querySelector('.spinner');
|
||||
const buttonText = submitButton.querySelector('.btn-text');
|
||||
|
||||
const submitButton = form.querySelector(".btn-login");
|
||||
const spinner = submitButton.querySelector(".spinner");
|
||||
const buttonText = submitButton.querySelector(".btn-text");
|
||||
|
||||
submitButton.disabled = true;
|
||||
spinner.style.display = 'inline-block';
|
||||
buttonText.style.opacity = '0';
|
||||
spinner.style.display = "inline-block";
|
||||
buttonText.style.opacity = "0";
|
||||
|
||||
|
||||
form.submit();
|
||||
}
|
||||
|
||||
|
||||
if (window.location.href.includes('idp.e-kreta.hu/Account/Login')) {
|
||||
transformLoginPage().catch(error => {
|
||||
console.error('Error:', error);
|
||||
if (window.location.href.includes("idp.e-kreta.hu/Account/Login")) {
|
||||
transformLoginPage().catch((error) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,301 +1,261 @@
|
||||
:root {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
:root[data-theme="light-green"] {
|
||||
--icon-invert: 0.1;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 0.1;
|
||||
--icon-invert:0.1;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:0.1;
|
||||
}
|
||||
|
||||
:root[data-theme="dark-blue"] {
|
||||
--icon-invert: 0.9;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
:root[data-theme="dark-green"] {
|
||||
--icon-invert: 0.9;
|
||||
--icon-sepia: 0.1;
|
||||
--icon-saturate: 0.1;
|
||||
--icon-hue-rotate: 0deg;
|
||||
--icon-brightness: 1;
|
||||
--icon-invert:0.9;
|
||||
--icon-sepia:0.1;
|
||||
--icon-saturate:0.1;
|
||||
--icon-hue-rotate:0deg;
|
||||
--icon-brightness:1;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
margin-bottom: 16px;
|
||||
border-radius: 24px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
margin-bottom:16px;
|
||||
border-radius:24px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 16px 0;
|
||||
background: var(--card-card) !important;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0) !important;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:16px 0;
|
||||
background:var(--card-card) !important;
|
||||
border-bottom:1px solid rgba(0,0,0,0) !important;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 12px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:12px;
|
||||
}
|
||||
|
||||
.twofactor-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 130%;
|
||||
margin-bottom: 16px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:24px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:130%;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.twofactor-form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 14px;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
align-self: stretch;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-15) !important;
|
||||
border: 0px solid var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 14px;
|
||||
align-items:center;
|
||||
gap:10px;
|
||||
align-self:stretch;
|
||||
border-radius:12px;
|
||||
background:var(--accent-15) !important;
|
||||
border:0px solid var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent) !important;
|
||||
outline:none;
|
||||
border-color:var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-secondary) !important;
|
||||
color:var(--text-secondary) !important;
|
||||
}
|
||||
|
||||
.password-group {
|
||||
position: relative;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.show-password {
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position:absolute;
|
||||
right:12px;
|
||||
top:50%;
|
||||
transform:translateY(-50%);
|
||||
background:none;
|
||||
border:none;
|
||||
padding:4px;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.icon-eye {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
opacity: 0.6;
|
||||
transition: opacity 0.2s ease;
|
||||
filter: invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
width:20px;
|
||||
height:20px;
|
||||
opacity:0.6;
|
||||
transition:opacity 0.2s ease;
|
||||
filter:invert(var(--icon-invert)) sepia(var(--icon-sepia)) saturate(var(--icon-saturate)) hue-rotate(var(--icon-hue-rotate)) brightness(var(--icon-brightness));
|
||||
}
|
||||
|
||||
.show-password:hover .icon-eye {
|
||||
opacity: 1;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
margin-top:16px;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
border-radius: 6px;
|
||||
border: 2px solid var(--accent-accent);
|
||||
background-color: var(--card-card);
|
||||
cursor: pointer;
|
||||
width:20px;
|
||||
height:20px;
|
||||
margin-right:8px;
|
||||
border-radius:6px;
|
||||
border:2px solid var(--accent-accent);
|
||||
background-color:var(--card-card);
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.form-check-input:checked {
|
||||
background-color: var(--accent-accent);
|
||||
border-color: var(--accent-accent);
|
||||
background-color:var(--accent-accent);
|
||||
border-color:var(--accent-accent);
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
color: var(--text-primary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
cursor: pointer;
|
||||
color:var(--text-primary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.btn-kreta {
|
||||
display: flex;
|
||||
height: 48px;
|
||||
padding: 0px 24px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
border-radius: 12px;
|
||||
background: var(--accent-accent);
|
||||
color: white;
|
||||
font-family: Montserrat;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
display:flex;
|
||||
height:48px;
|
||||
padding:0px 24px;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
border-radius:12px;
|
||||
background:var(--accent-accent);
|
||||
color:white;
|
||||
font-family:Montserrat;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:normal;
|
||||
border:none;
|
||||
cursor:pointer;
|
||||
transition:background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
background-color: var(--accent-secondary);
|
||||
background-color:var(--accent-secondary);
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--accent-accent);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
background:none;
|
||||
border:none;
|
||||
color:var(--accent-accent);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-decoration:underline;
|
||||
cursor:pointer;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.btn-link:hover {
|
||||
color: var(--accent-secondary);
|
||||
color:var(--accent-secondary);
|
||||
}
|
||||
|
||||
.subtext {
|
||||
color: var(--text-primary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
color:var(--text-primary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.login-footer {
|
||||
margin-top: 24px;
|
||||
text-align: center;
|
||||
margin-top:24px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
font-family: Figtree;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
text-decoration: none;
|
||||
color:var(--text-secondary);
|
||||
font-family:Figtree;
|
||||
font-size:14px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
text-decoration: underline;
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
display: none;
|
||||
color: var(--error-text);
|
||||
font-family: Figtree;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 130%;
|
||||
margin-top: 4px;
|
||||
display:none;
|
||||
color:var(--error-text);
|
||||
font-family:Figtree;
|
||||
font-size:12px;
|
||||
font-style:normal;
|
||||
font-weight:400;
|
||||
line-height:130%;
|
||||
margin-top:4px;
|
||||
}
|
||||
|
||||
.error-message.show {
|
||||
display: block;
|
||||
display:block;
|
||||
}
|
||||
|
||||
.form-control.error {
|
||||
border: 1px solid var(--error-accent) !important;
|
||||
border:1px solid var(--error-accent) !important;
|
||||
}
|
||||
|
||||
/* Hide original elements */
|
||||
header, main > .container-fluid, footer {
|
||||
display: none !important;
|
||||
header,main > .container-fluid,footer {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
@media (max-width:576px) {
|
||||
.login-container {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.login-card {
|
||||
padding: 16px;
|
||||
}
|
||||
width:100%;
|
||||
padding:16px;
|
||||
}
|
||||
.login-card {
|
||||
padding:16px;
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,40 @@
|
||||
async function transformTwoFactorPage() {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => {
|
||||
window.addEventListener('load', resolve);
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) => {
|
||||
window.addEventListener("load", resolve);
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.show();
|
||||
}
|
||||
|
||||
const existingForm = document.querySelector('form');
|
||||
const existingForm = document.querySelector("form");
|
||||
const formData = {
|
||||
action: existingForm?.getAttribute('action') || '',
|
||||
clientId: document.querySelector('#ClientId')?.value || '',
|
||||
rememberLogin: document.querySelector('#RememberLogin')?.value || 'False',
|
||||
returnUrl: document.querySelector('#ReturnUrl')?.value || '',
|
||||
isRecoveryCode: document.querySelector('#IsRecoveryCode')?.value || 'False',
|
||||
requestToken: document.querySelector('input[name="__RequestVerificationToken"]')?.value || '',
|
||||
trustDeviceValue: document.querySelector('input[name="TrustDevice"][type="hidden"]')?.value || 'false'
|
||||
action: existingForm?.getAttribute("action") || "",
|
||||
clientId: document.querySelector("#ClientId")?.value || "",
|
||||
rememberLogin: document.querySelector("#RememberLogin")?.value || "False",
|
||||
returnUrl: document.querySelector("#ReturnUrl")?.value || "",
|
||||
isRecoveryCode:
|
||||
document.querySelector("#IsRecoveryCode")?.value || "False",
|
||||
requestToken:
|
||||
document.querySelector('input[name="__RequestVerificationToken"]')
|
||||
?.value || "",
|
||||
trustDeviceValue:
|
||||
document.querySelector('input[name="TrustDevice"][type="hidden"]')
|
||||
?.value || "false",
|
||||
};
|
||||
|
||||
|
||||
const newHTML = `
|
||||
<div class="login-container">
|
||||
<div class="login-card">
|
||||
<div class="card-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="twofactor-title">${LanguageManager.t('twofactor.title')}</h1>
|
||||
<h1 class="twofactor-title">${LanguageManager.t("twofactor.title")}</h1>
|
||||
</div>
|
||||
|
||||
<form class="twofactor-form" action="${formData.action}" method="post" id="twoFactorForm">
|
||||
@@ -41,30 +46,30 @@ async function transformTwoFactorPage() {
|
||||
|
||||
<div class="form-group password-group">
|
||||
<input class="form-control" type="password" id="VerificationCode" name="VerificationCode"
|
||||
placeholder="${LanguageManager.t('twofactor.code_placeholder')}" maxlength="256" autocomplete="off" required autofocus>
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t('twofactor.show_code')}">
|
||||
<img src="${chrome.runtime.getURL('icons/eye-off.svg')}" alt="Show password" class="icon-eye">
|
||||
placeholder="${LanguageManager.t("twofactor.code_placeholder")}" maxlength="256" autocomplete="off" required autofocus>
|
||||
<button type="button" class="show-password" aria-label="${LanguageManager.t("twofactor.show_code")}">
|
||||
<img src="${chrome.runtime.getURL("icons/eye-off.svg")}" alt="Show password" class="icon-eye">
|
||||
</button>
|
||||
<div class="error-message">${LanguageManager.t('twofactor.code_required')}</div>
|
||||
<div class="error-message">${LanguageManager.t("twofactor.code_required")}</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="trustDevice" name="TrustDevice" value="true">
|
||||
<label class="form-check-label" for="trustDevice">
|
||||
${LanguageManager.t('twofactor.trust_device')}
|
||||
${LanguageManager.t("twofactor.trust_device")}
|
||||
</label>
|
||||
<input name="TrustDevice" type="hidden" value="false">
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mb-3 mt-4">
|
||||
<button type="submit" class="btn-kreta">${LanguageManager.t('twofactor.verify_button')}</button>
|
||||
<button type="submit" class="btn-kreta">${LanguageManager.t("twofactor.verify_button")}</button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center mt-3">
|
||||
<span class="subtext">
|
||||
${LanguageManager.t('twofactor.no_access')}
|
||||
${LanguageManager.t("twofactor.no_access")}
|
||||
<button type="submit" class="btn-link" formaction="/account/loginwithrecoverycode">
|
||||
${LanguageManager.t('twofactor.recovery_code')}
|
||||
${LanguageManager.t("twofactor.recovery_code")}
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
@@ -73,21 +78,25 @@ async function transformTwoFactorPage() {
|
||||
|
||||
<footer class="login-footer">
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">${LanguageManager.t('login.privacy_policy')}</a>
|
||||
target="_blank" class="privacy-link">${LanguageManager.t("login.privacy_policy")}</a>
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
applyTheme();
|
||||
setupEventListeners();
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error transforming two-factor page:', error);
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}
|
||||
@@ -95,77 +104,85 @@ async function transformTwoFactorPage() {
|
||||
|
||||
function applyTheme() {
|
||||
try {
|
||||
if (typeof getCookie === 'function') {
|
||||
const theme = getCookie('theme') || 'light-blue';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
if (typeof getCookie === "function") {
|
||||
const theme = getCookie("theme") || "light-blue";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error applying theme:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
const twoFactorForm = document.getElementById('twoFactorForm');
|
||||
const verificationInput = document.getElementById('VerificationCode');
|
||||
const togglePasswordBtn = document.querySelector('.show-password');
|
||||
const formInputs = document.querySelectorAll('.form-control');
|
||||
const twoFactorForm = document.getElementById("twoFactorForm");
|
||||
const verificationInput = document.getElementById("VerificationCode");
|
||||
const togglePasswordBtn = document.querySelector(".show-password");
|
||||
const formInputs = document.querySelectorAll(".form-control");
|
||||
|
||||
if (togglePasswordBtn && verificationInput) {
|
||||
togglePasswordBtn.addEventListener('click', () => {
|
||||
const isPassword = verificationInput.type === 'password';
|
||||
verificationInput.type = isPassword ? 'text' : 'password';
|
||||
const icon = togglePasswordBtn.querySelector('.icon-eye');
|
||||
icon.src = chrome.runtime.getURL(`icons/${isPassword ? 'eye-on' : 'eye-off'}.svg`);
|
||||
togglePasswordBtn.addEventListener("click", () => {
|
||||
const isPassword = verificationInput.type === "password";
|
||||
verificationInput.type = isPassword ? "text" : "password";
|
||||
const icon = togglePasswordBtn.querySelector(".icon-eye");
|
||||
icon.src = chrome.runtime.getURL(
|
||||
`icons/${isPassword ? "eye-on" : "eye-off"}.svg`,
|
||||
);
|
||||
});
|
||||
}
|
||||
formInputs.forEach(input => {
|
||||
input.addEventListener('input', () => {
|
||||
formInputs.forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateInput(input);
|
||||
});
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
input.addEventListener("blur", () => {
|
||||
validateInput(input, true);
|
||||
});
|
||||
});
|
||||
if (twoFactorForm) {
|
||||
twoFactorForm.addEventListener('submit', handleSubmit);
|
||||
twoFactorForm.addEventListener("submit", handleSubmit);
|
||||
}
|
||||
}
|
||||
|
||||
function validateInput(input, showError = false) {
|
||||
const isValid = input.value.trim().length > 0;
|
||||
const errorElement = input.nextElementSibling?.nextElementSibling;
|
||||
|
||||
|
||||
if (!isValid && showError) {
|
||||
input.classList.add('error');
|
||||
errorElement?.classList.add('show');
|
||||
input.classList.add("error");
|
||||
errorElement?.classList.add("show");
|
||||
} else {
|
||||
input.classList.remove('error');
|
||||
errorElement?.classList.remove('show');
|
||||
input.classList.remove("error");
|
||||
errorElement?.classList.remove("show");
|
||||
}
|
||||
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function handleSubmit(event) {
|
||||
event.preventDefault();
|
||||
|
||||
|
||||
const form = event.target;
|
||||
const inputs = form.querySelectorAll('.form-control[required]');
|
||||
const inputs = form.querySelectorAll(".form-control[required]");
|
||||
let isValid = true;
|
||||
inputs.forEach(input => {
|
||||
inputs.forEach((input) => {
|
||||
if (!validateInput(input, true)) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
if (isValid) {
|
||||
const submitButton = form.querySelector('.btn-kreta');
|
||||
const submitButton = form.querySelector(".btn-kreta");
|
||||
if (submitButton) {
|
||||
submitButton.disabled = true;
|
||||
submitButton.innerHTML = `<span class="spinner"></span><span class="btn-text">${LanguageManager.t('twofactor.verifying')}</span>`;
|
||||
submitButton.innerHTML = '';
|
||||
const spinnerSpan = document.createElement('span');
|
||||
spinnerSpan.className = 'spinner';
|
||||
const textSpan = document.createElement('span');
|
||||
textSpan.className = 'btn-text';
|
||||
textSpan.textContent = LanguageManager.t('twofactor.verifying');
|
||||
submitButton.appendChild(spinnerSpan);
|
||||
submitButton.appendChild(textSpan);
|
||||
}
|
||||
|
||||
|
||||
form.submit();
|
||||
}
|
||||
}
|
||||
transformTwoFactorPage();
|
||||
transformTwoFactorPage();
|
||||
|
||||
@@ -1,138 +1,117 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.logout-container {
|
||||
width: 100%;
|
||||
max-width: 500px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
width:100%;
|
||||
max-width:500px;
|
||||
padding:20px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.logout-header {
|
||||
text-align: center;
|
||||
margin-bottom: 24px;
|
||||
text-align:center;
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 16px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color:var(--text-primary);
|
||||
font-size:24px;
|
||||
font-weight:600;
|
||||
margin:16px 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
width:24px;
|
||||
border-radius:8px;
|
||||
margin-right:8px;
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
background: var(--card-card);
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:24px;
|
||||
border-radius:24px;
|
||||
text-align:center;
|
||||
margin-bottom:16px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-message {
|
||||
margin-bottom: 24px;
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.logout-message strong {
|
||||
font-size: 18px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
font-size:18px;
|
||||
color:var(--text-primary);
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.redirect-timer {
|
||||
font-size: 48px;
|
||||
font-weight: 700;
|
||||
color: var(--accent-accent);
|
||||
margin-bottom: 24px;
|
||||
font-size:48px;
|
||||
font-weight:700;
|
||||
color:var(--accent-accent);
|
||||
margin-bottom:24px;
|
||||
}
|
||||
|
||||
.btn-continue {
|
||||
display: inline-block;
|
||||
padding: 12px 24px;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
text-decoration: none;
|
||||
border-radius: 12px;
|
||||
font-weight: 600;
|
||||
transition: background 0.2s ease, color 0.2s ease;
|
||||
display:inline-block;
|
||||
padding:12px 24px;
|
||||
background:var(--accent-accent);
|
||||
color:var(--button-secondaryFill);
|
||||
text-decoration:none;
|
||||
border-radius:12px;
|
||||
font-weight:600;
|
||||
transition:background 0.2s ease,color 0.2s ease;
|
||||
}
|
||||
|
||||
.btn-continue:hover {
|
||||
background: var(--accent-secondary) !important;
|
||||
color: var(--button-secondaryFill) !important;
|
||||
background:var(--accent-secondary) !important;
|
||||
color:var(--button-secondaryFill) !important;
|
||||
}
|
||||
|
||||
.logout-footer {
|
||||
text-align: center;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
margin-bottom: 8px;
|
||||
transition: color 0.2s ease;
|
||||
color:var(--text-secondary);
|
||||
text-decoration:none;
|
||||
font-size:14px;
|
||||
display:inline-block;
|
||||
margin-bottom:8px;
|
||||
transition:color 0.2s ease;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--text-primary);
|
||||
color:var(--text-primary);
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
@media (max-width:600px) {
|
||||
.logout-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.redirect-timer {
|
||||
font-size: 36px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
}
|
||||
padding:16px;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
.logout-card {
|
||||
padding:20px;
|
||||
}
|
||||
.redirect-timer {
|
||||
font-size:36px;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:20px;
|
||||
}
|
||||
.logo {
|
||||
width:20px;
|
||||
}
|
||||
}@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,17 @@
|
||||
(() => {
|
||||
function loadFonts() {
|
||||
// Create a new style element
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap');
|
||||
@import url('https://fonts.googleapis.com/icon?family=Material+Icons+Round');
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
function transformLogoutPage() {
|
||||
// Get current theme and school ID from cookies
|
||||
const theme = cookieManager.get('themePreference') || localStorage.getItem('themePreference') || 'light-green';
|
||||
const instituteCode = cookieManager.get('schoolSubdomain');
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
// Create new HTML structure
|
||||
async function transformLogoutPage() {
|
||||
const theme =
|
||||
await storageManager.get("themePreference", null) ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
const instituteCode = await storageManager.get("schoolSubdomain", null);
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
const newHTML = `
|
||||
<div class="logout-container">
|
||||
<header class="logout-header">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
</header>
|
||||
@@ -42,39 +34,49 @@
|
||||
</footer>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// Replace body content
|
||||
document.body.innerHTML = newHTML;
|
||||
|
||||
// Start countdown timer
|
||||
const timerElement = document.getElementById('automaticRedirectTimer');
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(newHTML, 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
const timerElement = document.getElementById("automaticRedirectTimer");
|
||||
let remainingTime = 5;
|
||||
|
||||
|
||||
const countdownInterval = setInterval(() => {
|
||||
remainingTime--;
|
||||
if (timerElement) {
|
||||
timerElement.textContent = remainingTime;
|
||||
}
|
||||
|
||||
|
||||
if (remainingTime <= 0) {
|
||||
clearInterval(countdownInterval);
|
||||
window.location.href = `https://${instituteCode}.e-kreta.hu`;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Handle manual redirect click
|
||||
document.querySelector('.btn-continue')?.addEventListener('click', (e) => {
|
||||
|
||||
document.querySelector(".btn-continue")?.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
clearInterval(countdownInterval);
|
||||
window.location.href = `https://${instituteCode}.e-kreta.hu`;
|
||||
});
|
||||
}
|
||||
// Load fonts immediately
|
||||
loadFonts();
|
||||
// Run the transformation
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', transformLogoutPage);
|
||||
|
||||
if (document.readyState === "loading") {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setTimeout(() => {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
}, 100);
|
||||
transformLogoutPage();
|
||||
});
|
||||
} else {
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
transformLogoutPage();
|
||||
}
|
||||
})();
|
||||
247
manifest.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Firxa",
|
||||
"version": "1.2.3",
|
||||
"version": "1.3.4",
|
||||
"description": "KRÉTA webes verziójának újraírása",
|
||||
"icons": {
|
||||
"128": "images/firka_logo_128.png"
|
||||
@@ -12,110 +12,217 @@
|
||||
"128": "images/firka_logo_128.png"
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"storage"
|
||||
],
|
||||
"background": {
|
||||
"service_worker": "tools/background.js"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "firxa@zan1456.hu",
|
||||
"strict_min_version": "58.0"
|
||||
"strict_min_version": "109.0",
|
||||
"data_collection_permissions": {
|
||||
"required": ["none"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"web_accessible_resources": [{
|
||||
"resources": [
|
||||
"settings/*",
|
||||
"global/language.js",
|
||||
"images/*",
|
||||
"fonts/*.woff2",
|
||||
"icons/*.svg",
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/cookieManager.js"
|
||||
],
|
||||
"matches": ["<all_urls>"]
|
||||
}],
|
||||
"web_accessible_resources": [
|
||||
{
|
||||
"resources": [
|
||||
"settings/*",
|
||||
"global/language.js",
|
||||
"images/*",
|
||||
"fonts/*.woff2",
|
||||
"icons/*.svg",
|
||||
"grades/chart.js",
|
||||
"i18n/*.json",
|
||||
"tools/cookieManager.js",
|
||||
"tools/storageManager.js",
|
||||
"tools/storageTest.js"
|
||||
],
|
||||
"matches": [
|
||||
"<all_urls>"
|
||||
]
|
||||
}
|
||||
],
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["https://*.e-kreta.hu/*"],
|
||||
"js": ["tools/loadingScreen.js, tools/cookieManager.js", "tools/helper.js", "tools/createTemplate.js",
|
||||
"global/language.js", "global/maintenance.js", "global/theme.js", "global/navigation.js"],
|
||||
"css": ["tools/loadingScreen.css", "global/theme.css", "global/navigation.css", "global/maintenance.css"],
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Login*",
|
||||
"https://idp.e-kreta.hu/Account/Logout*",
|
||||
"https://idp.e-kreta.hu/Account/LoginWithTwoFactor*",
|
||||
"https://*.e-kreta.hu/Hianyzas/Hianyzasok*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*",
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*",
|
||||
"https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*",
|
||||
"https://*.e-kreta.hu/Orarend/InformaciokOrarend*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/Profil*",
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*",
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*",
|
||||
"https://intezmenykereso.e-kreta.hu/*"
|
||||
],
|
||||
"js": [
|
||||
"global/language.js",
|
||||
"global/theme.js",
|
||||
"tools/loadingScreen.js",
|
||||
"tools/storageManager.js",
|
||||
"tools/helper.js",
|
||||
"tools/createTemplate.js",
|
||||
"global/maintenance.js",
|
||||
"global/navigation.js"
|
||||
],
|
||||
"css": [
|
||||
"tools/loadingScreen.css",
|
||||
"global/theme.css",
|
||||
"global/navigation.css",
|
||||
"global/maintenance.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/Account/Login*"],
|
||||
"js": ["login/login.js"],
|
||||
"css": ["login/login.css"]
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/account/loginwithtwofactor*"],
|
||||
"js": ["login/twofactor.js"],
|
||||
"css": ["login/twofactor.css"]
|
||||
},
|
||||
{
|
||||
"matches": ["https://*.e-kreta.hu/Hianyzas/Hianyzasok*"],
|
||||
"js": ["absences/absences.js"],
|
||||
"css": ["absences/absences.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": ["https://idp.e-kreta.hu/Account/Logout*"],
|
||||
"js": ["logout/logout.js"],
|
||||
"css": ["logout/logout.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": ["https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*"],
|
||||
"js": ["roleselect/roleselect.js"],
|
||||
"css": ["roleselect/roleselect.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": ["https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"],
|
||||
"js": ["forgotpassword/forgotpassword.js"],
|
||||
"css": ["forgotpassword/forgotpassword.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": ["https://*.e-kreta.hu/Intezmeny/Faliujsag*"],
|
||||
"js": ["dashboard/dashboard.js"],
|
||||
"css": ["dashboard/dashboard.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [ "https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*"
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Login*"
|
||||
],
|
||||
"js": [
|
||||
"login/login.js"
|
||||
],
|
||||
"css": [
|
||||
"login/login.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/account/loginwithtwofactor*"
|
||||
],
|
||||
"js": [
|
||||
"login/twofactor.js"
|
||||
],
|
||||
"css": [
|
||||
"login/twofactor.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Hianyzas/Hianyzasok*"
|
||||
],
|
||||
"js": [
|
||||
"absences/absences.js"
|
||||
],
|
||||
"css": [
|
||||
"absences/absences.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://idp.e-kreta.hu/Account/Logout*"
|
||||
],
|
||||
"js": [
|
||||
"logout/logout.js"
|
||||
],
|
||||
"css": [
|
||||
"logout/logout.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/BelepesKezelo*"
|
||||
],
|
||||
"js": [
|
||||
"roleselect/roleselect.js"
|
||||
],
|
||||
"css": [
|
||||
"roleselect/roleselect.css"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Intezmeny/Faliujsag*"
|
||||
],
|
||||
"js": [
|
||||
"dashboard/dashboard.js"
|
||||
],
|
||||
"css": [
|
||||
"dashboard/dashboard.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/TanuloErtekeles/Osztalyzatok*"
|
||||
],
|
||||
"js": [
|
||||
"grades/grades.js",
|
||||
"grades/chart.js"
|
||||
],
|
||||
"css": [
|
||||
"grades/grades.css"
|
||||
],
|
||||
"js": ["grades/grades.js", "grades/chart.js"],
|
||||
"css": ["grades/grades.css"],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Orarend/InformaciokOrarend*"
|
||||
],
|
||||
"js": ["timetable/timetable.js"],
|
||||
"css": ["timetable/timetable.css"],
|
||||
"js": [
|
||||
"timetable/timetable.js"
|
||||
],
|
||||
"css": [
|
||||
"timetable/timetable.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/Profil*"
|
||||
],
|
||||
"js": ["profile/profile.js"],
|
||||
"css": ["profile/profile.css"],
|
||||
"js": [
|
||||
"profile/profile.js"
|
||||
],
|
||||
"css": [
|
||||
"profile/profile.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Tanulo/TanuloHaziFeladat*"
|
||||
],
|
||||
"js": ["homework/homework.js"],
|
||||
"css": ["homework/homework.css"],
|
||||
"js": [
|
||||
"homework/homework.js"
|
||||
],
|
||||
"css": [
|
||||
"homework/homework.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.e-kreta.hu/Adminisztracio/ElfelejtettJelszo*"
|
||||
],
|
||||
"js": [
|
||||
"forgotpassword/forgotpassword.js"
|
||||
],
|
||||
"css": [
|
||||
"forgotpassword/forgotpassword.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://intezmenykereso.e-kreta.hu/"
|
||||
],
|
||||
"js": ["search/search.js"],
|
||||
"css": ["search/search.css"],
|
||||
"js": [
|
||||
"search/search.js"
|
||||
],
|
||||
"css": [
|
||||
"search/search.css"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,366 +1,325 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@import url('../global/theme.css');
|
||||
|
||||
|
||||
.main-header,
|
||||
.main-menu,
|
||||
.main-sidebar,
|
||||
.content-header,
|
||||
.favoriteIconContainer,
|
||||
#frissitesDatumDiv,
|
||||
#layout_navigationBar,
|
||||
.navbar,
|
||||
.sidebar-container,
|
||||
#sidepanel_tabs,
|
||||
.sidepanel-wrapper {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
color: var(--text-primary) !important;
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.kreta-container {
|
||||
.page-wrapper {
|
||||
background-color: var(--background) !important;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 0;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.content-content {
|
||||
background-color: var(--background) !important;
|
||||
min-height: auto !important;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
|
||||
.kreta-header {
|
||||
.firka-header {
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(300px, 400px) 1fr minmax(200px, 300px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background-color: var(--background);
|
||||
border-bottom: 1px solid var(--accent-15);
|
||||
}
|
||||
|
||||
.school-info {
|
||||
.back-button {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
padding: 12px 16px;
|
||||
color: var(--text-primary);
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-decoration: none;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
.back-button:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.back-button svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
fill: var(--text-primary);
|
||||
}
|
||||
|
||||
.page-title {
|
||||
color: var(--text-primary);
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
border-radius: 8px;
|
||||
margin-right: 8px;
|
||||
|
||||
.k-content {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
position: relative;
|
||||
justify-self: flex-end;
|
||||
}
|
||||
|
||||
.user-dropdown-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.user-dropdown-btn:hover {
|
||||
background: var(--card-card);
|
||||
}
|
||||
|
||||
.user-info {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
width: 200px;
|
||||
display: none;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.user-dropdown.show {
|
||||
display: block;
|
||||
animation: dropdownShow 0.2s ease;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
|
||||
.kreta-main {
|
||||
flex: 1;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: var(--card-card);
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
padding: 1.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
background-color: var(--card-card);
|
||||
}
|
||||
|
||||
|
||||
.profile-tabs {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.tab-headers {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
border-bottom: 1px solid var(--card-translucent);
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.tab-headers::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
padding: 0.75rem 1rem;
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
border-bottom: 2px solid transparent;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.tab-header.active {
|
||||
color: var(--accent-accent);
|
||||
border-bottom-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
display: none;
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 8px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.tab-content.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid var(--accent-15);
|
||||
border-radius: 8px;
|
||||
background: var(--accent-15);
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
outline: none;
|
||||
border-color: var(--accent-accent);
|
||||
}
|
||||
|
||||
.form-text {
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
|
||||
.security-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.step-card {
|
||||
background: var(--button-secondaryFill);
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
.step-card h3 {
|
||||
color: var(--text-primary);
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.step-card p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
margin-bottom: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.app-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1.5rem;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.app-section h4 {
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.app-links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.app-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.75rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 8px;
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.app-link:hover {
|
||||
background: var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
.qr-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
|
||||
.qr-container img {
|
||||
background: white;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.setup-key {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.key-display {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
background: var(--card-card);
|
||||
padding: 0.75rem;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.key-display code {
|
||||
font-family: monospace;
|
||||
color: var(--text-primary);
|
||||
font-size: 14px;
|
||||
flex-grow: 1;
|
||||
.k-content h4 {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 28px !important;
|
||||
font-weight: 600 !important;
|
||||
margin: 0 0 2rem 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-copy {
|
||||
background: none;
|
||||
border: none;
|
||||
color: var(--text-secondary);
|
||||
cursor: pointer;
|
||||
padding: 0.25rem;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.k-tabstrip-wrapper {
|
||||
background: var(--card-card) !important;
|
||||
border-radius: 24px !important;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow);
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.btn-copy:hover {
|
||||
color: var(--text-primary);
|
||||
background: var(--button-secondaryFill);
|
||||
.k-tabstrip {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
border-radius: 24px 24px 0 0 !important;
|
||||
padding: 0 20px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
margin: 0 !important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
color: var(--text-secondary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
padding: 16px 20px !important;
|
||||
border: none !important;
|
||||
background: transparent !important;
|
||||
border-radius: 0 !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item.k-state-active .k-link {
|
||||
color: var(--accent-accent) !important;
|
||||
font-weight: 600 !important;
|
||||
border-bottom: 2px solid var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item:hover .k-link {
|
||||
color: var(--text-primary) !important;
|
||||
}
|
||||
|
||||
|
||||
.btn-save {
|
||||
padding: 0.75rem 1.5rem;
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
transition: background-color 0.2s;
|
||||
.k-tabstrip .k-content {
|
||||
background: var(--card-card) !important;
|
||||
border: none !important;
|
||||
padding: 20px !important;
|
||||
border-radius: 0 0 24px 24px !important;
|
||||
}
|
||||
|
||||
.btn-save:hover {
|
||||
background: var(--accent-secondary);
|
||||
|
||||
form {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
.container-fluid.details {
|
||||
background: transparent !important;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.row {
|
||||
margin-bottom: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.windowInputLabel {
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 500 !important;
|
||||
font-size: 14px !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="email"],
|
||||
select,
|
||||
textarea {
|
||||
background: var(--button-secondaryFill) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 16px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-size: 14px !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="password"]:focus,
|
||||
input[type="email"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
box-shadow: 0 0 0 3px var(--accent-15) !important;
|
||||
}
|
||||
|
||||
.k-checkbox {
|
||||
appearance: none;
|
||||
width: 20px !important;
|
||||
height: 20px !important;
|
||||
border: 2px solid var(--accent-15) !important;
|
||||
border-radius: 4px !important;
|
||||
background: var(--button-secondaryFill) !important;
|
||||
cursor: pointer !important;
|
||||
position: relative !important;
|
||||
transition: all 0.2s ease !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked {
|
||||
background: var(--accent-accent) !important;
|
||||
border-color: var(--accent-accent) !important;
|
||||
}
|
||||
|
||||
.k-checkbox:checked::after {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.k-checkbox-label {
|
||||
margin-left: 8px !important;
|
||||
color: var(--text-primary) !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
cursor: pointer !important;
|
||||
}
|
||||
|
||||
.k-button,
|
||||
button {
|
||||
background: var(--accent-accent) !important;
|
||||
border: none !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 24px !important;
|
||||
color: white !important;
|
||||
font-family: 'Montserrat', sans-serif !important;
|
||||
font-weight: 600 !important;
|
||||
font-size: 14px !important;
|
||||
cursor: pointer !important;
|
||||
transition: all 0.2s ease !important;
|
||||
box-shadow: 0px 1px var(--shadow-blur, 2px) 0px var(--accent-shadow) !important;
|
||||
}
|
||||
|
||||
.k-button:hover,
|
||||
button:hover {
|
||||
background: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: 0px 2px var(--shadow-blur, 4px) 0px var(--accent-shadow) !important;
|
||||
}
|
||||
|
||||
.k-button:active,
|
||||
button:active {
|
||||
transform: translateY(0) !important;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.content-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.firka-header {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.k-content h4 {
|
||||
font-size: 24px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items {
|
||||
padding: 0 10px !important;
|
||||
}
|
||||
|
||||
.k-tabstrip-items .k-item .k-link {
|
||||
padding: 12px 16px !important;
|
||||
font-size: 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
@@ -368,70 +327,159 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dropdownShow {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
.k-tabstrip-wrapper {
|
||||
animation: fadeIn 0.5s ease forwards;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"school toggle user"
|
||||
"nav nav nav";
|
||||
padding: 1rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
.k-widget,
|
||||
.k-header {
|
||||
background: var(--card-card) !important;
|
||||
color: var(--text-primary) !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
grid-area: school;
|
||||
}
|
||||
.k-state-default {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.user-profile {
|
||||
grid-area: user;
|
||||
}
|
||||
|
||||
.app-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.profile-tabs {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 1rem;
|
||||
}
|
||||
.k-state-active {
|
||||
background: transparent !important;
|
||||
}
|
||||
|
||||
|
||||
.material-icons-round {
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
.k-overlay,
|
||||
.k-window,
|
||||
.k-notification {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
.main-content .content-content {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] {
|
||||
display: flex !important;
|
||||
justify-content: space-between !important;
|
||||
align-items: center !important;
|
||||
margin-top: 2rem !important;
|
||||
padding-top: 2rem !important;
|
||||
border-top: 1px solid var(--accent-15) !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
|
||||
div[style*="display:flex;justify-content:space-between"] label {
|
||||
color: var(--text-secondary) !important;
|
||||
font-size: 12px !important;
|
||||
font-style: italic !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
.hidden-contact-info {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
}
|
||||
|
||||
.hidden-tab {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#ProfilTab-3 {
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
min-height: 500px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .container-fluid {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 h4 {
|
||||
color: #2c3e50;
|
||||
font-weight: 600;
|
||||
margin-bottom: 25px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 3px solid #3498db;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 8px;
|
||||
border-left: 4px solid #3498db;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .row:hover {
|
||||
background: #e3f2fd;
|
||||
transform: translateX(5px);
|
||||
box-shadow: 0 2px 10px rgba(52, 152, 219, 0.2);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .windowInputLabel {
|
||||
color: #34495e;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button {
|
||||
background: linear-gradient(135deg, #3498db, #2980b9);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
padding: 10px 20px;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-button:hover {
|
||||
background: linear-gradient(135deg, #2980b9, #1f5f8b);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 15px rgba(52, 152, 219, 0.4);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input {
|
||||
border: 2px solid #e0e6ed;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
transition: border-color 0.3s ease;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .k-input:focus {
|
||||
border-color: #3498db;
|
||||
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert {
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-info {
|
||||
background: linear-gradient(135deg, #e3f2fd, #bbdefb);
|
||||
color: #1565c0;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-success {
|
||||
background: linear-gradient(135deg, #e8f5e8, #c8e6c9);
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
#ProfilTab-3 .alert-warning {
|
||||
background: linear-gradient(135deg, #fff3e0, #ffcc02);
|
||||
color: #ef6c00;
|
||||
}
|
||||
|
||||
.details .row {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
@@ -1,396 +1,228 @@
|
||||
(() => {
|
||||
function createSecurityTab() {
|
||||
return `
|
||||
<div class="security-content">
|
||||
<div class="setup-steps">
|
||||
<div class="step-card">
|
||||
<h3>1. lépés: Hitelesítési alkalmazás telepítése</h3>
|
||||
<p>A kétfaktoros hitelesítés használatához telepítsen egy időalapú, egyszer használatos jelszó (TOTP) alkalmazást:</p>
|
||||
|
||||
<div class="app-grid">
|
||||
<div class="app-section">
|
||||
<h4>Android</h4>
|
||||
<div class="app-links">
|
||||
<a href="https://play.google.com/store/apps/details?id=hu.innobile.niszauth" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
NISZ Hitelesítő
|
||||
</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.azure.authenticator" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Microsoft Authenticator
|
||||
</a>
|
||||
<a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Google Authenticator
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-section">
|
||||
<h4>iPhone</h4>
|
||||
<div class="app-links">
|
||||
<a href="https://apps.apple.com/hu/app/nisz-hiteles%C3%ADt%C5%91/id1603444961" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
NISZ Hitelesítő
|
||||
</a>
|
||||
<a href="https://apps.apple.com/hu/app/microsoft-authenticator/id983156458" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Microsoft Authenticator
|
||||
</a>
|
||||
<a href="https://apps.apple.com/hu/app/google-authenticator/id388497605" target="_blank" class="app-link">
|
||||
<span class="material-icons-round">download</span>
|
||||
Google Authenticator
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-card">
|
||||
<h3>2. lépés: Kétfaktoros azonosítás beállítása</h3>
|
||||
<div class="setup-form">
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="enable2FA">Kétfaktoros azonosítás bekapcsolása</button>
|
||||
</div>
|
||||
|
||||
<div id="qrSetup" style="display: none;">
|
||||
<div class="qr-container">
|
||||
<img id="qrCode" alt="QR kód" style="display: none;">
|
||||
<div class="setup-key">
|
||||
<label class="form-label">Biztonsági kulcs:</label>
|
||||
<div class="key-display">
|
||||
<code id="secretKey"></code>
|
||||
<button type="button" class="btn-copy" id="copyKey">
|
||||
<span class="material-icons-round">content_copy</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="verificationCode">Ellenőrző kód</label>
|
||||
<input type="text" class="form-control" id="verificationCode" maxlength="6" placeholder="123456">
|
||||
<small class="form-text">Adja meg a hitelesítő alkalmazásban megjelenő 6 számjegyű kódot.</small>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="verify2FA">Ellenőrzés és aktiválás</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step-card" id="backupCodes" style="display: none;">
|
||||
<h3>3. lépés: Biztonsági kódok mentése</h3>
|
||||
<p>Az alábbi biztonsági kódokat használhatja bejelentkezéshez, ha nem fér hozzá a hitelesítő alkalmazásához. Minden kód csak egyszer használható.</p>
|
||||
|
||||
<div class="backup-codes">
|
||||
<pre id="backupCodesList"></pre>
|
||||
<button type="button" class="btn-save" id="downloadCodes">
|
||||
<span class="material-icons-round">download</span>
|
||||
Kódok letöltése
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createContactTab() {
|
||||
return `
|
||||
<div class="contact-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="email">E-mail cím</label>
|
||||
<input type="email" class="form-control" id="email" required>
|
||||
<small class="form-text">Az e-mail cím megadása a jelszó emlékeztető miatt szükséges.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="phone">Telefonszám</label>
|
||||
<input type="tel" class="form-control" id="phone" placeholder="+36 xx xxx xxxx">
|
||||
<small class="form-text">A telefonszám megadása nem kötelező.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="saveContacts">Mentés</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createPasswordTab() {
|
||||
return `
|
||||
<div class="password-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="currentPassword">Jelenlegi jelszó</label>
|
||||
<input type="password" class="form-control" id="currentPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="newPassword">Új jelszó</label>
|
||||
<input type="password" class="form-control" id="newPassword" required minlength="8">
|
||||
<small class="form-text">A jelszónak legalább 8 karakter hosszúnak kell lennie.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="confirmPassword">Új jelszó megerősítése</label>
|
||||
<input type="password" class="form-control" id="confirmPassword" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="savePassword">Jelszó módosítása</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function createSettingsTab() {
|
||||
return `
|
||||
<div class="settings-form">
|
||||
<div class="form-group">
|
||||
<label class="form-label">
|
||||
<input type="checkbox" id="hideTips">
|
||||
Tippek elrejtése
|
||||
</label>
|
||||
<small class="form-text">A tippek megjelenítésének ki/be kapcsolása.</small>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="button" class="btn-save" id="saveSettings">Mentés</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function setupContactForm() {
|
||||
const form = document.querySelector('.contact-form');
|
||||
if (!form) return;
|
||||
|
||||
const emailInput = form.querySelector('#email');
|
||||
const phoneInput = form.querySelector('#phone');
|
||||
const saveButton = form.querySelector('#saveContacts');
|
||||
|
||||
|
||||
emailInput.value = cookieManager.get('userEmail') || '';
|
||||
phoneInput.value = cookieManager.get('userPhone') || '';
|
||||
|
||||
saveButton?.addEventListener('click', async () => {
|
||||
const email = emailInput.value.trim();
|
||||
const phone = phoneInput.value.trim();
|
||||
|
||||
if (!email) {
|
||||
alert(LanguageManager.t('profile.email_required'));
|
||||
return;
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function hideLoadingScreen() {
|
||||
const loadingElement = document.getElementById('KretaProgressBar');
|
||||
if (loadingElement) {
|
||||
loadingElement.style.display = 'none !important';
|
||||
loadingElement.style.visibility = 'hidden';
|
||||
loadingElement.style.opacity = '0';
|
||||
loadingElement.remove();
|
||||
|
||||
}
|
||||
|
||||
if (email && !isValidEmail(email)) {
|
||||
alert(LanguageManager.t('profile.invalid_email'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (phone && !isValidPhone(phone)) {
|
||||
alert(LanguageManager.t('profile.invalid_phone'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveElerhetosegek', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({ email, phone })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert(LanguageManager.t('profile.contacts_saved'));
|
||||
} else {
|
||||
throw new Error(LanguageManager.t('profile.contacts_save_error'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving contacts:', error);
|
||||
alert(LanguageManager.t('profile.save_error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isValidEmail(email) {
|
||||
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
||||
}
|
||||
|
||||
function isValidPhone(phone) {
|
||||
return /^\+?[0-9\s-]{9,}$/.test(phone);
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
|
||||
document.querySelectorAll('.tab-header').forEach(header => {
|
||||
header.addEventListener('click', () => {
|
||||
document.querySelectorAll('.tab-header').forEach(h => h.classList.remove('active'));
|
||||
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
||||
|
||||
header.classList.add('active');
|
||||
const targetId = header.dataset.tab;
|
||||
document.getElementById(`${targetId}-content`).classList.add('active');
|
||||
|
||||
|
||||
const loadingElements = document.querySelectorAll('[class*="loading"], [id*="loading"], [class*="Loading"], [id*="Loading"]');
|
||||
loadingElements.forEach(el => {
|
||||
el.style.display = 'none !important';
|
||||
el.style.visibility = 'hidden';
|
||||
el.style.opacity = '0';
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const userBtn = document.querySelector('.user-dropdown-btn');
|
||||
const userDropdown = document.querySelector('.user-dropdown');
|
||||
|
||||
userBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
userDropdown?.classList.toggle('show');
|
||||
});
|
||||
|
||||
document.addEventListener('click', () => {
|
||||
userDropdown?.classList.remove('show');
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('saveSettings')?.addEventListener('click', async () => {
|
||||
const hideTips = document.getElementById('hideTips').checked;
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveTippekBeallitasa', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({ hideTips })
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert(LanguageManager.t('profile.settings_saved'));
|
||||
} else {
|
||||
throw new Error(LanguageManager.t('profile.settings_save_error'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error saving settings:', error);
|
||||
alert(LanguageManager.t('profile.save_error'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
document.getElementById('savePassword')?.addEventListener('click', async () => {
|
||||
const currentPassword = document.getElementById('currentPassword').value;
|
||||
const newPassword = document.getElementById('newPassword').value;
|
||||
const confirmPassword = document.getElementById('confirmPassword').value;
|
||||
|
||||
if (!currentPassword || !newPassword || !confirmPassword) {
|
||||
alert(LanguageManager.t('profile.fill_all_fields'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword !== confirmPassword) {
|
||||
alert(LanguageManager.t('profile.passwords_not_match'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newPassword.length < 8) {
|
||||
alert(LanguageManager.t('profile.password_min_length'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/Profil/SaveJelszoModositas', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]').value
|
||||
},
|
||||
body: JSON.stringify({
|
||||
currentPassword,
|
||||
newPassword,
|
||||
confirmPassword
|
||||
})
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
alert(LanguageManager.t('profile.password_changed'));
|
||||
document.getElementById('currentPassword').value = '';
|
||||
document.getElementById('newPassword').value = '';
|
||||
document.getElementById('confirmPassword').value = '';
|
||||
} else {
|
||||
throw new Error(LanguageManager.t('profile.password_change_error'));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error changing password:', error);
|
||||
alert(LanguageManager.t('profile.password_change_error'));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const timerEl = document.getElementById('logoutTimer');
|
||||
if (timerEl) {
|
||||
const startTime = parseInt(timerEl.textContent?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
setInterval(updateTimer, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function createProfileHTML() {
|
||||
return `
|
||||
<div class="kreta-container">
|
||||
${createTemplate.header()}
|
||||
|
||||
<main class="kreta-main">
|
||||
<div class="card">
|
||||
<h2>Profil beállítások</h2>
|
||||
<div class="profile-tabs">
|
||||
<div class="tab-headers">
|
||||
<button class="tab-header active" data-tab="settings">Beállítások</button>
|
||||
<button class="tab-header" data-tab="password">Jelszó módosítása</button>
|
||||
<button class="tab-header" data-tab="security">Biztonsági beállítások</button>
|
||||
<button class="tab-header" data-tab="contacts">Elérhetőségek</button>
|
||||
</div>
|
||||
|
||||
<div id="settings-content" class="tab-content active">
|
||||
${createSettingsTab()}
|
||||
</div>
|
||||
|
||||
<div id="password-content" class="tab-content">
|
||||
${createPasswordTab()}
|
||||
</div>
|
||||
|
||||
<div id="security-content" class="tab-content">
|
||||
${createSecurityTab()}
|
||||
</div>
|
||||
|
||||
<div id="contacts-content" class="tab-content">
|
||||
${createContactTab()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
async function init() {
|
||||
if (window.location.pathname.includes('/Adminisztracio/Profil')) {
|
||||
|
||||
|
||||
function addBackButton() {
|
||||
|
||||
if (document.getElementById('firka-back-button')) {
|
||||
return;
|
||||
}
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
document.body.innerHTML = createProfileHTML();
|
||||
setupUserDropdown();
|
||||
setupMobileNavigation();
|
||||
setupEventListeners();
|
||||
setupContactForm();
|
||||
}
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.id = 'firka-back-button';
|
||||
backButton.innerHTML = '← Vissza';
|
||||
backButton.style.cssText = `
|
||||
position: static;
|
||||
margin: 20px;
|
||||
z-index: 100;
|
||||
background-color: var(--card-background, #ffffff);
|
||||
color: var(--text-primary, #333333);
|
||||
border: 1px solid var(--border-color, #e0e0e0);
|
||||
border-radius: 8px;
|
||||
padding: 10px 16px;
|
||||
font-family: 'Montserrat', sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.2s ease;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: auto;
|
||||
`;
|
||||
|
||||
|
||||
backButton.addEventListener('mouseenter', function() {
|
||||
this.style.backgroundColor = 'var(--card-hover, #f5f5f5)';
|
||||
this.style.transform = 'translateY(-1px)';
|
||||
this.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15)';
|
||||
});
|
||||
|
||||
backButton.addEventListener('mouseleave', function() {
|
||||
this.style.backgroundColor = 'var(--card-background, #ffffff)';
|
||||
this.style.transform = 'translateY(0)';
|
||||
this.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.1)';
|
||||
});
|
||||
|
||||
|
||||
backButton.addEventListener('click', function() {
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
|
||||
document.body.insertBefore(backButton, document.body.firstChild);
|
||||
|
||||
}
|
||||
|
||||
init();
|
||||
|
||||
|
||||
function hideMainFooter2() {
|
||||
const footer2 = document.querySelector('.main-footer2');
|
||||
if (footer2) {
|
||||
footer2.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideLakatImg() {
|
||||
const lakatImg = document.querySelector('.lakatimg');
|
||||
if (lakatImg) {
|
||||
lakatImg.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideCustomUserSettingsTab() {
|
||||
|
||||
const firstTab = document.querySelector('#ProfilTab .k-tabstrip-items li[aria-controls="ProfilTab-1"]');
|
||||
if (firstTab) {
|
||||
firstTab.classList.add('hidden-tab');
|
||||
}
|
||||
|
||||
|
||||
const tabLinks = document.querySelectorAll('#ProfilTab .k-tabstrip-items .k-link');
|
||||
tabLinks.forEach(link => {
|
||||
if (link.textContent && link.textContent.includes('Egyedi felhasználó beállítások')) {
|
||||
const parentTab = link.closest('li');
|
||||
if (parentTab) {
|
||||
parentTab.classList.add('hidden-tab');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
const contentPanel = document.querySelector('#ProfilTab-1');
|
||||
if (contentPanel) {
|
||||
contentPanel.classList.add('hidden-tab');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function hideAdditionalContactInfo() {
|
||||
|
||||
function hideElementsWithText(text) {
|
||||
const elements = document.querySelectorAll('h4');
|
||||
elements.forEach(h4 => {
|
||||
if (h4.textContent && h4.textContent.includes(text)) {
|
||||
// Hide the parent row
|
||||
let parent = h4.closest('.row');
|
||||
if (parent) {
|
||||
parent.classList.add('hidden-contact-info');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
hideElementsWithText('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK');
|
||||
hideElementsWithText('TOVÁBBI TELEFONSZÁMOK');
|
||||
|
||||
|
||||
const rows = document.querySelectorAll('.row');
|
||||
rows.forEach(row => {
|
||||
const h4Elements = row.querySelectorAll('h4');
|
||||
h4Elements.forEach(h4 => {
|
||||
if (h4.textContent &&
|
||||
(h4.textContent.includes('TOVÁBBI E-MAIL ELÉRHETŐSÉGEK') ||
|
||||
h4.textContent.includes('TOVÁBBI TELEFONSZÁMOK'))) {
|
||||
row.classList.add('hidden-contact-info');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function init() {
|
||||
hideLoadingScreen();
|
||||
addBackButton();
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
|
||||
|
||||
const observer = new MutationObserver(() => {
|
||||
hideAdditionalContactInfo();
|
||||
hideCustomUserSettingsTab();
|
||||
hideMainFooter2();
|
||||
hideLakatImg();
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('load', init);
|
||||
|
||||
|
||||
setTimeout(hideLoadingScreen, 1000);
|
||||
|
||||
|
||||
let attempts = 0;
|
||||
const maxAttempts = 20;
|
||||
const aggressiveHide = setInterval(() => {
|
||||
attempts++;
|
||||
hideLoadingScreen();
|
||||
|
||||
if (attempts >= maxAttempts) {
|
||||
clearInterval(aggressiveHide);
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
if (typeof MutationObserver !== 'undefined') {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType === 1) {
|
||||
if (node.id === 'KretaProgressBar' ||
|
||||
node.className && (node.className.includes('loading') || node.className.includes('Loading'))) {
|
||||
node.style.display = 'none !important';
|
||||
node.style.visibility = 'hidden';
|
||||
node.style.opacity = '0';
|
||||
if (node.parentNode) {
|
||||
node.parentNode.removeChild(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -1,354 +1,323 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
|
||||
.kreta-container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: clamp(1rem, 3vw, 2rem);
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width:100%;
|
||||
min-height:100vh;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
padding:clamp(1rem,3vw,2rem);
|
||||
max-width:1200px;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
|
||||
.kreta-header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
margin-bottom: clamp(2rem, 5vw, 3rem);
|
||||
display:grid;
|
||||
grid-template-columns:auto 1fr auto;
|
||||
align-items:center;
|
||||
gap:2rem;
|
||||
margin-bottom:clamp(2rem,5vw,3rem);
|
||||
}
|
||||
|
||||
|
||||
.school-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:0.5rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
font-size:1.5rem;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
margin:0;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 8px;
|
||||
margin-right: 0.75rem;
|
||||
width:32px;
|
||||
height:32px;
|
||||
border-radius:8px;
|
||||
margin-right:0.75rem;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.1rem;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width: 300px;
|
||||
padding-left: 2px;
|
||||
color:var(--text-secondary);
|
||||
font-size:1.1rem;
|
||||
white-space:nowrap;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
max-width:300px;
|
||||
padding-left:2px;
|
||||
}
|
||||
|
||||
|
||||
.user-profile {
|
||||
justify-self: flex-end;
|
||||
text-align: right;
|
||||
justify-self:flex-end;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:flex-end;
|
||||
gap:4px;
|
||||
}
|
||||
|
||||
|
||||
.user-name, .role-text {
|
||||
color: var(--text-primary);
|
||||
font-family: Montserrat;
|
||||
font-weight: 600;
|
||||
.user-name,.role-text {
|
||||
color:var(--text-primary);
|
||||
font-family:Montserrat;
|
||||
font-weight:600;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 16px;
|
||||
font-size:16px;
|
||||
}
|
||||
|
||||
.role-text {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
font-size:20px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.logout-timer, .role-description {
|
||||
color: var(--text-secondary);
|
||||
font-family: Figtree;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
.logout-timer,.role-description {
|
||||
color:var(--text-secondary);
|
||||
font-family:Figtree;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
.logout-timer {
|
||||
font-size: 14px;
|
||||
text-align: right;
|
||||
font-size:14px;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.role-description {
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
font-size:16px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
|
||||
.role-container {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.role-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr minmax(300px, 1fr);
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
display:grid;
|
||||
grid-template-columns:1fr minmax(300px,1fr);
|
||||
gap:1.5rem;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
display: grid;
|
||||
grid-template-rows: 1fr auto;
|
||||
gap: 1.5rem;
|
||||
display:grid;
|
||||
grid-template-rows:1fr auto;
|
||||
gap:1.5rem;
|
||||
}
|
||||
|
||||
|
||||
.role-card {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1.5rem;
|
||||
padding: 2rem;
|
||||
background: var(--card-card);
|
||||
border-radius: 1rem;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
border: none;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition: all 0.2s ease;
|
||||
width:100%;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
gap:1.5rem;
|
||||
padding:2rem;
|
||||
background:var(--card-card);
|
||||
border-radius:1rem;
|
||||
cursor:pointer;
|
||||
text-align:center;
|
||||
border:none;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.role-card[data-role="Ellenorzo"] {
|
||||
height: 480px;
|
||||
background: var(--card-card);
|
||||
height:480px;
|
||||
background:var(--card-card);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"] {
|
||||
height: 280px;
|
||||
background: var(--card-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
height:280px;
|
||||
background:var(--card-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-card {
|
||||
height: 180px;
|
||||
background: var(--error-card);
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
height:180px;
|
||||
background:var(--error-card);
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
.role-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 12px;
|
||||
transition: transform 0.2s ease;
|
||||
background: var(--accent-15);
|
||||
width:48px;
|
||||
height:48px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
border-radius:12px;
|
||||
transition:transform 0.2s ease;
|
||||
background:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
transition: transform 0.2s ease;
|
||||
width:32px;
|
||||
height:32px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"] .role-icon {
|
||||
background: var(--warning-15);
|
||||
background:var(--warning-15);
|
||||
}
|
||||
|
||||
.logout-card .role-icon {
|
||||
background: var(--error-15);
|
||||
background:var(--error-15);
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
transition: transform 0.2s ease;
|
||||
width:32px;
|
||||
height:32px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
|
||||
|
||||
.role-card:hover {
|
||||
transform: translateY(-2px);
|
||||
transform:translateY(-2px);
|
||||
}
|
||||
|
||||
.role-card:hover .role-icon img {
|
||||
transform: scale(1.2);
|
||||
transform:scale(1.2);
|
||||
}
|
||||
|
||||
.role-card:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
transform:translateY(1px);
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
.role-card[data-role="Ellenorzo"]:hover {
|
||||
background-color: var(--accent-15);
|
||||
background-color:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"]:hover {
|
||||
background-color: var(--accent-15);
|
||||
background-color:var(--accent-15);
|
||||
}
|
||||
|
||||
.role-card[data-role="DKT"]:active {
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logout-card:hover {
|
||||
background-color: var(--error-15);
|
||||
background-color:var(--error-15);
|
||||
}
|
||||
|
||||
.logout-card:active {
|
||||
box-shadow: 0px 0px var(--shadow-blur) 0px var(--error-shadow);
|
||||
box-shadow:0px 0px var(--shadow-blur) 0px var(--error-shadow);
|
||||
}
|
||||
|
||||
|
||||
:root[data-theme="light-blue"] .role-card:hover,
|
||||
:root[data-theme="light-green"] .role-card:hover {
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
:root[data-theme="light-blue"] .role-card:hover,:root[data-theme="light-green"] .role-card:hover {
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
width:8px;
|
||||
height:8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--background);
|
||||
background:var(--background);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--text-secondary);
|
||||
border-radius: 4px;
|
||||
background:var(--text-secondary);
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-primary);
|
||||
background:var(--text-primary);
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
opacity:0;
|
||||
transform:translateY(-10px);
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
to {
|
||||
opacity:1;
|
||||
transform:translateY(0);
|
||||
}
|
||||
}@media (max-width:1200px) {
|
||||
.role-grid {
|
||||
grid-template-columns: 1fr 280px;
|
||||
}
|
||||
grid-template-columns:1fr 280px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
}@media (max-width:900px) {
|
||||
.role-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: none;
|
||||
}
|
||||
|
||||
.role-card[data-role="Ellenorzo"],
|
||||
.role-card[data-role="DKT"],
|
||||
.logout-card {
|
||||
height: 300px;
|
||||
}
|
||||
grid-template-columns:1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.side-roles {
|
||||
grid-template-columns:1fr 1fr;
|
||||
grid-template-rows:none;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:300px;
|
||||
}
|
||||
}@media (max-width:768px) {
|
||||
.kreta-header {
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.school-info {
|
||||
max-width: 60%;
|
||||
}
|
||||
|
||||
.school-details {
|
||||
max-width: 200px;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
grid-template-columns:1fr auto;
|
||||
gap:1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.school-info {
|
||||
max-width:60%;
|
||||
}
|
||||
.school-details {
|
||||
max-width:200px;
|
||||
font-size:1rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:1.2rem;
|
||||
}
|
||||
.logo {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
}@media (max-width:640px) {
|
||||
.kreta-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.side-roles {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.role-card {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.role-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.role-icon img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
|
||||
.role-text {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.role-description {
|
||||
font-size: 1rem;
|
||||
}
|
||||
padding:1rem;
|
||||
}
|
||||
.side-roles {
|
||||
grid-template-columns:1fr;
|
||||
gap:0.75rem;
|
||||
}
|
||||
.role-card {
|
||||
padding:1rem;
|
||||
gap:1rem;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:200px;
|
||||
}
|
||||
.role-icon {
|
||||
width:40px;
|
||||
height:40px;
|
||||
}
|
||||
.role-icon img {
|
||||
width:24px;
|
||||
height:24px;
|
||||
}
|
||||
.role-text {
|
||||
font-size:1.5rem;
|
||||
}
|
||||
.role-description {
|
||||
font-size:1.2rem;
|
||||
}
|
||||
.user-name {
|
||||
font-size:18px;
|
||||
}
|
||||
.logout-timer {
|
||||
font-size:16px;
|
||||
}
|
||||
}
|
||||
@media (max-width:480px) {
|
||||
.kreta-container {
|
||||
padding:0.75rem;
|
||||
}
|
||||
.kreta-header {
|
||||
margin-bottom:1.5rem;
|
||||
}
|
||||
.side-roles {
|
||||
gap:0.5rem;
|
||||
}
|
||||
.role-card {
|
||||
padding:0.75rem;
|
||||
gap:0.75rem;
|
||||
}
|
||||
.role-card[data-role="Ellenorzo"],.role-card[data-role="DKT"],.logout-card {
|
||||
height:160px;
|
||||
}
|
||||
.role-text {
|
||||
font-size:1.6rem;
|
||||
line-height:1.2;
|
||||
}
|
||||
.role-description {
|
||||
font-size:1.3rem;
|
||||
line-height:1.3;
|
||||
}
|
||||
.user-name {
|
||||
font-size:20px;
|
||||
}
|
||||
.logout-timer {
|
||||
font-size:18px;
|
||||
}
|
||||
.school-details {
|
||||
font-size:0.9rem;
|
||||
}
|
||||
.logo-text {
|
||||
font-size:1.1rem;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
(() => {
|
||||
const startLogoutTimer = () => {
|
||||
let timeLeft = 45 * 60;
|
||||
const timerElement = document.getElementById('logoutTimer');
|
||||
|
||||
const timerElement = document.getElementById("logoutTimer");
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
|
||||
|
||||
if (timerElement) {
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
timerElement.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
timeLeft <= 0 ? window.location.href = '/Home/Logout' : timeLeft--;
|
||||
|
||||
timeLeft <= 0 ? (window.location.href = "/Home/Logout") : timeLeft--;
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
@@ -20,21 +20,24 @@
|
||||
|
||||
const handleRoleChange = async (role) => {
|
||||
try {
|
||||
const response = await fetch('/Adminisztracio/SzerepkorValaszto/ChangeRole', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ Role: role })
|
||||
});
|
||||
|
||||
const response = await fetch(
|
||||
"/Adminisztracio/SzerepkorValaszto/ChangeRole",
|
||||
{
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ Role: role }),
|
||||
},
|
||||
);
|
||||
|
||||
const data = await response.json();
|
||||
if (data.Success) {
|
||||
window.location.assign(data.Url);
|
||||
} else {
|
||||
throw new Error('Role change failed');
|
||||
throw new Error("Role change failed");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error changing role:', error);
|
||||
alert(LanguageManager.t('roleselect.role_change_error'));
|
||||
console.error("Error changing role:", error);
|
||||
alert(LanguageManager.t("roleselect.role_change_error"));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -43,11 +46,11 @@
|
||||
<header class="kreta-header">
|
||||
<div class="school-info">
|
||||
<p class="logo-text">
|
||||
<img src=${chrome.runtime.getURL('images/firka_logo.png')} alt="Firka" class="logo">
|
||||
<img src=${chrome.runtime.getURL("images/firka_logo.png")} alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details">
|
||||
<span>${schoolCode || ''} - ${fullSchoolName || 'Iskola'}</span>
|
||||
<span>${schoolCode || ""} - ${fullSchoolName || "Iskola"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="user-profile">
|
||||
@@ -63,11 +66,11 @@
|
||||
<div class="main-role">
|
||||
<div class="role-card" data-role="Ellenorzo">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/naplo.svg')}" alt="Napló ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/naplo.svg")}" alt="Napló ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
${LanguageManager.t('roleselect.student_book')}
|
||||
<div class="role-description">${LanguageManager.t('roleselect.student_description')}</div>
|
||||
${LanguageManager.t("roleselect.student_book")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.student_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,21 +78,21 @@
|
||||
<div class="side-roles">
|
||||
<div class="role-card" data-role="DKT">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/dkt.svg')}" alt="DKT ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/dkt.svg")}" alt="DKT ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
${LanguageManager.t('roleselect.dkt_title')}
|
||||
<div class="role-description">${LanguageManager.t('roleselect.dkt_description')}</div>
|
||||
${LanguageManager.t("roleselect.dkt_title")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.dkt_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="role-card logout-card">
|
||||
<div class="role-icon">
|
||||
<img src="${chrome.runtime.getURL('icons/logout.svg')}" alt="Kijelentkezés ikon">
|
||||
<img src="${chrome.runtime.getURL("icons/logout.svg")}" alt="Kijelentkezés ikon">
|
||||
</div>
|
||||
<div class="role-text">
|
||||
${LanguageManager.t('roleselect.logout_title')}
|
||||
<div class="role-description">${LanguageManager.t('roleselect.logout_description')}</div>
|
||||
${LanguageManager.t("roleselect.logout_title")}
|
||||
<div class="role-description">${LanguageManager.t("roleselect.logout_description")}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -100,65 +103,77 @@
|
||||
|
||||
const transformRoleSelectPage = async () => {
|
||||
try {
|
||||
if (document.readyState !== 'complete') {
|
||||
await new Promise(resolve => window.addEventListener('load', resolve));
|
||||
if (document.readyState !== "complete") {
|
||||
await new Promise((resolve) =>
|
||||
window.addEventListener("load", resolve),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
const schoolNameEl = document.querySelector('.IntezmenyNev');
|
||||
const schoolName = schoolNameEl?.textContent.trim() || 'Iskola neve';
|
||||
const [schoolCode, fullSchoolName] = schoolName.split(' - ');
|
||||
const schoolNameEl = document.querySelector(".IntezmenyNev");
|
||||
const schoolName = schoolNameEl?.textContent.trim() || "Iskola neve";
|
||||
const [schoolCode, fullSchoolName] = schoolName.split(" - ");
|
||||
|
||||
|
||||
const schoolSubdomain = window.location.hostname.split('.')[0];
|
||||
const schoolSubdomain = window.location.hostname.split(".")[0];
|
||||
|
||||
const userNameEl = document.querySelector('.UserName');
|
||||
const userName = userNameEl?.textContent.trim() || LanguageManager.t('common.username');
|
||||
const userNameEl = document.querySelector(".UserName");
|
||||
const userName =
|
||||
userNameEl?.textContent.trim() || LanguageManager.t("common.username");
|
||||
|
||||
|
||||
if (schoolCode && fullSchoolName) {
|
||||
cookieManager.set('schoolCode', schoolCode);
|
||||
cookieManager.set('schoolName', fullSchoolName);
|
||||
cookieManager.set('schoolSubdomain', schoolSubdomain);
|
||||
await storageManager.set("schoolCode", schoolCode);
|
||||
await storageManager.set("schoolName", fullSchoolName);
|
||||
await storageManager.set("schoolSubdomain", schoolSubdomain);
|
||||
}
|
||||
if (userName) {
|
||||
cookieManager.set('userName', userName);
|
||||
await storageManager.set("userName", userName);
|
||||
}
|
||||
document.body.innerHTML = '';
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(createHTML(
|
||||
schoolCode,
|
||||
fullSchoolName,
|
||||
userName,
|
||||
), 'text/html');
|
||||
const tempDiv = doc.body;
|
||||
while (tempDiv.firstChild) {
|
||||
document.body.appendChild(tempDiv.firstChild);
|
||||
}
|
||||
|
||||
|
||||
document.body.innerHTML = createHTML(schoolCode, fullSchoolName, userName);
|
||||
|
||||
createTemplate.importFonts();
|
||||
|
||||
const timerInterval = startLogoutTimer();
|
||||
|
||||
|
||||
document.querySelector('.role-card[data-role="Ellenorzo"]')?.addEventListener('click', () => {
|
||||
handleRoleChange('Ellenorzo');
|
||||
});
|
||||
document
|
||||
.querySelector('.role-card[data-role="Ellenorzo"]')
|
||||
?.addEventListener("click", () => {
|
||||
handleRoleChange("Ellenorzo");
|
||||
});
|
||||
|
||||
document.querySelector('.role-card[data-role="DKT"]')?.addEventListener('click', () => {
|
||||
window.location.href = '/Adminisztracio/BelepesKezelo/DKTTanuloOrGondviselo';
|
||||
});
|
||||
|
||||
document.querySelector('.logout-card')?.addEventListener('click', async () => {
|
||||
try {
|
||||
clearInterval(timerInterval);
|
||||
await fetch('/Home/LogOut', { method: 'POST' });
|
||||
} catch {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
} finally {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
}
|
||||
});
|
||||
document
|
||||
.querySelector('.role-card[data-role="DKT"]')
|
||||
?.addEventListener("click", () => {
|
||||
window.location.href =
|
||||
"/Adminisztracio/BelepesKezelo/DKTTanuloOrGondviselo";
|
||||
});
|
||||
|
||||
document
|
||||
.querySelector(".logout-card")
|
||||
?.addEventListener("click", async () => {
|
||||
try {
|
||||
clearInterval(timerInterval);
|
||||
await fetch("/Home/LogOut", { method: "POST" });
|
||||
} catch {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
} finally {
|
||||
window.location.replace("https://idp.e-kreta.hu/Account/Logout");
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error transforming page:', error);
|
||||
console.error("Error transforming page:", error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (window.location.href.includes('/Adminisztracio/BelepesKezelo')) {
|
||||
if (window.location.href.includes("/Adminisztracio/BelepesKezelo")) {
|
||||
transformRoleSelectPage();
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -1,222 +1,196 @@
|
||||
/* Hide original elements */
|
||||
header, footer, .page-title, .card-kreta {
|
||||
display: none !important;
|
||||
header,footer,.page-title,.card-kreta {
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important;
|
||||
min-height: 100vh;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif !important;
|
||||
min-height:100vh;
|
||||
font-size:16px;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
/* Firka search page styling */
|
||||
.firka-search-wrapper {
|
||||
width: 90%;
|
||||
max-width: 500px;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width:90%;
|
||||
max-width:500px;
|
||||
padding:0;
|
||||
margin:0 auto;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
position:absolute;
|
||||
top:50%;
|
||||
left:50%;
|
||||
transform:translate(-50%,-50%);
|
||||
}
|
||||
|
||||
/* Firka header styling */
|
||||
.firka-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin: 0;
|
||||
background: var(--card-card) !important;
|
||||
padding: 24px;
|
||||
border-radius: 24px 24px 0 0;
|
||||
width: 100%;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
margin:0;
|
||||
background:var(--card-card) !important;
|
||||
padding:24px;
|
||||
border-radius:24px 24px 0 0;
|
||||
width:100%;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
width:32px;
|
||||
height:32px;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 24px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: normal;
|
||||
margin: 8px 0;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:24px;
|
||||
font-style:normal;
|
||||
font-weight:600;
|
||||
line-height:normal;
|
||||
margin:8px 0;
|
||||
}
|
||||
|
||||
/* Form container styling */
|
||||
.firka-form-container {
|
||||
background: var(--card-card);
|
||||
padding: 0 24px 24px 24px;
|
||||
border-radius: 0 0 24px 24px;
|
||||
width: 100%;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
background:var(--card-card);
|
||||
padding:0 24px 24px 24px;
|
||||
border-radius:0 0 24px 24px;
|
||||
width:100%;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
/* Form styling */
|
||||
form {
|
||||
width: 100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
background-color: var(--button-secondaryFill) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
color: var(--text-primary) !important;
|
||||
padding: 12px 16px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 400 !important;
|
||||
height: auto !important;
|
||||
transition: border-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
|
||||
background-color:var(--button-secondaryFill) !important;
|
||||
border:1px solid var(--accent-15) !important;
|
||||
border-radius:12px !important;
|
||||
color:var(--text-primary) !important;
|
||||
padding:12px 16px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:16px !important;
|
||||
font-weight:400 !important;
|
||||
height:auto !important;
|
||||
transition:border-color 0.2s ease-in-out,box-shadow 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--accent-accent) !important;
|
||||
box-shadow: 0 0 0 2px var(--accent-15) !important;
|
||||
outline: none !important;
|
||||
border-color:var(--accent-accent) !important;
|
||||
box-shadow:0 0 0 2px var(--accent-15) !important;
|
||||
outline:none !important;
|
||||
}
|
||||
|
||||
.form-control::placeholder {
|
||||
color: var(--text-teritary) !important;
|
||||
color:var(--text-teritary) !important;
|
||||
}
|
||||
|
||||
/* Autocomplete dropdown styling */
|
||||
.dropdown-menu {
|
||||
background-color: var(--card-card) !important;
|
||||
border: 1px solid var(--accent-15) !important;
|
||||
border-radius: 12px !important;
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1) !important;
|
||||
padding: 8px !important;
|
||||
max-height: 300px !important;
|
||||
overflow-y: auto !important;
|
||||
width: 100% !important;
|
||||
background-color:var(--card-card) !important;
|
||||
border:1px solid var(--accent-15) !important;
|
||||
border-radius:12px !important;
|
||||
box-shadow:0 4px 8px rgba(0,0,0,0.1) !important;
|
||||
padding:8px !important;
|
||||
max-height:300px !important;
|
||||
overflow-y:auto !important;
|
||||
width:100% !important;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
color: var(--text-primary) !important;
|
||||
padding: 10px 16px !important;
|
||||
border-radius: 8px !important;
|
||||
margin-bottom: 4px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 14px !important;
|
||||
transition: background-color 0.2s ease-in-out !important;
|
||||
color:var(--text-primary) !important;
|
||||
padding:10px 16px !important;
|
||||
border-radius:8px !important;
|
||||
margin-bottom:4px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:14px !important;
|
||||
transition:background-color 0.2s ease-in-out !important;
|
||||
}
|
||||
|
||||
li.dropdown-item:hover, li.dropdown-item:focus {
|
||||
background-color: var(--accent-15) !important;
|
||||
color: var(--text-primary) !important;
|
||||
li.dropdown-item:hover,li.dropdown-item:focus {
|
||||
background-color:var(--accent-15) !important;
|
||||
color:var(--text-primary) !important;
|
||||
text-decoration:none !important;
|
||||
}
|
||||
|
||||
a.dropdown-item:hover, a.dropdown-item:focus {
|
||||
background-color: #00000000 !important;
|
||||
a.dropdown-item:hover,a.dropdown-item:focus {
|
||||
background-color:#00000000 !important;
|
||||
text-decoration:none !important;
|
||||
}
|
||||
|
||||
.dropdown-item.active {
|
||||
background-color: var(--accent-accent) !important;
|
||||
color: white !important;
|
||||
background-color:var(--accent-accent) !important;
|
||||
color:white !important;
|
||||
}
|
||||
|
||||
/* Button styling */
|
||||
.btn-kreta {
|
||||
background-color: var(--accent-accent) !important;
|
||||
color: white !important;
|
||||
border: none !important;
|
||||
border-radius: 12px !important;
|
||||
padding: 12px 24px !important;
|
||||
font-family: Montserrat !important;
|
||||
font-size: 16px !important;
|
||||
font-weight: 600 !important;
|
||||
cursor: pointer !important;
|
||||
transition: background-color 0.2s ease-in-out, transform 0.1s ease-in-out !important;
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
justify-content: center !important;
|
||||
background-color:var(--accent-accent) !important;
|
||||
color:white !important;
|
||||
border:none !important;
|
||||
border-radius:12px !important;
|
||||
padding:12px 24px !important;
|
||||
font-family:Montserrat !important;
|
||||
font-size:16px !important;
|
||||
font-weight:600 !important;
|
||||
cursor:pointer !important;
|
||||
transition:background-color 0.2s ease-in-out,transform 0.1s ease-in-out !important;
|
||||
display:inline-flex !important;
|
||||
align-items:center !important;
|
||||
justify-content:center !important;
|
||||
}
|
||||
|
||||
.btn-kreta:hover {
|
||||
background-color: var(--accent-secondary) !important;
|
||||
transform: translateY(-1px) !important;
|
||||
background-color:var(--accent-secondary) !important;
|
||||
transform:translateY(-1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:active {
|
||||
transform: translateY(1px) !important;
|
||||
transform:translateY(1px) !important;
|
||||
}
|
||||
|
||||
.btn-kreta:disabled {
|
||||
background-color: var(--text-teritary) !important;
|
||||
cursor: not-allowed !important;
|
||||
transform: none !important;
|
||||
background-color:var(--text-teritary) !important;
|
||||
cursor:not-allowed !important;
|
||||
transform:none !important;
|
||||
}
|
||||
|
||||
/* Footer styling */
|
||||
.firka-footer {
|
||||
margin-top: 16px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
margin-top:16px;
|
||||
text-align:center;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.privacy-link {
|
||||
color: var(--text-secondary);
|
||||
font-family: Montserrat;
|
||||
font-size: 14px;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s ease-in-out;
|
||||
color:var(--text-secondary);
|
||||
font-family:Montserrat;
|
||||
font-size:14px;
|
||||
text-decoration:none;
|
||||
transition:color 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
.privacy-link:hover {
|
||||
color: var(--accent-accent);
|
||||
text-decoration: underline;
|
||||
color:var(--accent-accent);
|
||||
text-decoration:underline;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 576px) {
|
||||
@media (max-width:576px) {
|
||||
.firka-search-wrapper {
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.search-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.btn-kreta {
|
||||
padding: 10px 20px !important;
|
||||
font-size: 14px !important;
|
||||
}
|
||||
width:95%;
|
||||
}
|
||||
.search-title {
|
||||
font-size:20px;
|
||||
}
|
||||
.btn-kreta {
|
||||
padding:10px 20px !important;
|
||||
font-size:14px !important;
|
||||
}
|
||||
}
|
||||
122
search/search.js
@@ -1,7 +1,7 @@
|
||||
function initializeTransformation() {
|
||||
const form = document.querySelector('form');
|
||||
const autocomplete = document.querySelector('.autocomplete');
|
||||
|
||||
const form = document.querySelector("form");
|
||||
const autocomplete = document.querySelector(".autocomplete");
|
||||
|
||||
if (form && autocomplete) {
|
||||
applyFirkaStyling();
|
||||
} else {
|
||||
@@ -9,46 +9,67 @@ function initializeTransformation() {
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
});
|
||||
|
||||
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
||||
if (
|
||||
document.readyState === "complete" ||
|
||||
document.readyState === "interactive"
|
||||
) {
|
||||
setTimeout(initializeTransformation, 1000);
|
||||
}
|
||||
|
||||
function applyFirkaStyling() {
|
||||
async function applyFirkaStyling() {
|
||||
try {
|
||||
const theme = cookieManager.get('themePreference') || localStorage.getItem('themePreference') || 'light-green';
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
if (typeof loadingScreen !== 'undefined') {
|
||||
const theme =
|
||||
await storageManager.get("themePreference") ||
|
||||
localStorage.getItem("themePreference") ||
|
||||
"light-green";
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
if (typeof loadingScreen !== "undefined") {
|
||||
loadingScreen.hide();
|
||||
}
|
||||
const originalForm = document.querySelector('form');
|
||||
const instituteInput = document.querySelector('.autocomplete');
|
||||
const redirectButton = document.getElementById('redirectToInstitute');
|
||||
const instituteCodeInput = document.querySelector('.autocomplete-value');
|
||||
const requestToken = document.querySelector('input[name="__RequestVerificationToken"]');
|
||||
const searchWrapper = document.createElement('div');
|
||||
searchWrapper.className = 'firka-search-wrapper';
|
||||
const firkaHeader = document.createElement('div');
|
||||
firkaHeader.className = 'firka-header';
|
||||
firkaHeader.innerHTML = `
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<h1 class="search-title">Válassz iskolát</h1>
|
||||
`;
|
||||
const formContainer = document.createElement('div');
|
||||
formContainer.className = 'firka-form-container';
|
||||
const firkaFooter = document.createElement('div');
|
||||
firkaFooter.className = 'firka-footer';
|
||||
firkaFooter.innerHTML = `
|
||||
<a href="https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926"
|
||||
target="_blank" class="privacy-link">Adatkezelési tájékoztató</a>
|
||||
`;
|
||||
const existingWrapper = document.querySelector('.firka-search-wrapper');
|
||||
const originalForm = document.querySelector("form");
|
||||
const instituteInput = document.querySelector(".autocomplete");
|
||||
const redirectButton = document.getElementById("redirectToInstitute");
|
||||
const instituteCodeInput = document.querySelector(".autocomplete-value");
|
||||
const requestToken = document.querySelector(
|
||||
'input[name="__RequestVerificationToken"]',
|
||||
);
|
||||
const searchWrapper = document.createElement("div");
|
||||
searchWrapper.className = "firka-search-wrapper";
|
||||
const firkaHeader = document.createElement("div");
|
||||
firkaHeader.className = "firka-header";
|
||||
const logoText = document.createElement('p');
|
||||
logoText.className = 'logo-text';
|
||||
|
||||
const logoImg = document.createElement('img');
|
||||
logoImg.src = chrome.runtime.getURL('images/firka_logo.png');
|
||||
logoImg.alt = 'Firka';
|
||||
logoImg.className = 'logo';
|
||||
|
||||
logoText.appendChild(logoImg);
|
||||
logoText.appendChild(document.createTextNode('Firka'));
|
||||
|
||||
const searchTitle = document.createElement('h1');
|
||||
searchTitle.className = 'search-title';
|
||||
searchTitle.textContent = 'Válassz iskolát';
|
||||
|
||||
firkaHeader.appendChild(logoText);
|
||||
firkaHeader.appendChild(searchTitle);
|
||||
const formContainer = document.createElement("div");
|
||||
formContainer.className = "firka-form-container";
|
||||
const firkaFooter = document.createElement("div");
|
||||
firkaFooter.className = "firka-footer";
|
||||
const privacyLink = document.createElement('a');
|
||||
privacyLink.href = 'https://tudasbazis.ekreta.hu/pages/viewpage.action?pageId=4064926';
|
||||
privacyLink.target = '_blank';
|
||||
privacyLink.className = 'privacy-link';
|
||||
privacyLink.textContent = 'Adatkezelési tájékoztató';
|
||||
|
||||
firkaFooter.appendChild(privacyLink);
|
||||
const existingWrapper = document.querySelector(".firka-search-wrapper");
|
||||
if (existingWrapper) {
|
||||
existingWrapper.remove();
|
||||
}
|
||||
@@ -61,33 +82,32 @@ function applyFirkaStyling() {
|
||||
document.body.appendChild(searchWrapper);
|
||||
setupAutocompleteListeners();
|
||||
if (redirectButton) {
|
||||
redirectButton.addEventListener('click', function(event) {
|
||||
redirectButton.addEventListener("click", function (event) {
|
||||
if (!instituteCodeInput.value) {
|
||||
event.preventDefault();
|
||||
alert(LanguageManager.t('search.select_institution'));
|
||||
alert(LanguageManager.t("search.select_institution"));
|
||||
}
|
||||
});
|
||||
}
|
||||
observeAutocompleteValue(instituteCodeInput, redirectButton);
|
||||
} catch (error) {
|
||||
console.error('Error applying Firka styling:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function setupAutocompleteListeners() {
|
||||
const autocompleteInput = document.querySelector('.autocomplete');
|
||||
const autocompleteValue = document.querySelector('.autocomplete-value');
|
||||
const redirectButton = document.getElementById('redirectToInstitute');
|
||||
|
||||
const autocompleteInput = document.querySelector(".autocomplete");
|
||||
const autocompleteValue = document.querySelector(".autocomplete-value");
|
||||
const redirectButton = document.getElementById("redirectToInstitute");
|
||||
|
||||
if (autocompleteInput && autocompleteValue) {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
const dropdown = document.querySelector('.autocomplete-dropdown');
|
||||
const dropdown = document.querySelector(".autocomplete-dropdown");
|
||||
if (dropdown) {
|
||||
dropdown.classList.add('dropdown-menu');
|
||||
const items = dropdown.querySelectorAll('li');
|
||||
items.forEach(item => {
|
||||
item.classList.add('dropdown-item');
|
||||
item.addEventListener('click', () => {
|
||||
dropdown.classList.add("dropdown-menu");
|
||||
const items = dropdown.querySelectorAll("li");
|
||||
items.forEach((item) => {
|
||||
item.classList.add("dropdown-item");
|
||||
item.addEventListener("click", () => {
|
||||
if (redirectButton) {
|
||||
redirectButton.disabled = false;
|
||||
}
|
||||
@@ -95,10 +115,10 @@ function setupAutocompleteListeners() {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -112,7 +132,7 @@ function observeAutocompleteValue(valueInput, button) {
|
||||
|
||||
observer.observe(valueInput, {
|
||||
attributes: true,
|
||||
attributeFilter: ['value']
|
||||
attributeFilter: ["value"],
|
||||
});
|
||||
|
||||
const checkInterval = setInterval(() => {
|
||||
@@ -121,4 +141,4 @@ function observeAutocompleteValue(valueInput, button) {
|
||||
clearInterval(checkInterval);
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,308 +1,250 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing:border-box;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 400px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--text-primary);
|
||||
background-color: var(--background) !important;
|
||||
font-family: "Montserrat", serif;
|
||||
font-size: 14px;
|
||||
width:400px;
|
||||
margin:0;
|
||||
padding:0;
|
||||
color:var(--text-primary);
|
||||
background-color:var(--background) !important;
|
||||
font-family:"Montserrat",serif;
|
||||
font-size:14px;
|
||||
}
|
||||
|
||||
|
||||
* {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width:none;
|
||||
-ms-overflow-style:none;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
display: none;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.popup-container {
|
||||
padding: 16px;
|
||||
padding:16px;
|
||||
}
|
||||
|
||||
.popup-header {
|
||||
text-align: center;
|
||||
margin-bottom: 16px;
|
||||
text-align:center;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
color: var(--text-primary);
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 8px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color:var(--text-primary);
|
||||
font-size:20px;
|
||||
font-weight:600;
|
||||
margin:8px 0;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 20px;
|
||||
border-radius: 6px;
|
||||
margin-right: 8px;
|
||||
width:20px;
|
||||
border-radius:6px;
|
||||
margin-right:8px;
|
||||
}
|
||||
|
||||
.settings-card,
|
||||
.about-card,
|
||||
.support-card {
|
||||
background: var(--card-card);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
margin-bottom: 16px;
|
||||
box-shadow: 0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
.settings-card,.about-card,.support-card {
|
||||
background:var(--card-card);
|
||||
border-radius:16px;
|
||||
padding:16px;
|
||||
margin-bottom:16px;
|
||||
box-shadow:0px 1px var(--shadow-blur) 0px var(--accent-shadow);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 12px;
|
||||
background-color: var(--card-card);
|
||||
font-size:16px;
|
||||
font-weight:600;
|
||||
color:var(--text-primary);
|
||||
margin-bottom:12px;
|
||||
background-color:var(--card-card);
|
||||
}
|
||||
|
||||
.settings-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:16px;
|
||||
}
|
||||
|
||||
.setting-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
gap:12px;
|
||||
}
|
||||
|
||||
.setting-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 500;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
color:var(--text-primary);
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
|
||||
.theme-grid,
|
||||
.language-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
.theme-grid,.language-grid {
|
||||
display:grid;
|
||||
grid-template-columns:repeat(2,1fr);
|
||||
gap:12px;
|
||||
}
|
||||
.theme-option,
|
||||
.language-option {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
transition: transform 0.2s ease;
|
||||
.theme-option,.language-option {
|
||||
background:none;
|
||||
border:none;
|
||||
padding:0;
|
||||
cursor:pointer;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
transition:transform 0.2s ease;
|
||||
}
|
||||
.theme-option:hover,
|
||||
.language-option:hover {
|
||||
transform: translateY(-2px);
|
||||
.theme-option:hover,.language-option:hover {
|
||||
transform:translateY(-2px);
|
||||
}
|
||||
.theme-option.active .theme-preview {
|
||||
outline: 2px solid var(--accent-accent);
|
||||
outline-offset: 2px;
|
||||
outline:2px solid var(--accent-accent);
|
||||
outline-offset:2px;
|
||||
}
|
||||
.language-option.active .language-preview {
|
||||
outline: 2px solid var(--accent-accent);
|
||||
outline-offset: 2px;
|
||||
outline:2px solid var(--accent-accent);
|
||||
outline-offset:2px;
|
||||
}
|
||||
.theme-preview {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width:100%;
|
||||
height:100px;
|
||||
border-radius:8px;
|
||||
overflow:hidden;
|
||||
position:relative;
|
||||
}
|
||||
.theme-option.disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
position: relative;
|
||||
opacity:0.5;
|
||||
cursor:not-allowed;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.theme-option.disabled::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.1);
|
||||
border-radius: 8px;
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
background-color:rgba(0,0,0,0.1);
|
||||
border-radius:8px;
|
||||
}
|
||||
|
||||
.language-option {
|
||||
background: var(--card-card);
|
||||
border: 1px solid var(--border-border);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
transition: all 0.2s ease;
|
||||
background:var(--card-card);
|
||||
border:1px solid var(--border-border);
|
||||
border-radius:8px;
|
||||
padding:12px;
|
||||
transition:all 0.2s ease;
|
||||
}
|
||||
|
||||
.language-option:hover {
|
||||
background: var(--card-hover);
|
||||
border-color: var(--accent-accent);
|
||||
background:var(--card-hover);
|
||||
border-color:var(--accent-accent);
|
||||
}
|
||||
|
||||
.language-option.active {
|
||||
background: var(--accent-accent);
|
||||
border-color: var(--accent-accent);
|
||||
color: white;
|
||||
background:var(--accent-accent);
|
||||
border-color:var(--accent-accent);
|
||||
color:white;
|
||||
}
|
||||
|
||||
.language-name {
|
||||
color: var(--text-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color:var(--text-primary);
|
||||
font-size:12px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
|
||||
.theme-preview.light-blue {
|
||||
background: #DAE4F7;
|
||||
background:#DAE4F7;
|
||||
}
|
||||
|
||||
.theme-preview.light-blue .preview-header {
|
||||
background: #EDF3FF;
|
||||
background:#EDF3FF;
|
||||
}
|
||||
|
||||
.theme-preview.light-blue .preview-card {
|
||||
background: #FBFCFF;
|
||||
background:#FBFCFF;
|
||||
}
|
||||
|
||||
|
||||
.theme-preview.light-green {
|
||||
background: #FAFFF0;
|
||||
background:#FAFFF0;
|
||||
}
|
||||
|
||||
.theme-preview.light-green .preview-header {
|
||||
background: #F3FBDE;
|
||||
background:#F3FBDE;
|
||||
}
|
||||
|
||||
.theme-preview.light-green .preview-card {
|
||||
background: #FEFFFD;
|
||||
background:#FEFFFD;
|
||||
}
|
||||
|
||||
|
||||
.theme-preview.dark-blue {
|
||||
background: #070A0E;
|
||||
background:#070A0E;
|
||||
}
|
||||
|
||||
.theme-preview.dark-blue .preview-header {
|
||||
background: #0F131B;
|
||||
background:#0F131B;
|
||||
}
|
||||
|
||||
.theme-preview.dark-blue .preview-card {
|
||||
background: #131822;
|
||||
background:#131822;
|
||||
}
|
||||
|
||||
|
||||
.theme-preview.dark-green {
|
||||
background: #0D1202;
|
||||
background:#0D1202;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green .preview-header {
|
||||
background: #141905;
|
||||
background:#141905;
|
||||
}
|
||||
|
||||
.theme-preview.dark-green .preview-card {
|
||||
background: #20290b;
|
||||
background:#20290b;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
height: 30%;
|
||||
width: 100%;
|
||||
height:30%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.preview-content {
|
||||
padding: 8px;
|
||||
padding:8px;
|
||||
}
|
||||
|
||||
.preview-card {
|
||||
height: 30px;
|
||||
border-radius: 4px;
|
||||
height:30px;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.theme-name {
|
||||
color: var(--text-primary);
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color:var(--text-primary);
|
||||
font-size:12px;
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
.about-content,
|
||||
.support-content {
|
||||
color: var(--text-secondary);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
.about-content,.support-content {
|
||||
color:var(--text-secondary);
|
||||
font-size:14px;
|
||||
line-height:1.5;
|
||||
}
|
||||
|
||||
.about-content p,
|
||||
.support-content p {
|
||||
margin-bottom: 12px;
|
||||
.about-content p,.support-content p {
|
||||
margin-bottom:12px;
|
||||
}
|
||||
|
||||
.github-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
color: var(--accent-accent);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: color 0.2s;
|
||||
display:inline-flex;
|
||||
align-items:center;
|
||||
gap:6px;
|
||||
color:var(--accent-accent);
|
||||
text-decoration:none;
|
||||
font-weight:500;
|
||||
transition:color 0.2s;
|
||||
}
|
||||
|
||||
.github-link:hover {
|
||||
color: var(--accent-secondary);
|
||||
color:var(--accent-secondary);
|
||||
}
|
||||
|
||||
.support-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 12px;
|
||||
display:flex;
|
||||
gap:8px;
|
||||
margin-top:12px;
|
||||
}
|
||||
|
||||
.support-button {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px;
|
||||
background: var(--accent-15);
|
||||
color: var(--text-primary);
|
||||
text-decoration: none;
|
||||
border-radius: 8px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
gap:6px;
|
||||
padding:8px;
|
||||
background:var(--accent-15);
|
||||
color:var(--text-primary);
|
||||
text-decoration:none;
|
||||
border-radius:8px;
|
||||
font-weight:500;
|
||||
transition:all 0.2s;
|
||||
}
|
||||
|
||||
.support-button:hover {
|
||||
background: var(--accent-accent);
|
||||
color: var(--button-secondaryFill);
|
||||
background:var(--accent-accent);
|
||||
color:var(--button-secondaryFill);
|
||||
}
|
||||
|
||||
.popup-footer {
|
||||
text-align: center;
|
||||
margin-top: 16px;
|
||||
text-align:center;
|
||||
margin-top:16px;
|
||||
}
|
||||
|
||||
.version-info {
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
color:var(--text-secondary);
|
||||
font-size:12px;
|
||||
}
|
||||
|
||||
|
||||
.material-icons-round {
|
||||
font-size: 18px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
font-size:18px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<div class="popup-container">
|
||||
<header class="popup-header">
|
||||
<p class="logo-text">
|
||||
<img src="https://i.imgur.com/WugwlzI.png" alt="Firka" class="logo">
|
||||
<img src="../images/firka_logo.png" alt="Firka" class="logo">
|
||||
Firxa
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@@ -1,181 +1,189 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
while (typeof window.LanguageManager === 'undefined') {
|
||||
await new Promise(resolve => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
function isThemeDisabled(theme) {
|
||||
const blueThemesUnlocked = localStorage.getItem('blueThemesUnlocked') === 'true';
|
||||
return (theme === 'default' || theme === 'light-blue' || theme === 'dark-blue') && !blueThemesUnlocked;
|
||||
}
|
||||
|
||||
function updateThemeAvailability() {
|
||||
const blueThemesUnlocked = localStorage.getItem('blueThemesUnlocked') === 'true';
|
||||
document.querySelectorAll('.theme-option').forEach(button => {
|
||||
const theme = button.dataset.theme;
|
||||
if (theme === 'default' || theme === 'light-blue' || theme === 'dark-blue') {
|
||||
if (blueThemesUnlocked) {
|
||||
button.style.display = 'block';
|
||||
button.classList.remove('disabled');
|
||||
button.removeAttribute('disabled');
|
||||
} else {
|
||||
button.style.display = 'none';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
while (typeof window.LanguageManager === "undefined") {
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
|
||||
function isThemeDisabled(theme) {
|
||||
const blueThemesUnlocked =
|
||||
localStorage.getItem("blueThemesUnlocked") === "true";
|
||||
return (
|
||||
(theme === "default" ||
|
||||
theme === "light-blue" ||
|
||||
theme === "dark-blue") &&
|
||||
!blueThemesUnlocked
|
||||
);
|
||||
}
|
||||
|
||||
function updateThemeAvailability() {
|
||||
const blueThemesUnlocked =
|
||||
localStorage.getItem("blueThemesUnlocked") === "true";
|
||||
document.querySelectorAll(".theme-option").forEach((button) => {
|
||||
const theme = button.dataset.theme;
|
||||
if (
|
||||
theme === "default" ||
|
||||
theme === "light-blue" ||
|
||||
theme === "dark-blue"
|
||||
) {
|
||||
if (blueThemesUnlocked) {
|
||||
button.style.display = "block";
|
||||
button.classList.remove("disabled");
|
||||
button.removeAttribute("disabled");
|
||||
} else {
|
||||
button.style.display = "none";
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(";");
|
||||
|
||||
for (let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === " ") {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
function setCookie(name, value, days = 365) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
}
|
||||
|
||||
|
||||
function getCurrentTheme() {
|
||||
return localStorage.getItem('themePreference') ||
|
||||
getCookie('themePreference') ||
|
||||
'light-green';
|
||||
return (
|
||||
localStorage.getItem("themePreference") ||
|
||||
getCookie("themePreference") ||
|
||||
"light-green"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function updateThemeButtons(currentTheme) {
|
||||
document.querySelectorAll('.theme-option').forEach(button => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle('active', theme === currentTheme);
|
||||
});
|
||||
updateThemeAvailability();
|
||||
document.querySelectorAll(".theme-option").forEach((button) => {
|
||||
const theme = button.dataset.theme;
|
||||
button.classList.toggle("active", theme === currentTheme);
|
||||
});
|
||||
updateThemeAvailability();
|
||||
}
|
||||
|
||||
function getCurrentLanguage() {
|
||||
return localStorage.getItem('languagePreference') ||
|
||||
getCookie('languagePreference') ||
|
||||
'hu';
|
||||
return (
|
||||
localStorage.getItem("languagePreference") ||
|
||||
getCookie("languagePreference") ||
|
||||
"hu"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
function updateLanguageButtons(currentLanguage) {
|
||||
document.querySelectorAll('.language-option').forEach(button => {
|
||||
const language = button.dataset.language;
|
||||
button.classList.toggle('active', language === currentLanguage);
|
||||
});
|
||||
document.querySelectorAll(".language-option").forEach((button) => {
|
||||
const language = button.dataset.language;
|
||||
button.classList.toggle("active", language === currentLanguage);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function applyLanguage(language) {
|
||||
setCookie('languagePreference', language);
|
||||
localStorage.setItem('languagePreference', language);
|
||||
setCookie("languagePreference", language);
|
||||
localStorage.setItem("languagePreference", language);
|
||||
|
||||
updateLanguageButtons(language);
|
||||
updateLanguageButtons(language);
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach(tab => {
|
||||
chrome.tabs.sendMessage(tab.id, {
|
||||
action: 'changeLanguage',
|
||||
language: language
|
||||
}).catch(() => {
|
||||
});
|
||||
});
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach((tab) => {
|
||||
chrome.tabs
|
||||
.sendMessage(tab.id, {
|
||||
action: "changeLanguage",
|
||||
language: language,
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
async function applyTheme(theme) {
|
||||
setCookie('themePreference', theme);
|
||||
localStorage.setItem('themePreference', theme);
|
||||
|
||||
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
|
||||
updateThemeButtons(theme);
|
||||
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach(tab => {
|
||||
chrome.tabs.sendMessage(tab.id, {
|
||||
action: 'changeTheme',
|
||||
theme: theme
|
||||
}).catch(() => {
|
||||
});
|
||||
});
|
||||
setCookie("themePreference", theme);
|
||||
localStorage.setItem("themePreference", theme);
|
||||
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
|
||||
updateThemeButtons(theme);
|
||||
|
||||
const tabs = await chrome.tabs.query({});
|
||||
tabs.forEach((tab) => {
|
||||
chrome.tabs
|
||||
.sendMessage(tab.id, {
|
||||
action: "changeTheme",
|
||||
theme: theme,
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const themeButtons = document.querySelectorAll('.theme-option');
|
||||
themeButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const theme = button.dataset.theme;
|
||||
|
||||
|
||||
if (button.hasAttribute('disabled')) {
|
||||
alert(window.LanguageManager.t('common.warning') + ': ' + window.LanguageManager.t('settings.theme_not_available'));
|
||||
return;
|
||||
}
|
||||
|
||||
applyTheme(theme);
|
||||
});
|
||||
|
||||
const themeButtons = document.querySelectorAll(".theme-option");
|
||||
themeButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const theme = button.dataset.theme;
|
||||
|
||||
if (button.hasAttribute("disabled")) {
|
||||
alert(
|
||||
window.LanguageManager.t("common.warning") +
|
||||
": " +
|
||||
window.LanguageManager.t("settings.theme_not_available"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
applyTheme(theme);
|
||||
});
|
||||
});
|
||||
|
||||
const languageButtons = document.querySelectorAll('.language-option');
|
||||
languageButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
const language = button.dataset.language;
|
||||
applyLanguage(language);
|
||||
});
|
||||
|
||||
const languageButtons = document.querySelectorAll(".language-option");
|
||||
languageButtons.forEach((button) => {
|
||||
button.addEventListener("click", () => {
|
||||
const language = button.dataset.language;
|
||||
applyLanguage(language);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
let initialTheme = getCurrentTheme();
|
||||
|
||||
|
||||
|
||||
if (isThemeDisabled(initialTheme)) {
|
||||
initialTheme = 'light-green';
|
||||
initialTheme = "light-green";
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateThemeAvailability();
|
||||
await applyTheme(initialTheme);
|
||||
|
||||
|
||||
const initialLanguage = getCurrentLanguage();
|
||||
updateLanguageButtons(initialLanguage);
|
||||
|
||||
|
||||
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.action === 'themeChanged') {
|
||||
updateThemeButtons(message.theme);
|
||||
document.documentElement.setAttribute('data-theme', message.theme);
|
||||
}
|
||||
if (message.action === "themeChanged") {
|
||||
updateThemeButtons(message.theme);
|
||||
document.documentElement.setAttribute("data-theme", message.theme);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const versionElement = document.getElementById('version');
|
||||
const versionElement = document.getElementById("version");
|
||||
versionElement.textContent = `v${manifest.version}`;
|
||||
|
||||
|
||||
|
||||
let clickCount = 0;
|
||||
versionElement.addEventListener('click', () => {
|
||||
clickCount++;
|
||||
if (clickCount >= 5) {
|
||||
localStorage.setItem('blueThemesUnlocked', 'true');
|
||||
updateThemeAvailability();
|
||||
|
||||
|
||||
const notification = document.createElement('div');
|
||||
notification.style.cssText = `
|
||||
versionElement.addEventListener("click", () => {
|
||||
clickCount++;
|
||||
if (clickCount >= 5) {
|
||||
localStorage.setItem("blueThemesUnlocked", "true");
|
||||
updateThemeAvailability();
|
||||
|
||||
const notification = document.createElement("div");
|
||||
notification.style.cssText = `
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
@@ -189,54 +197,54 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
animation: slideIn 0.3s ease-out;
|
||||
`;
|
||||
notification.textContent = window.LanguageManager.t('common.success') + ': ' + window.LanguageManager.t('settings.blue_themes_unlocked');
|
||||
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.textContent = `
|
||||
notification.textContent =
|
||||
window.LanguageManager.t("common.success") +
|
||||
": " +
|
||||
window.LanguageManager.t("settings.blue_themes_unlocked");
|
||||
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
@keyframes slideIn {
|
||||
from { transform: translateX(100%); opacity: 0; }
|
||||
to { transform: translateX(0); opacity: 1; }
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
style.remove();
|
||||
}, 3000);
|
||||
|
||||
clickCount = 0;
|
||||
document.head.appendChild(style);
|
||||
|
||||
document.body.appendChild(notification);
|
||||
|
||||
setTimeout(() => {
|
||||
notification.remove();
|
||||
style.remove();
|
||||
}, 3000);
|
||||
|
||||
clickCount = 0;
|
||||
}
|
||||
});
|
||||
|
||||
themeButtons.forEach((button) => {
|
||||
button.addEventListener("mouseover", () => {
|
||||
if (!button.hasAttribute("disabled")) {
|
||||
button.style.transform = "translateY(-2px)";
|
||||
}
|
||||
});
|
||||
|
||||
button.addEventListener("mouseout", () => {
|
||||
button.style.transform = "translateY(0)";
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
themeButtons.forEach(button => {
|
||||
button.addEventListener('mouseover', () => {
|
||||
if (!button.hasAttribute('disabled')) {
|
||||
button.style.transform = 'translateY(-2px)';
|
||||
}
|
||||
});
|
||||
|
||||
button.addEventListener('mouseout', () => {
|
||||
button.style.transform = 'translateY(0)';
|
||||
});
|
||||
|
||||
languageButtons.forEach((button) => {
|
||||
button.addEventListener("mouseover", () => {
|
||||
button.style.transform = "translateY(-2px)";
|
||||
});
|
||||
|
||||
button.addEventListener("mouseout", () => {
|
||||
button.style.transform = "translateY(0)";
|
||||
});
|
||||
});
|
||||
|
||||
languageButtons.forEach(button => {
|
||||
button.addEventListener('mouseover', () => {
|
||||
button.style.transform = 'translateY(-2px)';
|
||||
});
|
||||
|
||||
button.addEventListener('mouseout', () => {
|
||||
button.style.transform = 'translateY(0)';
|
||||
});
|
||||
|
||||
window.addEventListener("languageChanged", (event) => {
|
||||
updateLanguageButtons(event.detail.language);
|
||||
});
|
||||
|
||||
window.addEventListener('languageChanged', (event) => {
|
||||
updateLanguageButtons(event.detail.language);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
106
tools/background.js
Normal file
@@ -0,0 +1,106 @@
|
||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
(async () => {
|
||||
try {
|
||||
switch (request.action) {
|
||||
case 'storage_set':
|
||||
await handleStorageSet(request.key, request.value);
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
case 'storage_get':
|
||||
const value = await handleStorageGet(request.key, request.defaultValue);
|
||||
sendResponse({ success: true, value: value });
|
||||
break;
|
||||
|
||||
case 'storage_remove':
|
||||
await handleStorageRemove(request.key);
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
case 'storage_clear':
|
||||
await handleStorageClear();
|
||||
sendResponse({ success: true });
|
||||
break;
|
||||
|
||||
default:
|
||||
console.warn('[Background] Unknown action:', request.action);
|
||||
sendResponse({ success: false, error: 'Unknown action' });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Error handling message:', error);
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
})();
|
||||
return true;
|
||||
});
|
||||
|
||||
async function handleStorageSet(key, value) {
|
||||
try {
|
||||
await chrome.storage.sync.set({ [key]: value });
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to save ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageGet(key, defaultValue = null) {
|
||||
try {
|
||||
const result = await chrome.storage.sync.get(key);
|
||||
const value = result[key];
|
||||
return value !== undefined ? value : defaultValue;
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to get ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageRemove(key) {
|
||||
try {
|
||||
await chrome.storage.sync.remove(key);
|
||||
} catch (error) {
|
||||
console.error(`[Background] Failed to remove ${key}:`, error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleStorageClear() {
|
||||
try {
|
||||
const allData = await chrome.storage.sync.get(null);
|
||||
const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
|
||||
|
||||
if (firkaKeys.length > 0) {
|
||||
await chrome.storage.sync.remove(firkaKeys);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Failed to clear storage:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
chrome.storage.onChanged.addListener((changes, namespace) => {
|
||||
if (namespace === 'sync') {
|
||||
const firkaChanges = Object.keys(changes).filter(key => key.startsWith('firka_'));
|
||||
if (firkaChanges.length > 0) {
|
||||
notifyContentScriptsOfChanges(changes);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function notifyContentScriptsOfChanges(changes) {
|
||||
try {
|
||||
const tabs = await chrome.tabs.query({ url: 'https://*.e-kreta.hu/*' });
|
||||
|
||||
for (const tab of tabs) {
|
||||
try {
|
||||
await chrome.tabs.sendMessage(tab.id, {
|
||||
action: 'storage_changed',
|
||||
changes: changes
|
||||
});
|
||||
} catch (error) {
|
||||
console.debug(`[Background] Could not notify tab ${tab.id}:`, error.message);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[Background] Failed to notify content scripts:', error);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
const cookieManager = {
|
||||
get(name) {
|
||||
const cookieName = `${name}=`;
|
||||
const decodedCookie = decodeURIComponent(document.cookie);
|
||||
const cookieArray = decodedCookie.split(';');
|
||||
|
||||
for(let i = 0; i < cookieArray.length; i++) {
|
||||
let cookie = cookieArray[i];
|
||||
while (cookie.charAt(0) === ' ') {
|
||||
cookie = cookie.substring(1);
|
||||
}
|
||||
if (cookie.indexOf(cookieName) === 0) {
|
||||
return cookie.substring(cookieName.length, cookie.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
set(name, value, days = 365) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
const expires = `expires=${date.toUTCString()}`;
|
||||
document.cookie = `${name}=${value}; ${expires}; path=/; domain=.e-kreta.hu`;
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,25 @@
|
||||
const createTemplate = {
|
||||
header() {
|
||||
const data = {
|
||||
schoolInfo: {
|
||||
name: cookieManager.get('schoolName') || 'Iskola',
|
||||
id: cookieManager.get('schoolCode') || ''
|
||||
},
|
||||
userData: {
|
||||
name: cookieManager.get('userName') || 'Felhasználó',
|
||||
time: document.querySelector('.usermenu_timer')?.textContent?.trim() || '45:00',
|
||||
email: cookieManager.get('userEmail') || ''
|
||||
}
|
||||
};
|
||||
async header() {
|
||||
const data = {
|
||||
schoolInfo: {
|
||||
name: await storageManager.get("schoolName", "OM azonosító - Iskola neve"),
|
||||
id: await storageManager.get("schoolCode", ""),
|
||||
},
|
||||
userData: {
|
||||
name: await storageManager.get("userName", "Felhasználónév"),
|
||||
time:
|
||||
document.querySelector(".usermenu_timer")?.textContent?.trim() ||
|
||||
"45:00",
|
||||
},
|
||||
};
|
||||
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = helper.shortenSchoolName(schoolNameFull);
|
||||
const schoolNameFull = `${data.schoolInfo.id} - ${data.schoolInfo.name}`;
|
||||
const shortenedSchoolName = helper.shortenSchoolName(schoolNameFull);
|
||||
|
||||
|
||||
|
||||
const element = `<header class="kreta-header">
|
||||
const element = `<header class="kreta-header">
|
||||
<div class="school-info">
|
||||
<p class="logo-text">
|
||||
<img src="${chrome.runtime.getURL('images/firka_logo.png')}" alt="Firka" class="logo">
|
||||
<img src="${chrome.runtime.getURL("images/firka_logo.png")}" alt="Firka" class="logo">
|
||||
Firka
|
||||
</p>
|
||||
<div class="school-details" title="${schoolNameFull}">
|
||||
@@ -28,7 +27,7 @@ const createTemplate = {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="nav-toggle" aria-label="${LanguageManager.t('navigation.nav_toggle')}">
|
||||
<button class="nav-toggle" aria-label="${LanguageManager.t("navigation.nav_toggle")}">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/>
|
||||
</svg>
|
||||
@@ -36,25 +35,25 @@ const createTemplate = {
|
||||
|
||||
<nav class="kreta-nav">
|
||||
<div class="nav-links">
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item ${( location.pathname == '/Intezmeny/Faliujsag' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/dashboard-' + ( location.pathname == '/Intezmeny/Faliujsag' ? 'active' : 'inactive') + '.svg')}" alt="${LanguageManager.t('navigation.dashboard')}">
|
||||
${LanguageManager.t('navigation.dashboard')}
|
||||
<a href="/Intezmeny/Faliujsag" data-page="dashboard" class="nav-item ${location.pathname == "/Intezmeny/Faliujsag" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/dashboard-" + (location.pathname == "/Intezmeny/Faliujsag" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.dashboard")}">
|
||||
${LanguageManager.t("navigation.dashboard")}
|
||||
</a>
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item ${( location.pathname == '/TanuloErtekeles/Osztalyzatok' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/grades-' + ( location.pathname == '/TanuloErtekeles/Osztalyzatok' ? 'active' : 'inactive') + '.svg')}" alt="${LanguageManager.t('navigation.grades')}">
|
||||
${LanguageManager.t('navigation.grades')}
|
||||
<a href="/TanuloErtekeles/Osztalyzatok" data-page="grades" class="nav-item ${location.pathname == "/TanuloErtekeles/Osztalyzatok" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/grades-" + (location.pathname == "/TanuloErtekeles/Osztalyzatok" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.grades")}">
|
||||
${LanguageManager.t("navigation.grades")}
|
||||
</a>
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item ${( location.pathname == '/Orarend/InformaciokOrarend' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/timetable-' + ( location.pathname == '/Orarend/InformaciokOrarend' ? 'active' : 'inactive') + '.svg')}" alt="${LanguageManager.t('navigation.timetable')}">
|
||||
${LanguageManager.t('navigation.timetable')}
|
||||
<a href="/Orarend/InformaciokOrarend" data-page="timetable" class="nav-item ${location.pathname == "/Orarend/InformaciokOrarend" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/timetable-" + (location.pathname == "/Orarend/InformaciokOrarend" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.timetable")}">
|
||||
${LanguageManager.t("navigation.timetable")}
|
||||
</a>
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item ${( location.pathname == '/Hianyzas/Hianyzasok' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/absences-' + ( location.pathname == '/Hianyzas/Hianyzasok' ? 'active' : 'inactive') + '.svg')}" alt="${LanguageManager.t('navigation.absences')}">
|
||||
${LanguageManager.t('navigation.absences')}
|
||||
<a href="/Hianyzas/Hianyzasok" data-page="absences" class="nav-item ${location.pathname == "/Hianyzas/Hianyzasok" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/absences-" + (location.pathname == "/Hianyzas/Hianyzasok" ? "active" : "inactive") + ".svg")}" alt="${LanguageManager.t("navigation.absences")}">
|
||||
${LanguageManager.t("navigation.absences")}
|
||||
</a>
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item ${( location.pathname == '/Tanulo/TanuloHaziFeladat' ? 'active' : '')}">
|
||||
<img src="${chrome.runtime.getURL('icons/others.svg')}" alt="${LanguageManager.t('navigation.other')}">
|
||||
${LanguageManager.t('navigation.other')}
|
||||
<a href="/Tanulo/TanuloHaziFeladat" data-page="other" class="nav-item ${location.pathname == "/Tanulo/TanuloHaziFeladat" ? "active" : ""}">
|
||||
<img src="${chrome.runtime.getURL("icons/others.svg")}" alt="${LanguageManager.t("navigation.other")}">
|
||||
${LanguageManager.t("navigation.other")}
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -68,73 +67,55 @@ const createTemplate = {
|
||||
</button>
|
||||
<div class="user-dropdown">
|
||||
<a href="https://bmszc-puskas.e-kreta.hu/Home/Uzenetek" data-page="messages" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL('icons/messages.svg')}" alt="${LanguageManager.t('navigation.messages')}">
|
||||
${LanguageManager.t('navigation.messages')}
|
||||
<img src="${chrome.runtime.getURL("icons/messages.svg")}" alt="${LanguageManager.t("navigation.messages")}">
|
||||
${LanguageManager.t("navigation.messages")}
|
||||
</a>
|
||||
<a href="/Adminisztracio/Profil" data-page="profile" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL('icons/profile.svg')}" alt="${LanguageManager.t('navigation.profile')}">
|
||||
${LanguageManager.t('navigation.profile')}
|
||||
<img src="${chrome.runtime.getURL("icons/profile.svg")}" alt="${LanguageManager.t("navigation.profile")}">
|
||||
${LanguageManager.t("navigation.profile")}
|
||||
</a>
|
||||
<a href="#" class="dropdown-item" id="settingsBtn">
|
||||
<img src="${chrome.runtime.getURL('icons/settings.svg')}" alt="${LanguageManager.t('navigation.settings')}">
|
||||
${LanguageManager.t('navigation.settings')}
|
||||
<img src="${chrome.runtime.getURL("icons/settings.svg")}" alt="${LanguageManager.t("navigation.settings")}">
|
||||
${LanguageManager.t("navigation.settings")}
|
||||
</a>
|
||||
<a href="/Home/Logout" data-page="logout" class="dropdown-item">
|
||||
<img src="${chrome.runtime.getURL('icons/logout.svg')}" alt="${LanguageManager.t('navigation.logout')}">
|
||||
${LanguageManager.t('navigation.logout')}
|
||||
<img src="${chrome.runtime.getURL("icons/logout.svg")}" alt="${LanguageManager.t("navigation.logout")}">
|
||||
${LanguageManager.t("navigation.logout")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>`
|
||||
</header>`;
|
||||
|
||||
const startTime = parseInt(data.userData.time?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
const timerEl = document.getElementById('logoutTimer');
|
||||
if (timerEl) {
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = '/Home/Logout';
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
const startTime = parseInt(data.userData.time?.match(/\d+/)?.[0] || "45");
|
||||
let timeLeft = startTime * 60;
|
||||
|
||||
setInterval(updateTimer, 1000);
|
||||
const updateTimer = () => {
|
||||
const minutes = Math.floor(timeLeft / 60);
|
||||
const seconds = timeLeft % 60;
|
||||
const timerEl = document.getElementById("logoutTimer");
|
||||
if (timerEl) {
|
||||
timerEl.textContent = `${minutes}:${seconds.toString().padStart(2, "0")}`;
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
if (timeLeft <= 0) {
|
||||
window.location.href = "/Home/Logout";
|
||||
} else {
|
||||
timeLeft--;
|
||||
}
|
||||
};
|
||||
|
||||
importFonts() {
|
||||
const links = [
|
||||
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
|
||||
{ rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: true },
|
||||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap' },
|
||||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap' },
|
||||
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons+Round' }
|
||||
];
|
||||
|
||||
links.forEach(link => {
|
||||
const linkElement = document.createElement('link');
|
||||
Object.entries(link).forEach(([key, value]) => {
|
||||
linkElement[key] = value;
|
||||
});
|
||||
document.head.appendChild(linkElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
setInterval(updateTimer, 1000);
|
||||
|
||||
return element;
|
||||
},
|
||||
};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
await helper.waitForElement('#settingsBtn');
|
||||
document.querySelector('#settingsBtn').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL('settings/index.html');
|
||||
window.open(url, '_blank', 'width=400,height=600');
|
||||
});
|
||||
});
|
||||
await helper.waitForElement("#settingsBtn");
|
||||
document.querySelector("#settingsBtn").addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const url = chrome.runtime.getURL("settings/index.html");
|
||||
window.open(url, "_blank", "width=400,height=600");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +1,40 @@
|
||||
const helper = {
|
||||
shortenSchoolName(name, maxLength = 50) {
|
||||
if (!name) return '';
|
||||
if (name.length <= maxLength) return name;
|
||||
|
||||
const parts = name.split(' - ');
|
||||
if (parts.length === 2) {
|
||||
const [code, fullName] = parts;
|
||||
if (fullName.length > maxLength - code.length - 3) {
|
||||
return `${code} - ${fullName.substring(0, maxLength - code.length - 6)}...`;
|
||||
}
|
||||
}
|
||||
return name.substring(0, maxLength - 3) + '...';
|
||||
},
|
||||
|
||||
async waitForElement(selector) {
|
||||
return new Promise(resolve => {
|
||||
if (document.querySelector(selector)) {
|
||||
return resolve(document.querySelector(selector));
|
||||
}
|
||||
shortenSchoolName(name, maxLength = 50) {
|
||||
if (!name) return "";
|
||||
if (name.length <= maxLength) return name;
|
||||
|
||||
const observer = new MutationObserver(mutations => {
|
||||
if (document.querySelector(selector)) {
|
||||
observer.disconnect();
|
||||
resolve(document.querySelector(selector));
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
convertTimeToMinutes(timeStr) {
|
||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||||
return hours * 60 + minutes;
|
||||
const parts = name.split(" - ");
|
||||
if (parts.length === 2) {
|
||||
const [code, fullName] = parts;
|
||||
if (fullName.length > maxLength - code.length - 3) {
|
||||
return `${code} - ${fullName.substring(0, maxLength - code.length - 6)}...`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return name.substring(0, maxLength - 3) + "...";
|
||||
},
|
||||
|
||||
async waitForElement(selector) {
|
||||
return new Promise((resolve) => {
|
||||
if (document.querySelector(selector)) {
|
||||
return resolve(document.querySelector(selector));
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
if (document.querySelector(selector)) {
|
||||
observer.disconnect();
|
||||
resolve(document.querySelector(selector));
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
convertTimeToMinutes(timeStr) {
|
||||
const [hours, minutes] = timeStr.split(":").map(Number);
|
||||
return hours * 60 + minutes;
|
||||
},
|
||||
};
|
||||
@@ -1,59 +1,53 @@
|
||||
.modalBckgroundMain {
|
||||
display: none !important;
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
body:not(.loaded) {
|
||||
opacity: 0 !important;
|
||||
visibility: hidden !important;
|
||||
height: 100vh !important;
|
||||
overflow: hidden !important;
|
||||
opacity:0 !important;
|
||||
visibility:hidden !important;
|
||||
height:100vh !important;
|
||||
overflow:hidden !important;
|
||||
}
|
||||
|
||||
.loading-screen {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: var(--background);
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: opacity 0.3s ease;
|
||||
position:fixed;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100vw;
|
||||
height:100vh;
|
||||
background-color:var(--background);
|
||||
z-index:9999;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
transition:opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap:1rem;
|
||||
}
|
||||
|
||||
.loading-logo {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
width:48px;
|
||||
height:48px;
|
||||
border-radius:16px;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
font-family: Montserrat;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
line-height: normal;
|
||||
color:var(--text-primary);
|
||||
text-align:center;
|
||||
font-family:Montserrat;
|
||||
font-size:20px;
|
||||
font-style:normal;
|
||||
font-weight:700;
|
||||
line-height:normal;
|
||||
}
|
||||
|
||||
.loading-text2 {
|
||||
align-self: stretch;
|
||||
color: var(--text-secondary);
|
||||
text-align: center;
|
||||
font-family: Figtree;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 130%;
|
||||
align-self:stretch;
|
||||
color:var(--text-secondary);
|
||||
text-align:center;
|
||||
font-family:Figtree;
|
||||
font-size:16px;
|
||||
font-style:normal;
|
||||
font-weight:500;
|
||||
line-height:130%;
|
||||
}
|
||||
|
||||
@@ -1,53 +1,77 @@
|
||||
const loadingScreen = {
|
||||
show() {
|
||||
document.body.classList.remove('loaded');
|
||||
const existingLoadingScreen = document.querySelector('.loading-screen');
|
||||
if (existingLoadingScreen) return;
|
||||
show() {
|
||||
document.body.classList.remove("loaded");
|
||||
const existingLoadingScreen = document.querySelector(".loading-screen");
|
||||
if (existingLoadingScreen) return;
|
||||
|
||||
const loadingScreen = document.createElement('div');
|
||||
loadingScreen.className = 'loading-screen';
|
||||
loadingScreen.innerHTML = `
|
||||
<div class="loading-content">
|
||||
<img src="${chrome.runtime.getURL('images/loading.gif')}" alt="Firka" class="loading-logo">
|
||||
<div class="loading-text" data-i18n="loading.text">Betöltés alatt...</div>
|
||||
<div class="loading-text2" data-i18n="loading.subtext">Kis türelmet!</div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(loadingScreen);
|
||||
document.body.classList.add('loaded');
|
||||
},
|
||||
const loadingScreen = document.createElement("div");
|
||||
loadingScreen.className = "loading-screen";
|
||||
|
||||
const loadingContent = document.createElement('div');
|
||||
loadingContent.className = 'loading-content';
|
||||
|
||||
const loadingLogo = document.createElement('img');
|
||||
loadingLogo.src = chrome.runtime.getURL("images/loading.gif");
|
||||
loadingLogo.alt = 'Firka';
|
||||
loadingLogo.className = 'loading-logo';
|
||||
|
||||
const loadingText = document.createElement('div');
|
||||
loadingText.className = 'loading-text';
|
||||
loadingText.setAttribute('data-i18n', 'loading.text');
|
||||
loadingText.textContent = 'Betöltés alatt...';
|
||||
|
||||
const loadingText2 = document.createElement('div');
|
||||
loadingText2.className = 'loading-text2';
|
||||
loadingText2.setAttribute('data-i18n', 'loading.subtext');
|
||||
loadingText2.textContent = 'Kis türelmet!';
|
||||
|
||||
loadingContent.appendChild(loadingLogo);
|
||||
loadingContent.appendChild(loadingText);
|
||||
loadingContent.appendChild(loadingText2);
|
||||
loadingScreen.appendChild(loadingContent);
|
||||
document.body.appendChild(loadingScreen);
|
||||
document.body.classList.add("loaded");
|
||||
},
|
||||
|
||||
hide() {
|
||||
document.body.classList.add('loaded');
|
||||
const loadingScreen = document.querySelector('.loading-screen');
|
||||
if (loadingScreen) {
|
||||
loadingScreen.style.opacity = '0';
|
||||
hide() {
|
||||
document.body.classList.add("loaded");
|
||||
const loadingScreen = document.querySelector(".loading-screen");
|
||||
if (loadingScreen) {
|
||||
loadingScreen.style.opacity = "0";
|
||||
|
||||
const removeLoadingScreen = () => {
|
||||
if (loadingScreen && loadingScreen.parentNode) {
|
||||
loadingScreen.remove();
|
||||
}
|
||||
};
|
||||
|
||||
loadingScreen.addEventListener('transitionend', removeLoadingScreen, { once: true });
|
||||
setTimeout(removeLoadingScreen, 500);
|
||||
const removeLoadingScreen = () => {
|
||||
if (loadingScreen && loadingScreen.parentNode) {
|
||||
loadingScreen.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('DOMContentLoaded', () => {
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const urls = [];
|
||||
|
||||
if (manifest.content_scripts) {
|
||||
manifest.content_scripts.forEach(script => {
|
||||
if (script.matches) {
|
||||
urls.push(...script.matches);
|
||||
}
|
||||
});
|
||||
loadingScreen.addEventListener("transitionend", removeLoadingScreen, {
|
||||
once: true,
|
||||
});
|
||||
setTimeout(removeLoadingScreen, 500);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (urls.some(url => url.includes(location.pathname))) {
|
||||
loadingScreen.show();
|
||||
}
|
||||
});
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const manifest = chrome.runtime.getManifest();
|
||||
const urls = [];
|
||||
|
||||
if (manifest.content_scripts) {
|
||||
manifest.content_scripts.forEach((script) => {
|
||||
if (script.matches) {
|
||||
urls.push(...script.matches);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const currentUrl = location.href;
|
||||
const shouldShowLoading = urls.some((urlPattern) => {
|
||||
const regex = new RegExp(urlPattern.replace(/\*/g, '.*'));
|
||||
return regex.test(currentUrl);
|
||||
});
|
||||
|
||||
if (shouldShowLoading) {
|
||||
loadingScreen.show();
|
||||
}
|
||||
});
|
||||
|
||||
193
tools/storageManager.js
Normal file
@@ -0,0 +1,193 @@
|
||||
const storageManager = {
|
||||
isExtensionContext() {
|
||||
return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.id;
|
||||
},
|
||||
|
||||
isContentScript() {
|
||||
return typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.sendMessage;
|
||||
},
|
||||
|
||||
async set(key, value) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
await chrome.storage.sync.set({ [prefixedKey]: value });
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_set',
|
||||
key: prefixedKey,
|
||||
value: value
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to save via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
localStorage.setItem(prefixedKey, JSON.stringify(value));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Primary storage failed for ${key}, falling back to cookie:`, error);
|
||||
if (typeof cookieManager !== 'undefined') {
|
||||
cookieManager.set(prefixedKey, JSON.stringify(value));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async get(key, defaultValue = null) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
const result = await chrome.storage.sync.get(prefixedKey);
|
||||
const value = result[prefixedKey];
|
||||
return value !== undefined ? value : defaultValue;
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_get',
|
||||
key: prefixedKey,
|
||||
defaultValue: defaultValue
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.hasOwnProperty('value')) {
|
||||
resolve(response.value);
|
||||
} else {
|
||||
reject(new Error('Failed to get via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const value = localStorage.getItem(prefixedKey);
|
||||
if (value !== null) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Primary storage failed for ${key}, falling back to cookie:`, error);
|
||||
if (typeof cookieManager !== 'undefined') {
|
||||
const cookieValue = cookieManager.get(prefixedKey);
|
||||
if (cookieValue) {
|
||||
try {
|
||||
return JSON.parse(cookieValue);
|
||||
} catch (parseError) {
|
||||
return cookieValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
},
|
||||
|
||||
async remove(key) {
|
||||
const prefixedKey = `firka_${key}`;
|
||||
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
await chrome.storage.sync.remove(prefixedKey);
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_remove',
|
||||
key: prefixedKey
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to remove via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
localStorage.removeItem(prefixedKey);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Failed to remove ${key}:`, error);
|
||||
}
|
||||
},
|
||||
|
||||
async clear() {
|
||||
try {
|
||||
if (this.isExtensionContext()) {
|
||||
const allData = await chrome.storage.sync.get(null);
|
||||
const firkaKeys = Object.keys(allData).filter(key => key.startsWith('firka_'));
|
||||
if (firkaKeys.length > 0) {
|
||||
await chrome.storage.sync.remove(firkaKeys);
|
||||
}
|
||||
} else if (this.isContentScript()) {
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage({
|
||||
action: 'storage_clear'
|
||||
}, (response) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError);
|
||||
} else if (response && response.success) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error('Failed to clear via message passing'));
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const keysToRemove = [];
|
||||
for (let i = 0; i < localStorage.length; i++) {
|
||||
const key = localStorage.key(i);
|
||||
if (key && key.startsWith('firka_')) {
|
||||
keysToRemove.push(key);
|
||||
}
|
||||
}
|
||||
keysToRemove.forEach(key => localStorage.removeItem(key));
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[StorageManager] Failed to clear storage:', error);
|
||||
}
|
||||
},
|
||||
|
||||
async migrateFromCookies() {
|
||||
if (typeof cookieManager === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
const knownSettings = [
|
||||
'theme', 'language', 'notifications', 'autoRefresh',
|
||||
'compactMode', 'showGrades', 'showAbsences'
|
||||
];
|
||||
|
||||
let migratedCount = 0;
|
||||
|
||||
for (const setting of knownSettings) {
|
||||
try {
|
||||
const cookieValue = cookieManager.get(`firka_${setting}`);
|
||||
if (cookieValue !== null) {
|
||||
let value;
|
||||
try {
|
||||
value = JSON.parse(cookieValue);
|
||||
} catch {
|
||||
value = cookieValue;
|
||||
}
|
||||
|
||||
await this.set(setting, value);
|
||||
migratedCount++;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`[StorageManager] Failed to migrate ${setting}:`, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof document !== 'undefined') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
storageManager.migrateFromCookies().catch(console.error);
|
||||
});
|
||||
}
|
||||