@@ -10,7 +10,16 @@ import { Image } from "astro:assets";
1010
1111const CONTRIBUTOR_COUNT = 30 ;
1212
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+ );
1423const gettingStartedArticles = allWikiArticles .filter (
1524 (article ) => article .data [" getting-started" ] === true
1625);
@@ -135,13 +144,27 @@ if (!contributors) {
135144 </section >
136145 <section id =" all-articles" >
137146 <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 >
138157 <div class =" grid" >
139158 {
140159 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+ >
142165 <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 >
145168 </a >
146169 </div >
147170 ))
@@ -152,6 +175,54 @@ if (!contributors) {
152175 </main >
153176</Layout >
154177
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+
155226<style lang =" scss" >
156227 .grid {
157228 display: grid;
@@ -262,6 +333,29 @@ if (!contributors) {
262333 .grid {
263334 grid-template-columns: repeat(auto-fill, minmax(15em, 1fr));
264335 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+ }
265359 }
266360 }
267361
0 commit comments