aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFuwn <[email protected]>2024-02-13 09:18:13 -0800
committerFuwn <[email protected]>2024-02-13 09:18:13 -0800
commit84f0ce66ca51e78da8685b9be5aaa0e03d5b3eef (patch)
treed50c1b61908680cd99252d6f86b0bd7333d2cdfe /src
parentfeat(tools): bigger descriptions (diff)
downloaddue.moe-84f0ce66ca51e78da8685b9be5aaa0e03d5b3eef.tar.xz
due.moe-84f0ce66ca51e78da8685b9be5aaa0e03d5b3eef.zip
feat(events): groups page
Diffstat (limited to 'src')
-rw-r--r--src/lib/Database/groups.ts32
-rw-r--r--src/routes/api/events/group/+server.ts4
-rw-r--r--src/routes/api/events/groups/+server.ts3
-rw-r--r--src/routes/events/groups/+page.svelte129
4 files changed, 168 insertions, 0 deletions
diff --git a/src/lib/Database/groups.ts b/src/lib/Database/groups.ts
new file mode 100644
index 00000000..e3e392b8
--- /dev/null
+++ b/src/lib/Database/groups.ts
@@ -0,0 +1,32 @@
+import supabase from './supabase';
+
+export interface Group {
+ id: number;
+ created_at: string;
+ updated_at?: string;
+ members: number[];
+ avatar: string;
+ banner: string;
+ description?: string;
+ name: string;
+ anilist_id: number;
+ anilist_username: string;
+ badge?: string;
+ badge_description?: string;
+}
+
+export const getGroups = async () => {
+ const { data, error } = await supabase.from('groups').select('*');
+
+ if (error) return [];
+
+ return data as Group[];
+};
+
+export const getGroup = async (slug: string) => {
+ const { data, error } = await supabase.from('groups').select('*').eq('slug', slug);
+
+ if (error) return [];
+
+ return data as Group[];
+};
diff --git a/src/routes/api/events/group/+server.ts b/src/routes/api/events/group/+server.ts
new file mode 100644
index 00000000..b79895fd
--- /dev/null
+++ b/src/routes/api/events/group/+server.ts
@@ -0,0 +1,4 @@
+import { getGroup } from '$lib/Database/groups';
+
+export const GET = async ({ url }) =>
+ Response.json(await getGroup(url.searchParams.get('slug') || ''));
diff --git a/src/routes/api/events/groups/+server.ts b/src/routes/api/events/groups/+server.ts
new file mode 100644
index 00000000..512dde37
--- /dev/null
+++ b/src/routes/api/events/groups/+server.ts
@@ -0,0 +1,3 @@
+import { getGroups } from '$lib/Database/groups';
+
+export const GET = async () => Response.json(await getGroups());
diff --git a/src/routes/events/groups/+page.svelte b/src/routes/events/groups/+page.svelte
new file mode 100644
index 00000000..b52407f0
--- /dev/null
+++ b/src/routes/events/groups/+page.svelte
@@ -0,0 +1,129 @@
+<script lang="ts">
+ import type { Group } from '$lib/Database/groups';
+ import Message from '$lib/Loading/Message.svelte';
+ import tooltip from '$lib/Tooltip/tooltip';
+ import root from '$lib/Utility/root';
+ import { onMount } from 'svelte';
+
+ let groupsResponse: Promise<Response>;
+
+ onMount(async () => {
+ groupsResponse = fetch(root('/api/events/groups'));
+ });
+
+ const asGroup = (group: any) => group as Group;
+</script>
+
+{#await groupsResponse}
+ <Message message="Loading groups ..." />
+{:then groups}
+ {#if groups}
+ {#await groups.json()}
+ <Message message="Parsing groups ..." />
+ {:then json}
+ <ul>
+ {#each json as rawGroup}
+ {@const group = asGroup(rawGroup)}
+
+ <div
+ class="card"
+ id="user-grid"
+ style={`background-image: ${
+ group.banner ? `url(${group.banner})` : 'none'
+ }; padding: 0;`}
+ >
+ {#if group}
+ <img src={group.banner} alt="" id="cover-image" />
+ {/if}
+
+ <div class="card" id="user-grid-content">
+ <div id="user-grid-avatar">
+ <a href={`https://anilist.co/user/${group.anilist_username}`} target="_blank">
+ <img src={group.avatar} alt="" width="100vw" id="avatar" />
+ </a>
+ </div>
+
+ <div id="user-grid-content-text">
+ <p>
+ <a
+ href={`https://anilist.co/user/${group.anilist_username}`}
+ target="_blank"
+ title={String(group.anilist_id)}
+ use:tooltip
+ >
+ @{group.name}
+ </a>
+ {#if group && group.badge}
+ &#8204;
+ <button
+ class="unclickable-button button-badge badge-rainbow"
+ title={group.badge_description}
+ use:tooltip
+ data-tooltip-disable={group.badge_description}
+ >
+ {group.badge}
+ </button>
+ {/if}
+ </p>
+
+ <p>
+ {group.description}
+ </p>
+ </div>
+ </div>
+ </div>
+ {/each}
+ </ul>
+ {:catch}
+ <Message message="" loader="ripple" slot>
+ Error parsing groups. Please
+ <a href={'#'} on:click={() => location.reload()}>try again</a> later.
+ </Message>
+ {/await}
+ {:else}
+ <Message message="Parsing groups ..." />
+ {/if}
+{:catch}
+ <Message message="" loader="ripple" slot>
+ Error loading groups. Please
+ <a href={'#'} on:click={() => location.reload()}>try again</a> later.
+ </Message>
+{/await}
+
+<style>
+ #user-grid-content {
+ display: flex;
+ flex-wrap: wrap;
+ column-gap: 1.5em;
+ background-color: rgba(0, 0, 0, 0.468);
+ color: #d8d8d8;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ }
+
+ #user-grid-avatar {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ }
+
+ #avatar {
+ border-radius: 8px;
+ }
+
+ /* .click-item {
+ margin: 0 0.625rem;
+ } */
+
+ #user-grid {
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ }
+
+ #cover-image {
+ visibility: hidden;
+ height: 4.5em;
+ }
+</style>