You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.5 KiB
JavaScript

export default {
setup() {
const { ref, computed } = Vue;
const columns = ["title", "overview", "categories", "date"];
const loaded = ref(false);
const currentPage = ref("");
const pads = ref([]);
const currentSort = ref("date");
const currentSortDir = ref("desc");
const categories = ref([]);
const selected = ref(new Set());
const toggle = function (tag) {
selected.value.has(tag) ? selected.value.delete(tag) : selected.value.add(tag);
};
fetch("api")
.then((res) => res.json())
.then((data) => {
pads.value = data.pads;
pads.value.map(
(pad) =>
(pad.categories = pad.categories
.split(",")
.map((category) => category.trim()))
);
categories.value = Array.from(
new Set([...pads.value.map((pad) => pad.categories)].flat())
).sort();
currentPage.value = data.page;
loaded.value = true;
});
const sortedPads = computed(() => {
return filteredPads.value.sort((a, b) => {
let modifier = 1;
if (currentSortDir.value === "desc") modifier = -1;
if (currentSort.value === "date") {
a[currentSort.value] = new Date(a[currentSort.value]);
b[currentSort.value] = new Date(b[currentSort.value]);
}
if (a[currentSort.value] < b[currentSort.value]) return -1 * modifier;
if (a[currentSort.value] > b[currentSort.value]) return 1 * modifier;
return 0;
});
});
const sort = function (s) {
if (s == currentSort.value) {
currentSortDir.value = currentSortDir.value === "asc" ? "desc" : "asc";
}
currentSort.value = s;
};
const filteredPads = computed(() => {
if (selected.value.size == 0) return pads.value;
else
return pads.value.filter((pad) => {
return pad.categories.some((category) => selected.value.has(category));
});
});
const formatDate = function (date) {
return `${String(date.getDate()).padStart(2, "0")}-${String(
date.getMonth() + 1
).padStart(2, "0")}-${date.getFullYear()}`;
};
return {
pads,
columns,
currentPage,
loaded,
filteredPads,
categories,
selected,
sortedPads,
currentSort,
currentSortDir,
toggle,
sort,
formatDate,
};
},
template: `
<div v-if="!loaded" class='loading grow'>
Loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading loading etc
</div>
<div v-else>
<div class="filter">
<h2>Filter Categories</h2>
<ul>
<li :class="{active: selected.size == 0}" @click="selected.clear()">All</li>
<li v-for="tag in categories" :key="tag" @click="toggle(tag)" :class="{active: selected.has(tag)}">{{tag}}</li>
</ul>
</div>
<p class="from">
Fetching pads from
<a :href="'https://pzwiki.wdka.nl/mediadesign/' + currentPage">{{currentPage}}</a>
</p>
<table>
<tr class="header">
<th v-for="column in columns" :class="column" @click='sort(column)'>
{{column }}
<span v-if='column == currentSort'> {{ currentSortDir == 'asc' ? '▼' : '▲'}}</span>
</th>
</tr>
<tr v-for="(pad, index) in sortedPads" key="pad.title, index" :class="pad.category">
<td class="title">
<a :href="pad.link" class='stretched' target="_blank"> {{pad.title}} </a>
</td>
<td class="overview">
<p>
{{pad.overview}}
</p>
</td>
<td class="categories">
<span class="category" v-for="category in pad.categories" :key="category">{{category}}</span>
</td>
<td class="date">{{formatDate(pad.date)}}</td>
</tr>
</table>
</div>
`,
};