summaryrefslogtreecommitdiff
path: root/garden
diff options
context:
space:
mode:
Diffstat (limited to 'garden')
-rw-r--r--garden/src/pages/council/users.tsx13
-rw-r--r--garden/src/store/council.ts22
-rw-r--r--garden/src/styles/council.css10
3 files changed, 40 insertions, 5 deletions
diff --git a/garden/src/pages/council/users.tsx b/garden/src/pages/council/users.tsx
index 4077dde..285c7b3 100644
--- a/garden/src/pages/council/users.tsx
+++ b/garden/src/pages/council/users.tsx
@@ -30,6 +30,11 @@ export default function CouncilUsers() {
return new Date(date).toLocaleDateString();
}
+ function sortIndicator(field: string) {
+ if (council.sortField() !== field) return "";
+ return council.sortOrder() === "asc" ? " \u25B2" : " \u25BC";
+ }
+
return (
<section>
<h2 class="page-title">Users</h2>
@@ -46,11 +51,11 @@ export default function CouncilUsers() {
<div class="council-grid">
<div class="council-grid-header">
- <span>User</span>
- <span>Email</span>
- <span>Role</span>
+ <span class="council-sortable" onClick={() => council.toggleSort("display_name")}>User{sortIndicator("display_name")}</span>
+ <span class="council-sortable" onClick={() => council.toggleSort("email")}>Email{sortIndicator("email")}</span>
+ <span class="council-sortable" onClick={() => council.toggleSort("role")}>Role{sortIndicator("role")}</span>
<span>Status</span>
- <span>Joined</span>
+ <span class="council-sortable" onClick={() => council.toggleSort("created_at")}>Joined{sortIndicator("created_at")}</span>
</div>
<Show when={!council.loading()} fallback={
<div class="council-grid-empty">Loading...</div>
diff --git a/garden/src/store/council.ts b/garden/src/store/council.ts
index 3ffe36a..559ecb8 100644
--- a/garden/src/store/council.ts
+++ b/garden/src/store/council.ts
@@ -9,10 +9,17 @@ const [page, setPage] = createSignal(1);
const [totalPages, setTotalPages] = createSignal(0);
const [loading, setLoading] = createSignal(false);
const [search, setSearch] = createSignal("");
+const [sortField, setSortField] = createSignal("created_at");
+const [sortOrder, setSortOrder] = createSignal<"asc" | "desc">("desc");
async function loadUsers(p = 1, q = "") {
setLoading(true);
- const params = new URLSearchParams({ page: String(p), per_page: "20" });
+ const params = new URLSearchParams({
+ page: String(p),
+ per_page: "20",
+ sort: sortField(),
+ order: sortOrder(),
+ });
if (q) params.set("search", q);
const response = await api<PaginatedResponse<AdminUser>>(`/council/users?${params}`, {
@@ -28,6 +35,16 @@ async function loadUsers(p = 1, q = "") {
setLoading(false);
}
+function toggleSort(field: string) {
+ if (sortField() === field) {
+ setSortOrder(sortOrder() === "asc" ? "desc" : "asc");
+ } else {
+ setSortField(field);
+ setSortOrder("desc");
+ }
+ loadUsers(1, search());
+}
+
export const council = {
users,
total,
@@ -37,4 +54,7 @@ export const council = {
search,
setSearch,
loadUsers,
+ sortField,
+ sortOrder,
+ toggleSort,
}; \ No newline at end of file
diff --git a/garden/src/styles/council.css b/garden/src/styles/council.css
index 3a23336..d623cab 100644
--- a/garden/src/styles/council.css
+++ b/garden/src/styles/council.css
@@ -43,6 +43,16 @@
border-bottom: 1px solid var(--color-border);
}
+.council-sortable {
+ cursor: pointer;
+ -webkit-user-select: none;
+ user-select: none;
+}
+
+.council-sortable:hover {
+ color: var(--color-text);
+}
+
.council-grid-row {
border-bottom: 1px solid var(--color-border);
color: var(--color-text);