From 3678f5a3e8159b5b75242f8de93b9c482959fd8c Mon Sep 17 00:00:00 2001
From: Sam
Date: Tue, 14 Mar 2023 16:43:31 +0100
Subject: [PATCH] feat: paginate member list, add create member button
---
frontend/src/lib/components/ErrorAlert.svelte | 15 +++
frontend/src/routes/@[username]/+page.svelte | 101 ++++++++++++++++--
.../routes/auth/login/discord/+page.svelte | 12 +--
frontend/src/routes/edit/profile/+page.svelte | 9 +-
frontend/src/routes/settings/+page.svelte | 11 +-
.../src/routes/settings/invites/+page.svelte | 6 +-
6 files changed, 120 insertions(+), 34 deletions(-)
create mode 100644 frontend/src/lib/components/ErrorAlert.svelte
diff --git a/frontend/src/lib/components/ErrorAlert.svelte b/frontend/src/lib/components/ErrorAlert.svelte
new file mode 100644
index 0000000..c9cbe2c
--- /dev/null
+++ b/frontend/src/lib/components/ErrorAlert.svelte
@@ -0,0 +1,15 @@
+
+
+
+ An error occurred
+ {error.code}:
+ {error.message}
+ {#if error.details}
+ ({error.details})
+ {/if}
+
diff --git a/frontend/src/routes/@[username]/+page.svelte b/frontend/src/routes/@[username]/+page.svelte
index 5652414..7b5e145 100644
--- a/frontend/src/routes/@[username]/+page.svelte
+++ b/frontend/src/routes/@[username]/+page.svelte
@@ -4,15 +4,34 @@
import type { PageData } from "./$types";
- import { Alert, Icon } from "sveltestrap";
+ import {
+ Alert,
+ Button,
+ ButtonGroup,
+ Icon,
+ Input,
+ Modal,
+ ModalBody,
+ ModalFooter,
+ } from "sveltestrap";
import FieldCard from "$lib/components/FieldCard.svelte";
import StatusIcon from "$lib/components/StatusIcon.svelte";
import PronounLink from "$lib/components/PronounLink.svelte";
import PartialMemberCard from "$lib/components/PartialMemberCard.svelte";
import FallbackImage from "$lib/components/FallbackImage.svelte";
import { userStore } from "$lib/store";
- import { pronounDisplay, userAvatars, WordStatus, type Member } from "$lib/api/entities";
+ import {
+ MAX_MEMBERS,
+ pronounDisplay,
+ userAvatars,
+ WordStatus,
+ type APIError,
+ type Member,
+ type PartialMember,
+ } from "$lib/api/entities";
import { PUBLIC_BASE_URL } from "$env/static/public";
+ import { apiFetchClient } from "$lib/api/fetch";
+ import ErrorAlert from "$lib/components/ErrorAlert.svelte";
export let data: PageData;
@@ -20,8 +39,44 @@
$: bio = data.bio ? sanitizeHtml(marked.parse(data.bio)) : null;
let memberPage: number = 0;
- let memberSlice: Member[] = [];
- $: member = data.members.slice(memberPage * 20, memberPage + 1 * 20);
+ let memberSlice: PartialMember[] = [];
+ $: memberSlice = data.members.slice(memberPage * 20, (memberPage + 1) * 20);
+ const totalPages = Math.floor(data.members.length / 20) + 1;
+
+ const prevPage = () => {
+ if (memberPage === 0) {
+ return;
+ }
+ memberPage = memberPage - 1;
+ };
+
+ const nextPage = () => {
+ if ((memberPage + 1) * 20 > data.members.length) {
+ return;
+ }
+ memberPage = memberPage + 1;
+ };
+
+ let modalOpen = false;
+ let toggleModal = () => (modalOpen = !modalOpen);
+ let newMemberName = "";
+ let newMemberError: APIError | null = null;
+
+ const createMember = async () => {
+ try {
+ const member = await apiFetchClient("/members", "POST", {
+ name: newMemberName,
+ });
+
+ newMemberName = "";
+ newMemberError = null;
+ data.members = [...data.members, member];
+
+ toggleModal();
+ } catch (e) {
+ newMemberError = e as APIError;
+ }
+ };
const favNames = data.names.filter((entry) => entry.status === WordStatus.Favourite);
const favPronouns = data.pronouns.filter((entry) => entry.status === WordStatus.Favourite);
@@ -97,15 +152,49 @@
- Members
+
+ Members
+ {#if $userStore && $userStore.id === data.id}
+
+ {/if}
+ {#if totalPages > 1}
+
+
+
+
+
+ {/if}
+
- {#each data.members as member}
+ {#each memberSlice as member}
{/each}
{/if}
+
+
+
+ {#if newMemberError}
+
+ {/if}
+
+
+
+
+
+
diff --git a/frontend/src/routes/auth/login/discord/+page.svelte b/frontend/src/routes/auth/login/discord/+page.svelte
index 703de43..9148eb1 100644
--- a/frontend/src/routes/auth/login/discord/+page.svelte
+++ b/frontend/src/routes/auth/login/discord/+page.svelte
@@ -7,6 +7,7 @@
import { apiFetch } from "$lib/api/fetch";
import { userStore } from "$lib/store";
import type { PageData } from "./$types";
+ import ErrorAlert from "$lib/components/ErrorAlert.svelte";
interface SignupResponse {
user: MeUser;
@@ -74,11 +75,7 @@
Log in with Discord
{#if data.error}
-
- An error occurred
- {data.error.code}:
- {data.error.message}
-
+
{/if}
{#if data.ticket}
{/if}
{#if error}
-
- An error occurred
- {error.code}: {error.message}
-
+
{/if}
@@ -137,10 +135,7 @@
{#if deleteError}
-
- An error occurred
- {deleteError.code}: {deleteError.message}
-
+
{/if}
diff --git a/frontend/src/routes/settings/invites/+page.svelte b/frontend/src/routes/settings/invites/+page.svelte
index 7b67ff7..9849972 100644
--- a/frontend/src/routes/settings/invites/+page.svelte
+++ b/frontend/src/routes/settings/invites/+page.svelte
@@ -1,6 +1,7 @@