msos/student-guide.js

191 lines
15 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ==========================================================================
Student Welcome Guide — "Build my route"
Client-side personalised checklist for the guide landing page.
The landing page sets <div class="guide-route" data-lang="en|si|mk">.
Links point to sibling guide pages (../<slug>/) and only reference pages
that exist, so there are no dead links.
========================================================================== */
(function () {
var root = document.querySelector('.guide-route');
if (!root) return;
var lang = root.getAttribute('data-lang') || 'en';
// Slugs of pages that exist and are safe to link to.
var S = {
journey: 'complete-student-journey',
bachelor: 'bachelor-application',
master: 'master-application',
deadlines: 'application-deadlines',
evs: 'evs-application-guide'
};
var T = {
en: {
heading: 'Build my route',
sub: 'Answer a few questions and we will outline your next steps.',
build: 'Show my route',
reset: 'Reset',
need: 'Please choose at least your level and your current stage.',
resultHead: 'Your route',
contextParts: { level: 'Level', phase: 'Stage', uni: 'Institution', city: 'City', year: 'Academic year' },
fields: {
level: 'Level of study', phase: 'Where are you now?', uni: 'University', city: 'Study city', year: 'Academic year'
},
pick: 'Select',
levels: { bachelor: 'Bachelor', master: 'Master' },
phases: { exploring: 'I am exploring', applying: 'I am applying', accepted: 'I have been accepted', moving: 'I am preparing to move', arrived: 'I am already in Slovenia' },
unis: { ul: 'University of Ljubljana', um: 'University of Maribor', up: 'University of Primorska', ung: 'University of Nova Gorica', other: 'Another institution' },
cities: { ljubljana: 'Ljubljana', maribor: 'Maribor', koper: 'Koper', 'nova-gorica': 'Nova Gorica', celje: 'Celje', other: 'Another city' },
yourUni: 'your chosen university', yourCity: 'your study city',
link: { journey: 'the full journey', bachelor: 'the bachelor application', master: 'the master application', deadlines: 'current deadlines', evs: 'the eVŠ guide' }
},
si: {
heading: 'Ustvari mojo pot',
sub: 'Odgovorite na nekaj vprašanj in orisali bomo vaše naslednje korake.',
build: 'Prikaži mojo pot',
reset: 'Ponastavi',
need: 'Izberite vsaj stopnjo študija in vašo trenutno fazo.',
resultHead: 'Vaša pot',
contextParts: { level: 'Stopnja', phase: 'Faza', uni: 'Institucija', city: 'Mesto', year: 'Študijsko leto' },
fields: {
level: 'Stopnja študija', phase: 'Kje ste zdaj?', uni: 'Univerza', city: 'Študijsko mesto', year: 'Študijsko leto'
},
pick: 'Izberite',
levels: { bachelor: 'Dodiplomski', master: 'Magistrski' },
phases: { exploring: 'Šele raziskujem', applying: 'Prijavljam se', accepted: 'Sprejet sem', moving: 'Pripravljam se na selitev', arrived: 'Sem že v Sloveniji' },
unis: { ul: 'Univerza v Ljubljani', um: 'Univerza v Mariboru', up: 'Univerza na Primorskem', ung: 'Univerza v Novi Gorici', other: 'Druga ustanova' },
cities: { ljubljana: 'Ljubljana', maribor: 'Maribor', koper: 'Koper', 'nova-gorica': 'Nova Gorica', celje: 'Celje', other: 'Drugo mesto' },
yourUni: 'izbrano univerzo', yourCity: 'vaše študijsko mesto',
link: { journey: 'celotno pot', bachelor: 'prijavo na dodiplomski študij', master: 'prijavo na magistrski študij', deadlines: 'trenutne roke', evs: 'navodila za eVŠ' }
},
mk: {
heading: 'Создади го мојот пат',
sub: 'Одговорете на неколку прашања и ќе ги оцртаме вашите следни чекори.',
build: 'Прикажи го мојот пат',
reset: 'Ресетирај',
need: 'Изберете барем степен на студии и вашата тековна фаза.',
resultHead: 'Вашиот пат',
contextParts: { level: 'Степен', phase: 'Фаза', uni: 'Институција', city: 'Град', year: 'Академска година' },
fields: {
level: 'Степен на студии', phase: 'Каде сте сега?', uni: 'Универзитет', city: 'Град на студирање', year: 'Академска година'
},
pick: 'Изберете',
levels: { bachelor: 'Додипломски', master: 'Магистерски' },
phases: { exploring: 'Сè уште истражувам', applying: 'Се пријавувам', accepted: 'Примен сум', moving: 'Се подготвувам за преселба', arrived: 'Веќе сум во Словенија' },
unis: { ul: 'Универзитет во Љубљана', um: 'Универзитет во Марибор', up: 'Универзитет на Приморска', ung: 'Универзитет во Нова Горица', other: 'Друга институција' },
cities: { ljubljana: 'Љубљана', maribor: 'Марибор', koper: 'Копер', 'nova-gorica': 'Нова Горица', celje: 'Целје', other: 'Друг град' },
yourUni: 'избраниот универзитет', yourCity: 'вашиот град на студирање',
link: { journey: 'целосниот пат', bachelor: 'пријавата за додипломски', master: 'пријавата за магистерски', deadlines: 'тековните рокови', evs: 'водичот за eVŠ' }
}
};
// Step templates per phase. {uni}/{city} are interpolated; `link` is a key of S (or null).
// Each step text is provided per language.
var STEPS = {
exploring: [
{ link: 'journey', en: 'Compare programmes and universities before you settle on a city.', si: 'Primerjajte programe in univerze, preden se odločite za mesto.', mk: 'Споредете програми и универзитети пред да се одлучите за град.' },
{ link: 'deadlines', en: 'Check the current application deadlines for {uni}.', si: 'Preverite trenutne prijavne roke za {uni}.', mk: 'Проверете ги тековните рокови за пријавување за {uni}.' },
{ link: '{levelPage}', en: 'Read the {levelWord} application overview.', si: 'Preberite pregled prijave na {levelWord} študij.', mk: 'Прочитајте го прегледот за пријавување на {levelWord} студии.' },
{ link: null, en: 'Confirm whether any special-status exception applies to you before you rely on the standard pathway.', si: 'Preverite, ali za vas velja katera od izjem s posebnim statusom, preden se zanesete na običajno pot.', mk: 'Потврдете дали за вас важи некој исклучок со посебен статус пред да се потпрете на стандардниот пат.' }
],
applying: [
{ link: '{levelPage}', en: 'Prepare your document package for {uni}.', si: 'Pripravite paket dokumentov za {uni}.', mk: 'Подгответе го пакетот документи за {uni}.' },
{ link: 'evs', en: 'Submit your application through eVŠ and save the confirmation.', si: 'Oddajte prijavo prek eVŠ in shranite potrdilo.', mk: 'Поднесете ја пријавата преку eVŠ и зачувајте ја потврдата.' },
{ link: 'journey', en: 'Start recognition of your foreign education inside the application.', si: 'Znotraj prijave začnite postopek priznavanja tujega izobraževanja.', mk: 'Во рамките на пријавата започнете го признавањето на странското образование.' },
{ link: 'deadlines', en: 'Track the document deadline and result date for {uni}.', si: 'Spremljajte rok za dokumente in datum rezultatov za {uni}.', mk: 'Следете го рокот за документи и датумот на резултати за {uni}.' }
],
accepted: [
{ link: 'journey', en: 'Read the faculty enrolment instructions and complete your enrolment.', si: 'Preberite navodila fakultete za vpis in dokončajte vpis.', mk: 'Прочитајте ги упатствата на факултетот за упис и завршете го уписот.' },
{ link: null, en: 'Request your certificate of enrolment (potrdilo o vpisu).', si: 'Zaprosite za potrdilo o vpisu.', mk: 'Побарајте потврда за упис (potrdilo o vpisu).' },
{ link: 'journey', en: 'Begin residence, health (RM/SI 3), and housing steps in parallel.', si: 'Vzporedno začnite urejati prebivanje, zdravstvo (RM/SI 3) in nastanitev.', mk: 'Паралелно започнете ги чекорите за престој, здравство (RM/SI 3) и сместување.' },
{ link: null, en: 'Arrange accommodation in {city} as early as possible.', si: 'Čim prej uredite nastanitev v mestu {city}.', mk: 'Средете сместување во {city} што е можно поскоро.' }
],
moving: [
{ link: 'journey', en: 'Arrange your temporary residence permit for study before or on arrival.', si: 'Uredite dovoljenje za začasno prebivanje za študij pred prihodom ali ob njem.', mk: 'Средете дозвола за привремен престој за студии пред или при пристигнувањето.' },
{ link: null, en: 'Obtain the Macedonian RM/SI 3 health-insurance form where eligible.', si: 'Pridobite makedonski obrazec RM/SI 3 za zdravstveno zavarovanje, če ste upravičeni.', mk: 'Обезбедете го македонскиот образец РМ/СИ 3 за здравствено осигурување ако имате право.' },
{ link: null, en: 'Organise accommodation and plan address registration in {city}.', si: 'Uredite nastanitev in načrtujte prijavo prebivališča v mestu {city}.', mk: 'Организирајте сместување и планирајте пријава на адреса во {city}.' },
{ link: 'journey', en: 'Pack originals of your education and residence documents in hand luggage.', si: 'V ročno prtljago spravite izvirnike izobraževalnih in bivalnih dokumentov.', mk: 'Спакувајте ги оригиналите од образовните и документите за престој во рачен багаж.' }
],
arrived: [
{ link: null, en: 'Register your address at the administrative unit within the deadline.', si: 'V roku prijavite prebivališče na upravni enoti.', mk: 'Пријавете ја адресата во управната единица во рокот.' },
{ link: null, en: 'Submit RM/SI 3 to ZZZS and activate your health insurance.', si: 'Oddajte RM/SI 3 na ZZZS in aktivirajte zdravstveno zavarovanje.', mk: 'Поднесете РМ/СИ 3 до ЗЗЗС и активирајте го здравственото осигурување.' },
{ link: null, en: 'Activate student meals and student transport in {city}.', si: 'Aktivirajte študentsko prehrano in študentski prevoz v mestu {city}.', mk: 'Активирајте студентска исхрана и студентски превоз во {city}.' },
{ link: 'journey', en: 'Track your residence and insurance expiry dates through the year.', si: 'Skozi leto spremljajte datume poteka prebivanja in zavarovanja.', mk: 'Во текот на годината следете ги датумите на истекување на престојот и осигурувањето.' }
]
};
var t = T[lang] || T.en;
function opt(value, label) {
var o = document.createElement('option');
o.value = value; o.textContent = label; return o;
}
function fillSelect(sel, obj, withPick) {
if (withPick) sel.appendChild(opt('', t.pick + '…'));
Object.keys(obj).forEach(function (k) { sel.appendChild(opt(k, obj[k])); });
}
var selLevel = root.querySelector('[data-role="level"]');
var selPhase = root.querySelector('[data-role="phase"]');
var selUni = root.querySelector('[data-role="uni"]');
var selCity = root.querySelector('[data-role="city"]');
var selYear = root.querySelector('[data-role="year"]');
var result = root.querySelector('.guide-route-result');
fillSelect(selLevel, t.levels, true);
fillSelect(selPhase, t.phases, true);
fillSelect(selUni, t.unis, true);
fillSelect(selCity, t.cities, true);
[ '2026/2027', '2027/2028' ].forEach(function (y) { selYear.appendChild(opt(y, y)); });
function esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
function build() {
var level = selLevel.value, phase = selPhase.value;
if (!level || !phase) {
result.hidden = false;
result.innerHTML = '<p class="guide-route-context">' + esc(t.need) + '</p>';
return;
}
var uniText = selUni.value ? t.unis[selUni.value] : t.yourUni;
var cityText = selCity.value ? t.cities[selCity.value] : t.yourCity;
var levelWord = t.levels[level].toLowerCase();
var levelPage = level === 'master' ? S.master : S.bachelor;
var ctx = [];
ctx.push(t.contextParts.level + ': ' + t.levels[level]);
ctx.push(t.contextParts.phase + ': ' + t.phases[phase]);
if (selUni.value) ctx.push(t.contextParts.uni + ': ' + t.unis[selUni.value]);
if (selCity.value) ctx.push(t.contextParts.city + ': ' + t.cities[selCity.value]);
if (selYear.value) ctx.push(t.contextParts.year + ': ' + selYear.value);
var items = STEPS[phase].map(function (step) {
var text = step[lang] || step.en;
text = text.replace('{uni}', uniText).replace('{city}', cityText).replace('{levelWord}', levelWord);
var linkKey = step.link;
if (linkKey === '{levelPage}') linkKey = level === 'master' ? 'master' : 'bachelor';
var slug = linkKey && S[linkKey];
var li = esc(text);
if (slug) {
var label = t.link[linkKey] || linkKey;
li += ' <a href="' + slug + '/">' + esc(label) + ' →</a>';
}
return '<li>' + li + '</li>';
}).join('');
result.hidden = false;
result.innerHTML =
'<h3>' + esc(t.resultHead) + '</h3>' +
'<p class="guide-route-context">' + esc(ctx.join(' · ')) + '</p>' +
'<ol>' + items + '</ol>';
result.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
root.querySelector('[data-action="build"]').addEventListener('click', build);
root.querySelector('[data-action="reset"]').addEventListener('click', function () {
[selLevel, selPhase, selUni, selCity].forEach(function (s) { s.value = ''; });
selYear.value = '2026/2027';
result.hidden = true; result.innerHTML = '';
});
})();