Add stats, profiles, avatars and palaute
Step 6. The surfaces around the review loop. - Nine leaderboards, ordered and limited in SQL, each with a deterministic tie-break so a tied board doesn't reshuffle between reloads. Min 3 reviews to qualify, for reviewer boards too - Profiles show counts and history-wide averages and the member's songs, never a list of their reviews — per-song opinion stays gated - Avatars: 5MB in, 256px JPEG out, ffmpeg's re-encode being the validation. No upload still means initials, and avatars are public - Changing your own password requires the current one and drops your other sessions - Palaute: free text plus the page you were on, carried in a footer link, and the user agent from the header. Reporters see their own; the admin resolves them with a timestamp rather than a status enum - Admin gained the song list with delete, the reports page, and an open-report count on the dashboard Two theme fixes the screenshots caught: leaderboard ranks need a CSS counter because display:grid suppresses list markers, and count-based boards were printing 3.0 where they mean 3.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
{{define "content"}}
|
||||
{{$p := .Data}}
|
||||
<div class="profilehead">
|
||||
{{if $p.Avatar}}
|
||||
<img class="avatar big" src="/avatars/{{$p.ID}}" alt="">
|
||||
{{else}}
|
||||
<span class="avatar big">{{$p.Initials}}</span>
|
||||
{{end}}
|
||||
<div>
|
||||
<h1>{{$p.Name}}</h1>
|
||||
<p class="muted">Liittyi {{fidate $p.CreatedAt}}{{if $p.Email}} · {{$p.Email}}{{end}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="statgrid">
|
||||
<div class="statcard"><span class="statvalue">{{$p.Stats.SongsSubmitted}}</span><span class="muted small">kappaletta</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{$p.Stats.ReviewsWritten}}</span><span class="muted small">arvostelua</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{if $p.Stats.AverageGiven}}{{score $p.Stats.AverageGiven}}{{else}}—{{end}}</span><span class="muted small">antanut ka.</span></div>
|
||||
<div class="statcard"><span class="statvalue">{{if $p.Stats.AverageReceived}}{{score $p.Stats.AverageReceived}}{{else}}—{{end}}</span><span class="muted small">saanut ka.</span></div>
|
||||
</div>
|
||||
|
||||
{{if $p.Own}}
|
||||
<details class="editbox">
|
||||
<summary>Muokkaa tietoja</summary>
|
||||
<form method="post" action="/profile" enctype="multipart/form-data" class="stack">
|
||||
<label>Nimi <input name="name" value="{{$p.Name}}" maxlength="50" required></label>
|
||||
<label>Sähköposti <input type="email" name="email" value="{{$p.Email}}" required></label>
|
||||
<label>Kuva <input type="file" name="avatar" accept="image/*"></label>
|
||||
<label>Nykyinen salasana <input type="password" name="current_password" autocomplete="current-password"></label>
|
||||
<label>Uusi salasana <input type="password" name="new_password" autocomplete="new-password"></label>
|
||||
<button type="submit">Tallenna</button>
|
||||
</form>
|
||||
<p class="muted small">Salasanan vaihto vaatii nykyisen salasanan ja kirjaa ulos muut laitteesi.</p>
|
||||
</details>
|
||||
{{end}}
|
||||
|
||||
<section>
|
||||
<h2>Kappaleet</h2>
|
||||
{{if $p.Songs}}
|
||||
<div class="songgrid">{{range $p.Songs}}{{template "songcard" .}}{{end}}</div>
|
||||
{{else}}
|
||||
<p class="muted">Ei vielä yhtään kappaletta.</p>
|
||||
{{end}}
|
||||
</section>
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user