diff options
Diffstat (limited to 'garden')
| -rw-r--r-- | garden/src/pages/council/users.tsx | 13 | ||||
| -rw-r--r-- | garden/src/store/council.ts | 22 | ||||
| -rw-r--r-- | garden/src/styles/council.css | 10 |
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); |
