Widget:UPDEvents: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 1: | Line 1: | ||
<includeonly> | <includeonly> | ||
<div id="upd-events-widget"> | <div id="upd-events-widget" class="upd-events-widget"> | ||
<div class="upd-events-loading">Loading upcoming events...</div> | <div class="upd-events-loading">Loading upcoming events...</div> | ||
<ul class="upd-events-list" style="display:none;"></ul> | <ul class="upd-events-list" style="display:none;"></ul> | ||
</div> | </div> | ||
<style> | |||
.upd-events-widget { | |||
color: #000; | |||
font-size: 15px; | |||
} | |||
.upd-events-list { | |||
list-style: none; | |||
padding: 0; | |||
margin: 0; | |||
} | |||
.upd-events-list li { | |||
margin: 0; | |||
padding: 10px 0; | |||
border-bottom: 1px solid #e5e5e5; | |||
} | |||
.upd-events-list li:last-child { | |||
border-bottom: none; | |||
} | |||
.upd-events-list a { | |||
color: #0E6021 !important; | |||
text-decoration: none; | |||
font-weight: 600; | |||
} | |||
.upd-events-list a:hover { | |||
text-decoration: underline; | |||
} | |||
.upd-events-loading, | |||
.upd-events-empty { | |||
color: #555; | |||
font-size: 14px; | |||
} | |||
</style> | |||
<script> | <script> | ||
| Line 12: | Line 45: | ||
var loading = container.querySelector('.upd-events-loading'); | var loading = container.querySelector('.upd-events-loading'); | ||
var | var list = container.querySelector('.upd-events-list'); | ||
var endpoint = new URL( | |||
'https://upd.edu.ph/wp-admin/admin-ajax.php' | |||
); | |||
var params = { | |||
action: 'search_events', | |||
id: '1', | |||
scope: 'future', | |||
orderby: 'event_start_date,event_start_time,event_name', | |||
view: 'list-grouped', | |||
pno: '1' | |||
}; | |||
Object.keys(params).forEach(function (key) { | |||
endpoint.searchParams.set(key, params[key]); | |||
}); | |||
fetch(endpoint.toString(), { | |||
method: 'GET', | |||
mode: 'cors', | |||
credentials: 'omit' | |||
}) | |||
.then(function (response) { | |||
if (!response.ok) { | |||
throw new Error('HTTP ' + response.status); | |||
} | |||
return response.text(); | |||
}) | |||
.then(function (html) { | |||
var doc = new DOMParser().parseFromString(html, 'text/html'); | |||
var anchors = doc.querySelectorAll( | |||
'#em-events-list-grouped-1 a[href*="/events/"], ' + | |||
'.em-events-list a[href*="/events/"]' | |||
); | |||
var seen = new Set(); | |||
var events = []; | |||
anchors.forEach(function (anchor) { | |||
. | var heading = anchor.querySelector('h4'); | ||
if (! | if (!heading) return; | ||
var title = heading.textContent.trim(); | |||
var url; | |||
try { | |||
url = new URL(anchor.getAttribute('href'), 'https://upd.edu.ph').href; | |||
} catch (e) { | |||
return; | |||
} | } | ||
if (!title || seen.has(url)) return; | |||
if (!/^https:\/\/upd\.edu\.ph\/events\//i.test(url)) return; | |||
seen.add(url); | |||
events.push({ title: title, url: url }); | |||
}); | }); | ||
list.replaceChildren(); | |||
events.slice(0, 5).forEach(function (event) { | |||
var li = document.createElement('li'); | |||
var a = document.createElement('a'); | |||
a.href = event.url; | |||
a.textContent = event.title; | |||
a.target = '_blank'; | |||
a.rel = 'noopener noreferrer'; | |||
li.appendChild(a); | |||
list.appendChild(li); | |||
}); | |||
loading.style.display = 'none'; | |||
if (events.length === 0) { | |||
var empty = document.createElement('div'); | |||
empty.className = 'upd-events-empty'; | |||
empty.textContent = 'No upcoming events were found.'; | |||
container.appendChild(empty); | |||
return; | |||
} | |||
list.style.display = 'block'; | |||
}) | |||
.catch(function (error) { | |||
console.error('UPEvents widget error:', error); | |||
loading.textContent = | |||
'Unable to load events automatically. Visit the '; | |||
var link = document.createElement('a'); | |||
link.href = 'https://upd.edu.ph/events-list/'; | |||
link.textContent = 'UP Diliman Events List'; | |||
link.target = '_blank'; | |||
link.rel = 'noopener noreferrer'; | |||
loading.appendChild(link); | |||
loading.appendChild(document.createTextNode(' for current listings.')); | |||
}); | |||
})(); | })(); | ||
</script> | </script> | ||
</includeonly> | </includeonly> | ||