peak search, denser catalog, profiles, filename parsing, themed map controls
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<script lang="ts">
|
||||
import Avatar from '$lib/components/Avatar.svelte';
|
||||
import ActivityItem from '$lib/components/ActivityItem.svelte';
|
||||
import StatTile from '$lib/components/StatTile.svelte';
|
||||
import { fmtDistance, fmtDuration, fmtElevation } from '$lib/format';
|
||||
|
||||
let { data } = $props();
|
||||
const p = $derived(data.profile);
|
||||
const memberSince = $derived(
|
||||
new Date(p.created_at + 'Z').toLocaleDateString('en-GB', { month: 'long', year: 'numeric' })
|
||||
);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{p.username} · Streba</title>
|
||||
</svelte:head>
|
||||
|
||||
<div class="head card">
|
||||
<Avatar avatar={p.avatar} username={p.username} size={88} />
|
||||
<div class="who">
|
||||
<h1>{p.username}</h1>
|
||||
<p class="meta">
|
||||
{#if p.location}{p.location} · {/if}member since {memberSince}
|
||||
</p>
|
||||
{#if p.bio}<p class="bio">{p.bio}</p>{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="kpis">
|
||||
<StatTile label="Activities" value={String(data.stats.activities)} />
|
||||
<StatTile label="Distance" value={fmtDistance(data.stats.distance_m)} />
|
||||
<StatTile label="Ascent" value={fmtElevation(data.stats.elev_gain_m)} />
|
||||
<StatTile label="Moving time" value={fmtDuration(data.stats.moving_s)} />
|
||||
</div>
|
||||
|
||||
{#if data.peaksReached > 0}
|
||||
<div class="card peak-strip">
|
||||
⛰ {data.peaksReached} peak{data.peaksReached === 1 ? '' : 's'} reached{#if data.highestAscent},
|
||||
highest: <strong>{data.highestAscent.name}</strong>
|
||||
({Math.round(data.highestAscent.elevation_m ?? 0).toLocaleString('en-US')} m){/if}.
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<h2>Recent activities</h2>
|
||||
{#if data.activities.length === 0}
|
||||
<div class="card empty">No activities yet.</div>
|
||||
{:else}
|
||||
<div class="card list">
|
||||
{#each data.activities as activity (activity.id)}
|
||||
<ActivityItem {activity} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.head {
|
||||
display: flex;
|
||||
gap: 1.25rem;
|
||||
align-items: flex-start;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
.who h1 {
|
||||
margin: 0;
|
||||
}
|
||||
.meta {
|
||||
margin: 0.15rem 0 0;
|
||||
color: var(--text-muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.bio {
|
||||
margin: 0.6rem 0 0;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.92rem;
|
||||
white-space: pre-line;
|
||||
}
|
||||
.kpis {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||
gap: 0.75rem;
|
||||
}
|
||||
.peak-strip {
|
||||
margin-top: 1.25rem;
|
||||
padding: 0.85rem 1.15rem;
|
||||
color: var(--text-secondary);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.peak-strip strong {
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.list :global(.item:not(:last-child)) {
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
.empty {
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user