@@ -10,7 +10,16 @@ import { Image } from "astro:assets";
10
10
11
11
const CONTRIBUTOR_COUNT = 30 ;
12
12
13
- const allWikiArticles = await getCollection (" wiki" );
13
+ const allWikiArticles = (await getCollection (" wiki" )).sort ((a , b ) =>
14
+ a .data .title .localeCompare (b .data .title )
15
+ );
16
+ await Promise .all (
17
+ allWikiArticles .map ((article ) =>
18
+ article .render ().then ((r ) => {
19
+ article .data .lastModified = r .remarkPluginFrontmatter .lastModified ;
20
+ })
21
+ )
22
+ );
14
23
const gettingStartedArticles = allWikiArticles .filter (
15
24
(article ) => article .data [" getting-started" ] === true
16
25
);
@@ -135,13 +144,27 @@ if (!contributors) {
135
144
</section >
136
145
<section id =" all-articles" >
137
146
<h2 >All Wiki Articles</h2 >
147
+ <div class =" sorts" >
148
+ <Tooltip content =" Sort Method" >
149
+ <Icon group =" solid" name =" sort" />
150
+ </Tooltip >
151
+ <select name =" sort" id =" sort" >
152
+ <option value =" alphabetical" >A-Z</option >
153
+ <option value =" last-modified" >Last Modified</option >
154
+ <option value =" length" >Length</option >
155
+ </select >
156
+ </div >
138
157
<div class =" grid" >
139
158
{
140
159
allWikiArticles .map ((article ) => (
141
- <div class = " article" >
160
+ <div
161
+ class = " article"
162
+ data-last-modified = { article .data .lastModified }
163
+ data-length = { article .body .length }
164
+ >
142
165
<a href = { ` /wiki/${article .slug }/ ` } >
143
- { article .data .title }
144
- <p >{ article .data .description } </p >
166
+ < div class = " name " > { article .data .title } </ div >
167
+ <p class = " description " >{ article .data .description } </p >
145
168
</a >
146
169
</div >
147
170
))
@@ -152,6 +175,54 @@ if (!contributors) {
152
175
</main >
153
176
</Layout >
154
177
178
+ <script >
179
+ import dayjs from "dayjs";
180
+
181
+ const articlesContainer = document.querySelector(
182
+ "section#all-articles div.grid"
183
+ );
184
+ const allArticles = Array.from(
185
+ document.querySelectorAll("section#all-articles div.grid > div.article")
186
+ );
187
+ const sortDropdown = document.querySelector(
188
+ "section#all-articles select#sort"
189
+ );
190
+
191
+ sortDropdown?.addEventListener("input", (e) => {
192
+ let sortFunction = (articleA: Element, articleB: Element): number => {
193
+ const nameA =
194
+ articleA.querySelector<HTMLAnchorElement>("div.name")?.innerText ?? "";
195
+ const nameB =
196
+ articleB.querySelector<HTMLAnchorElement>("div.name")?.innerText ?? "";
197
+
198
+ return nameA.localeCompare(nameB);
199
+ };
200
+
201
+ switch ((e.target as HTMLInputElement).value) {
202
+ case "last-modified":
203
+ sortFunction = (articleA, articleB) => {
204
+ const dateA = dayjs(articleA.getAttribute("data-last-modified"));
205
+ const dateB = dayjs(articleB.getAttribute("data-last-modified"));
206
+
207
+ return dateB.diff(dateA);
208
+ };
209
+ break;
210
+ case "length":
211
+ sortFunction = (articleA, articleB) => {
212
+ return (
213
+ Number(articleB.getAttribute("data-length") ?? 0) -
214
+ Number(articleA.getAttribute("data-length") ?? 0)
215
+ );
216
+ };
217
+ break;
218
+ }
219
+
220
+ allArticles
221
+ .sort(sortFunction)
222
+ .forEach((el) => articlesContainer?.appendChild(el));
223
+ });
224
+ </script >
225
+
155
226
<style lang =" scss" >
156
227
.grid {
157
228
display: grid;
@@ -262,6 +333,29 @@ if (!contributors) {
262
333
.grid {
263
334
grid-template-columns: repeat(auto-fill, minmax(15em, 1fr));
264
335
text-align: center;
336
+
337
+ .article {
338
+ display: flex;
339
+ flex-direction: column;
340
+ justify-content: space-between;
341
+ gap: 0.2em 0px;
342
+ }
343
+ }
344
+
345
+ .sorts {
346
+ width: fit-content;
347
+ margin-left: auto;
348
+
349
+ select#sort {
350
+ background: transparent;
351
+ border: none;
352
+ border-bottom: #276cae solid 0.2em;
353
+ color: white;
354
+
355
+ option {
356
+ color: black;
357
+ }
358
+ }
265
359
}
266
360
}
267
361
0 commit comments