diff options
| -rw-r--r-- | src/routes/user/[user]/badges/+page.svelte | 311 |
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 { |