aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/routes/user/[user]/badges/+page.svelte311
1 files changed, 162 insertions, 149 deletions
diff --git a/src/routes/user/[user]/badges/+page.svelte b/src/routes/user/[user]/badges/+page.svelte
index 51670bdf..68e35177 100644
--- a/src/routes/user/[user]/badges/+page.svelte
+++ b/src/routes/user/[user]/badges/+page.svelte
@@ -20,13 +20,22 @@
let transparent = false;
let confirmDelete = 0;
let selectedBadge: Badge | undefined = undefined;
+ let loadError: string | null = null;
type GroupedBadges = { [key: string]: Badge[] };
onMount(async () => {
// socket.on('badges', (message) => (badges = message));
- badgesPromise = fetch(`/api/badges?id=${(await user(data.username)).id}`);
+ const badger = await user(data.username);
+
+ if (!badger) {
+ loadError = 'User not found.';
+
+ return;
+ }
+
+ badgesPromise = fetch(`/api/badges?id=${badger.id}`);
if (data.user) {
currentUserIdentity = userIdentity(data.user);
@@ -192,163 +201,167 @@
<HeadTitle route={`${data.username}'s Badge Wall`} path={`/user/${data.username}`} />
-{#await currentUserIdentity}
- Loading user identity ... 60%
-{:then identity}
- {@const isOwner = identity && identity.name === data.username}
-
- {#if isOwner}
- <p>
- <a href={`/user/${data.username}`}>Back to Profile</a>
- •
- <a
- href={`#`}
- on:click={() => {
- if (editMode) selectedBadge = undefined;
-
- editMode = !editMode;
- }}
- >
- {editMode ? 'Disable' : 'Enable'} Edit Mode
- </a>
- •
- <a href={`#`} on:click={() => screenshot()}>Download</a>
- •
- <input type="checkbox" bind:checked={dark} /> Dark Mode
- <input type="checkbox" bind:checked={transparent} /> Transparent Background
- </p>
- {/if}
-
- {#if editMode && isOwner}
- {#if error}
- <p style="color: red;">{error}</p>
- {/if}
-
- <p>
- <input
- type="text"
- placeholder="Image URL"
- name="image_url"
- minlength="1"
- maxlength="1000"
- size="11"
- value={selectedBadge ? selectedBadge.image : ''}
- />
- <input
- type="text"
- placeholder="Activity URL"
- name="activity_url"
- minlength="1"
- maxlength="1000"
- size="11"
- value={selectedBadge ? (selectedBadge.post === '#' ? '' : selectedBadge.post) : ''}
- />
- <input
- type="text"
- placeholder="Description (Optional)"
- name="description"
- minlength="1"
- maxlength="1000"
- size="11"
- value={selectedBadge ? selectedBadge.description : ''}
- />
- <input
- type="text"
- placeholder="Category (Optional)"
- name="category"
- minlength="1"
- maxlength="1000"
- size="11"
- value={selectedBadge
- ? selectedBadge.category === 'Uncategorised'
- ? ''
- : selectedBadge.category
- : ''}
- />
- <a href={`#`} on:click={submitBadge}>{selectedBadge ? 'Update' : 'Add'} Badge</a>
- {#if selectedBadge}
- or
+{#if loadError}
+ {loadError}
+{:else}
+ {#await currentUserIdentity}
+ Loading user identity ... 60%
+ {:then identity}
+ {@const isOwner = identity && identity.name === data.username}
+
+ {#if isOwner}
+ <p>
+ <a href={`/user/${data.username}`}>Back to Profile</a>
+ •
<a
href={`#`}
on:click={() => {
- if (selectedBadge) removeBadge(selectedBadge);
- }}>Delete Badge (click twice)</a
+ if (editMode) selectedBadge = undefined;
+
+ editMode = !editMode;
+ }}
>
+ {editMode ? 'Disable' : 'Enable'} Edit Mode
+ </a>
+ •
+ <a href={`#`} on:click={() => screenshot()}>Download</a>
+ •
+ <input type="checkbox" bind:checked={dark} /> Dark Mode
+ <input type="checkbox" bind:checked={transparent} /> Transparent Background
+ </p>
+ {/if}
+
+ {#if editMode && isOwner}
+ {#if error}
+ <p style="color: red;">{error}</p>
{/if}
- <span style="float: right;">
+
+ <p>
+ <input
+ type="text"
+ placeholder="Image URL"
+ name="image_url"
+ minlength="1"
+ maxlength="1000"
+ size="11"
+ value={selectedBadge ? selectedBadge.image : ''}
+ />
+ <input
+ type="text"
+ placeholder="Activity URL"
+ name="activity_url"
+ minlength="1"
+ maxlength="1000"
+ size="11"
+ value={selectedBadge ? (selectedBadge.post === '#' ? '' : selectedBadge.post) : ''}
+ />
<input
- type="datetime-local"
- value={selectedBadge && selectedBadge.time ? selectedBadge.time : ''}
+ type="text"
+ placeholder="Description (Optional)"
+ name="description"
+ minlength="1"
+ maxlength="1000"
+ size="11"
+ value={selectedBadge ? selectedBadge.description : ''}
/>
- <small>Must be full date and time, defaults to now if any fields empty</small>
- </span>
- </p>
- {/if}
-
- {#await badgesPromise}
- Loading badges ... 40%
- {:then badgesResponse}
- {#if badgesResponse}
- {#await badgesResponse.json()}
- Loading badges ... 80%
- {:then ungroupedBadges}
- <div id="badges">
- {#if ungroupedBadges === null}
- {@html nbsp('Loading badges ... 50%')}
- {:else if ungroupedBadges.length === 0}
- {@html nbsp('No badges found for this user.')}
- {:else}
- {@const groupedBadges = Object.entries(groupBadges(ungroupedBadges))}
-
- {#each groupedBadges as [category, badges]}
- <details open>
- <summary>{category}</summary>
-
- <div class="badges">
- {#each badges as badge}
- {#if editMode}
- <a
- href={`#`}
- on:click={() => (selectedBadge = badge)}
- id={`badge-${badge.id}`}
- title={`${
- badge.time ? databaseTimeToDate(badge.time).toLocaleString() : ''
- }${badge.description ? `\n${badge.description}` : ''}`}
- >
- <img src={badge.image} alt={badge.description} />
- </a>
- {:else}
- <a
- href={badge.post}
- target="_blank"
- id={`badge-${badge.id}`}
- title={`${
- badge.time ? databaseTimeToDate(badge.time).toLocaleString() : ''
- }${badge.description ? `\n${badge.description}` : ''}`}
- >
- <img src={badge.image} alt={badge.description} />
- </a>
- {/if}
- {/each}
- </div>
- </details>
-
- {#if groupedBadges[groupedBadges.length - 1][0] !== category}
- <p />
- {/if}
- {/each}
- {/if}
- </div>
- {:catch}
- <p>Could not parse badges</p>
- {/await}
- {:else}
- Loading badges ... 20%
+ <input
+ type="text"
+ placeholder="Category (Optional)"
+ name="category"
+ minlength="1"
+ maxlength="1000"
+ size="11"
+ value={selectedBadge
+ ? selectedBadge.category === 'Uncategorised'
+ ? ''
+ : selectedBadge.category
+ : ''}
+ />
+ <a href={`#`} on:click={submitBadge}>{selectedBadge ? 'Update' : 'Add'} Badge</a>
+ {#if selectedBadge}
+ or
+ <a
+ href={`#`}
+ on:click={() => {
+ if (selectedBadge) removeBadge(selectedBadge);
+ }}>Delete Badge (click twice)</a
+ >
+ {/if}
+ <span style="float: right;">
+ <input
+ type="datetime-local"
+ value={selectedBadge && selectedBadge.time ? selectedBadge.time : ''}
+ />
+ <small>Must be full date and time, defaults to now if any fields empty</small>
+ </span>
+ </p>
{/if}
- {:catch}
- <p>Could not fetch badges</p>
+
+ {#await badgesPromise}
+ Loading badges ... 40%
+ {:then badgesResponse}
+ {#if badgesResponse}
+ {#await badgesResponse.json()}
+ Loading badges ... 80%
+ {:then ungroupedBadges}
+ <div id="badges">
+ {#if ungroupedBadges === null}
+ {@html nbsp('Loading badges ... 50%')}
+ {:else if ungroupedBadges.length === 0}
+ {@html nbsp('No badges found for this user.')}
+ {:else}
+ {@const groupedBadges = Object.entries(groupBadges(ungroupedBadges))}
+
+ {#each groupedBadges as [category, badges]}
+ <details open>
+ <summary>{category}</summary>
+
+ <div class="badges">
+ {#each badges as badge}
+ {#if editMode}
+ <a
+ href={`#`}
+ on:click={() => (selectedBadge = badge)}
+ id={`badge-${badge.id}`}
+ title={`${
+ badge.time ? databaseTimeToDate(badge.time).toLocaleString() : ''
+ }${badge.description ? `\n${badge.description}` : ''}`}
+ >
+ <img src={badge.image} alt={badge.description} />
+ </a>
+ {:else}
+ <a
+ href={badge.post}
+ target="_blank"
+ id={`badge-${badge.id}`}
+ title={`${
+ badge.time ? databaseTimeToDate(badge.time).toLocaleString() : ''
+ }${badge.description ? `\n${badge.description}` : ''}`}
+ >
+ <img src={badge.image} alt={badge.description} />
+ </a>
+ {/if}
+ {/each}
+ </div>
+ </details>
+
+ {#if groupedBadges[groupedBadges.length - 1][0] !== category}
+ <p />
+ {/if}
+ {/each}
+ {/if}
+ </div>
+ {:catch}
+ <p>Could not parse badges</p>
+ {/await}
+ {:else}
+ Loading badges ... 20%
+ {/if}
+ {:catch}
+ <p>Could not fetch badges</p>
+ {/await}
{/await}
-{/await}
+{/if}
<style>
/* body {