This commit is contained in:
2026-03-26 00:51:25 +01:00
parent 99db0b3c67
commit ef4496aa5d
31 changed files with 4185 additions and 452 deletions
+110 -1
View File
@@ -22,6 +22,18 @@
localStorage.removeItem('refresh_token');
goto('/auth');
}
let resendStatus = $state('');
async function resendVerification() {
resendStatus = 'sending';
await apiFetch(`${API_URL}/auth/resend-verification`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: profile.email }),
});
resendStatus = 'sent';
}
</script>
<main>
@@ -34,7 +46,17 @@
<div class="avatar">{profile.username[0].toUpperCase()}</div>
<div class="profile-info">
<h1 class="username">{profile.username}</h1>
<p class="email">{profile.email}</p>
<p class="email">
{profile.email}
{#if !profile.email_verified}
<span class="unverified-badge">unverified</span>
{/if}
</p>
{#if !profile.email_verified}
<button class="resend-btn" onclick={resendVerification} disabled={resendStatus === 'sending' || resendStatus === 'sent'}>
{resendStatus === 'sent' ? 'Email sent' : resendStatus === 'sending' ? 'Sending...' : 'Resend verification email'}
</button>
{/if}
<p class="joined">Member since {new Date(profile.created_at).toLocaleDateString('en-GB', { year: 'numeric', month: 'long', day: 'numeric' })}</p>
</div>
<button class="logout-btn" onclick={logout}>Log Out</button>
@@ -43,6 +65,15 @@
<div class="section-divider"></div>
<div class="shards-row">
<span class="shards-icon"></span>
<span class="shards-value">{profile.shards}</span>
<span class="shards-label">Shards</span>
<a href="/shards" class="shards-link">shatter cards</a>
</div>
<div class="section-divider"></div>
<h2 class="section-title">Stats</h2>
<div class="stats-grid">
<div class="stat-card">
@@ -164,6 +195,37 @@
margin: 0;
}
.unverified-badge {
font-family: 'Cinzel', serif;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: #c87830;
border: 1px solid rgba(200, 120, 48, 0.4);
border-radius: 3px;
padding: 1px 5px;
vertical-align: middle;
margin-left: 6px;
}
.resend-btn {
font-family: 'Crimson Text', serif;
font-size: 13px;
font-style: italic;
color: rgba(240, 180, 80, 0.5);
background: none;
border: none;
padding: 0;
cursor: pointer;
text-decoration: underline;
transition: color 0.15s;
text-align: left;
}
.resend-btn:hover:not(:disabled) { color: rgba(240, 180, 80, 0.8); }
.resend-btn:disabled { cursor: default; opacity: 0.6; }
.joined {
font-family: 'Crimson Text', serif;
font-size: 13px;
@@ -206,6 +268,53 @@
.reset-link:hover { color: rgba(240, 180, 80, 0.7); }
.shards-row {
display: flex;
align-items: center;
gap: 0.5rem;
}
.shards-link {
font-family: 'Cinzel', serif;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: rgba(126, 207, 207, 0.6);
border: 1px solid rgba(126, 207, 207, 0.3);
border-radius: 4px;
padding: 3px 8px;
text-decoration: none;
margin-top: 4px;
margin-left: 0.5rem;
transition: color 0.15s, border-color 0.15s;
}
.shards-link:hover { color: #7ecfcf; border-color: rgba(126, 207, 207, 0.7); }
.shards-icon {
font-size: 22px;
color: #7ecfcf;
position: relative;
top: -0.1em;
}
.shards-value {
font-family: 'Cinzel', serif;
font-size: 28px;
font-weight: 700;
color: #7ecfcf;
}
.shards-label {
font-family: 'Cinzel', serif;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
color: rgba(126, 207, 207, 0.5);
margin-top: 4px;
}
.section-divider {
height: 1px;
background: rgba(107, 76, 30, 0.3);