Add sort direction controls to ModList
This commit is contained in:
parent
e1c0c5b4fa
commit
0b85e30043
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @next/next/no-img-element */
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import MiniSearch from "minisearch";
|
import MiniSearch from "minisearch";
|
||||||
@ -28,6 +29,7 @@ type ModWithCounts = Mod & {
|
|||||||
const ModList: React.FC<Props> = ({ mods, files, counts }) => {
|
const ModList: React.FC<Props> = ({ mods, files, counts }) => {
|
||||||
const [includeTranslations, setIncludeTranslations] = useState(true);
|
const [includeTranslations, setIncludeTranslations] = useState(true);
|
||||||
const [sortBy, setSortBy] = useState<keyof ModWithCounts>("unique_downloads");
|
const [sortBy, setSortBy] = useState<keyof ModWithCounts>("unique_downloads");
|
||||||
|
const [sortAsc, setSortAsc] = useState<boolean>(false);
|
||||||
const [filter, setFilter] = useState<string>("");
|
const [filter, setFilter] = useState<string>("");
|
||||||
const [category, setCategory] = useState<string>("All");
|
const [category, setCategory] = useState<string>("All");
|
||||||
const [filterResults, setFilterResults] = useState<Set<number>>(new Set());
|
const [filterResults, setFilterResults] = useState<Set<number>>(new Set());
|
||||||
@ -60,15 +62,17 @@ const ModList: React.FC<Props> = ({ mods, files, counts }) => {
|
|||||||
const aVal = a[sortBy];
|
const aVal = a[sortBy];
|
||||||
const bVal = b[sortBy];
|
const bVal = b[sortBy];
|
||||||
if (typeof aVal === "number" && typeof bVal === "number") {
|
if (typeof aVal === "number" && typeof bVal === "number") {
|
||||||
return bVal - aVal;
|
return sortAsc ? aVal - bVal : bVal - aVal;
|
||||||
} else if (
|
} else if (
|
||||||
typeof aVal === "string" &&
|
typeof aVal === "string" &&
|
||||||
typeof bVal === "string" &&
|
typeof bVal === "string" &&
|
||||||
["first_upload_at", "last_update_at"].includes(sortBy)
|
["first_upload_at", "last_update_at"].includes(sortBy)
|
||||||
) {
|
) {
|
||||||
return new Date(bVal).getTime() - new Date(aVal).getTime();
|
const aTime = new Date(aVal).getTime();
|
||||||
|
const bTime = new Date(bVal).getTime();
|
||||||
|
return sortAsc ? aTime - bTime : bTime - aTime;
|
||||||
} else if (typeof aVal === "string" && typeof bVal === "string") {
|
} else if (typeof aVal === "string" && typeof bVal === "string") {
|
||||||
return aVal.localeCompare(bVal);
|
return sortAsc ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@ -129,6 +133,38 @@ const ModList: React.FC<Props> = ({ mods, files, counts }) => {
|
|||||||
</option>
|
</option>
|
||||||
<option value="nexus_mod_id">ID</option>
|
<option value="nexus_mod_id">ID</option>
|
||||||
</select>
|
</select>
|
||||||
|
<div className={styles["sort-direction"]}>
|
||||||
|
<button
|
||||||
|
title="Sort ascending"
|
||||||
|
className={sortAsc ? styles.active : ""}
|
||||||
|
onClick={() => setSortAsc(true)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Sort ascending"
|
||||||
|
src={
|
||||||
|
sortAsc
|
||||||
|
? "/img/arrow-selected.svg"
|
||||||
|
: "/img/arrow-disabled.svg"
|
||||||
|
}
|
||||||
|
className={styles.asc}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
title="Sort descending"
|
||||||
|
className={!sortAsc ? styles.active : ""}
|
||||||
|
onClick={() => setSortAsc(false)}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Sort descending"
|
||||||
|
src={
|
||||||
|
!sortAsc
|
||||||
|
? "/img/arrow-selected.svg"
|
||||||
|
: "/img/arrow-disabled.svg"
|
||||||
|
}
|
||||||
|
className={styles.desc}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={styles["filter-row"]}>
|
<div className={styles["filter-row"]}>
|
||||||
<label htmlFor="filter">Filter:</label>
|
<label htmlFor="filter">Filter:</label>
|
||||||
|
1
public/img/arrow-disabled.svg
Normal file
1
public/img/arrow-disabled.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="grey" d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"/></svg>
|
After Width: | Height: | Size: 541 B |
1
public/img/arrow-selected.svg
Normal file
1
public/img/arrow-selected.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="purple" d="M438.6 278.6l-160 160C272.4 444.9 264.2 448 256 448s-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L338.8 288H32C14.33 288 .0016 273.7 .0016 256S14.33 224 32 224h306.8l-105.4-105.4c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l160 160C451.1 245.9 451.1 266.1 438.6 278.6z"/></svg>
|
After Width: | Height: | Size: 543 B |
@ -56,7 +56,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sort-by {
|
.sort-by {
|
||||||
min-width: 175px;
|
min-width: 119px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-asc {
|
||||||
|
margin-left: 8px;
|
||||||
|
min-width: 50px;
|
||||||
|
max-width: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
@ -71,3 +77,33 @@
|
|||||||
.include-translations input {
|
.include-translations input {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.sort-direction {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-direction button {
|
||||||
|
width: 24px;
|
||||||
|
height: 20px;
|
||||||
|
display: block;
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sort-direction button img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.asc {
|
||||||
|
transform: rotate(-90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user