diff --git a/backend/routes/auth/invite.go b/backend/routes/auth/invite.go
index 00279c3..c71e24f 100644
--- a/backend/routes/auth/invite.go
+++ b/backend/routes/auth/invite.go
@@ -11,7 +11,7 @@ import (
)
type inviteResponse struct {
- Code string `json:"string"`
+ Code string `json:"code"`
Created time.Time `json:"created"`
Used bool `json:"used"`
}
diff --git a/backend/routes/meta/meta.go b/backend/routes/meta/meta.go
index 2b000b2..609d691 100644
--- a/backend/routes/meta/meta.go
+++ b/backend/routes/meta/meta.go
@@ -2,6 +2,7 @@ package meta
import (
"net/http"
+ "os"
"codeberg.org/u1f320/pronouns.cc/backend/server"
"emperror.dev/errors"
@@ -24,6 +25,7 @@ type MetaResponse struct {
GitCommit string `json:"git_commit"`
Users int64 `json:"users"`
Members int64 `json:"members"`
+ RequireInvite bool `json:"require_invite"`
}
func (s *Server) meta(w http.ResponseWriter, r *http.Request) error {
@@ -45,6 +47,7 @@ func (s *Server) meta(w http.ResponseWriter, r *http.Request) error {
GitCommit: server.Revision,
Users: numUsers,
Members: numMembers,
+ RequireInvite: os.Getenv("REQUIRE_INVITE") == "true",
})
return nil
}
diff --git a/frontend/src/routes/+layout.server.ts b/frontend/src/routes/+layout.server.ts
index 6d2fd68..d522a21 100644
--- a/frontend/src/routes/+layout.server.ts
+++ b/frontend/src/routes/+layout.server.ts
@@ -16,4 +16,5 @@ interface MetaResponse {
git_commit: string;
users: number;
members: number;
+ require_invite: boolean;
}
diff --git a/frontend/src/routes/auth/login/discord/+page.svelte b/frontend/src/routes/auth/login/discord/+page.svelte
index ae15086..ca5e80d 100644
--- a/frontend/src/routes/auth/login/discord/+page.svelte
+++ b/frontend/src/routes/auth/login/discord/+page.svelte
@@ -1,6 +1,6 @@
@@ -8,9 +13,32 @@
Settings
- Your profile
- Invites
- API tokens
+
+ Your profile
+
+ {#if data.require_invite}
+
+ Invites
+
+ {/if}
+
+ API tokens
+
+
+ Data export
+
diff --git a/frontend/src/routes/settings/+layout.ts b/frontend/src/routes/settings/+layout.ts
index a3d1578..4cdd760 100644
--- a/frontend/src/routes/settings/+layout.ts
+++ b/frontend/src/routes/settings/+layout.ts
@@ -1 +1,8 @@
+import type { LayoutLoad } from "./$types";
+
export const ssr = false;
+
+export const load = (async ({ parent }) => {
+ const data = await parent();
+ return data;
+}) satisfies LayoutLoad;
diff --git a/frontend/src/routes/settings/invites/+page.svelte b/frontend/src/routes/settings/invites/+page.svelte
new file mode 100644
index 0000000..7b67ff7
--- /dev/null
+++ b/frontend/src/routes/settings/invites/+page.svelte
@@ -0,0 +1,69 @@
+
+
+
Invites ({data.invites.length})
+
+
+ {#if !data.invitesEnabled}
+
Invites aren't required to sign up to pronouns.cc right now!
+ {:else}
+
+
+ Code |
+ Created at |
+ Used? |
+
+
+ {#each data.invites as invite}
+
+ {invite.code} |
+ {invite.created} |
+ {invite.used ? "yes" : "no"} |
+
+ {/each}
+
+
+
+
+
+
+
+ {#if error}
+
+ An error occurred
+ {error.code}: {error.message}
+
+ {/if}
+
+
+
+ Successfully created a new invite! Give the person you're sending it to this code:
+ {latestInvite?.code}
+
+ {/if}
+
diff --git a/frontend/src/routes/settings/invites/+page.ts b/frontend/src/routes/settings/invites/+page.ts
new file mode 100644
index 0000000..15179ca
--- /dev/null
+++ b/frontend/src/routes/settings/invites/+page.ts
@@ -0,0 +1,25 @@
+import { ErrorCode, type APIError, type Invite } from "$lib/api/entities";
+import { apiFetchClient } from "$lib/api/fetch";
+import { error } from "@sveltejs/kit";
+import type { PageLoad } from "../$types";
+
+export const load = (async () => {
+ const data = {
+ invitesEnabled: true,
+ invites: [] as Invite[],
+ };
+
+ try {
+ const invites = await apiFetchClient
("/auth/invites");
+ data.invites = invites;
+ } catch (e) {
+ if ((e as APIError).code === ErrorCode.InvitesDisabled) {
+ data.invitesEnabled = false;
+ data.invites = [];
+ } else {
+ throw error(500, (e as APIError).message);
+ }
+ }
+
+ return data;
+}) satisfies PageLoad;