Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 57 additions & 113 deletions src/lib/components/generic/ProfileCard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,69 +25,51 @@ Do NOT pass in values that are not of the CURRENT USER or it will NOT work prope
}
let { cardUserGames, activeGame = $bindable(), user }: Props = $props();

let dropdownVisible = $state(false);
let available_games = getAvailableGames(cardUserGames)
let availableGames = getAvailableGames(cardUserGames)
</script>
<div class="profile-card-container">
<!-- ughh i hate using IDs like this but it's the best solution rn -->
<input type="checkbox" style:display="none" id="profileCardSelectorOpen" bind:checked={dropdownVisible}>
<label for="profileCardSelectorOpen" aria-expanded={dropdownVisible} aria-controls="profileCardDropdown" class:self={activeGame}>
<div class="panel profile-card">
<!-- TODO: [USER PROFILE] use user's image -->
<img src={user.profilePicture ? getProfilePictureUrl(user.profilePicture) : "/asset/rei.png"} alt="User" use:fadeLoad>
<div class="profile-card-text">

{#if activeGame}
<div class="profile-card-name">
{fromSegacode(cardUserGames[activeGame]?.name ?? "?")}
</div>
<div class="profile-card-rating">
{$LL.navigationBar.rating({rating: formatRatingForGame(activeGame, cardUserGames[activeGame]?.rating ?? 0) ?? "?"})}
</div>
{:else}
<div class="profile-card-name">
{user.displayName || user.username}
</div>
<div class="profile-card-rating">
{$LL.navigationBar.noGamesNotice()}
</div>
{/if}
</div>
<div class="panel profile-card" class:has-contents={availableGames.length > 0}>
<img src={user.profilePicture ? getProfilePictureUrl(user.profilePicture) : "/asset/rei.png"} alt="User" use:fadeLoad>
<div class="profile-card-text">

{#if activeGame}
<div class="profile-card-badge">
{activeGame in $LL.games ? $LL.games[activeGame as keyof typeof $LL.games]() : "?"}
<div class="profile-card-name">
{user.displayName ?? fromSegacode(cardUserGames[activeGame]?.name ?? "?")}
</div>
<div class="profile-card-rating">
{$LL.navigationBar.rating({rating: formatRatingForGame(activeGame, cardUserGames[activeGame]?.rating ?? 0) ?? "?"})}
</div>
<div class="profile-card-dropdown-icon">
{@html OpenChevron}
{:else}
<div class="profile-card-name">
{user.displayName || user.username}
</div>
<div class="profile-card-rating">
{$LL.navigationBar.noGamesNotice()}
</div>
{/if}
</div>
</label>
{#if available_games.length > 0}
<div class="panel profile-card-dropdown" id="profileCardDropdown">
<form action="/net/api/active-game" method="POST" use:enhance={({formData}) => {
activeGame = formData.get("active-game")?.toString()!;
dropdownVisible = false
Loader.active = true
return async ({ update, result }) => {
Loader.active = false
await update({ reset: true, invalidateAll: false });

}
}}>
<input type="hidden" value={page.url.href} name="url">
{#each available_games as game}
<button value={game} name="active-game" class="profile-card-dropdown-item" type="submit">
</div>
{#if availableGames.length > 0}
<form action="/net/api/active-game" method="POST" use:enhance={({formData}) => {
activeGame = formData.get("active-game")?.toString()!;
Loader.active = true
return async ({ update, result }) => {
Loader.active = false
await update({ reset: true, invalidateAll: false });

}
}}>
<input type="hidden" value={page.url.href} name="url">
<div class="profile-card-tab-container">
{#each availableGames as game}
<button value={game} name="active-game" class="profile-card-tab panel" class:inactive={activeGame != game} type="submit">
<div class="profile-card-name">
{game in $LL.games ? $LL.games[game as keyof typeof $LL.games]() : "?"}
</div>
<div class="profile-card-rating">
{$LL.navigationBar.rating({rating: formatRatingForGame(game, cardUserGames[game]!.rating) ?? "?"})}
</div>
</button>
{/each}
</form>
</div>
</div>
</form>
{/if}
</div>
<style lang="scss">
Expand All @@ -106,6 +88,11 @@ Do NOT pass in values that are not of the CURRENT USER or it will NOT work prope
display: flex;
position: relative;

&.has-contents {
border-radius: var(--panel-border-radius) var(--panel-border-radius) 0 0;
border-bottom: none;
}

img {
height: 100%;
border-radius: 100%;
Expand All @@ -128,78 +115,35 @@ Do NOT pass in values that are not of the CURRENT USER or it will NOT work prope
color: var(--text-color-c)
}
}
.profile-card-badge {
position: absolute;
right: var(--profile-card-badge-offset);
top: 0;
transform: translate(0, -50%);
border-radius: var(--profile-card-badge-border-radius);
background: var(--panel-bg);
border: 1px solid var(--text-color-d);
color: var(--text-color-b);
font-size: 0.75em;
font-weight: 500;
padding: var(--profile-card-badge-padding) calc(var(--profile-card-badge-padding) * 2);
}
.profile-card-dropdown-icon {
:global(svg) {
fill: var(--text-color-b);
height: 1.25em;
width: 1.25em;
transition: 150ms transform;
}
height: 100%;
display: flex;
align-items: center;
}
}

#profileCardSelectorOpen:checked {
~ .profile-card-dropdown {
opacity: 1;
pointer-events: all;
transform: none;
}
~ label > .profile-card .profile-card-dropdown-icon {
:global(svg) {
transform: rotate(180deg);
}
}
}

.profile-card-dropdown {
.profile-card-tab-container {
display: flex;
flex-direction: row;
width: 100%;
position: absolute;
top: calc(100% + var(--sidebar-button-padding));
left: 0;
z-index: -1;

transform: translate(0, -100%) scale(100%, 0);
opacity: 0;
pointer-events: none;
transition: 150ms transform, 150ms opacity;
height: 2em;

/* backdrop-filter shows as baseline 2024 (but in reality it's 2022)-- is this fine? i want transparency */
backdrop-filter: blur(10px);
.profile-card-tab {
flex: 1;
border-radius: 0 0 var(--panel-border-radius) var(--panel-border-radius);
font-size: 0.75em;

.profile-card-name {
color: var(--text-color);
}
background: var(--panel-bg) !important;
border: solid 1px var(--panel-stroke) !important;

.profile-card-dropdown-item {
height: 3em;
transition: 150ms height;

display: flex;

justify-content: center;
flex-direction: column;
padding: var(--profile-card-margin) calc(var(--profile-card-margin) * 2);
background: none;
border: none;
width: 100%;
text-align: left;
align-items: center;

.profile-card-rating {
font-size: 0.875em;
color: var(--text-color-c)
padding: 0.5em !important;

&.inactive {
opacity: 50%;
height: 2.5em;
}
}
}
Expand Down