178 lines
4.1 KiB
Plaintext
178 lines
4.1 KiB
Plaintext
package component
|
|
|
|
import (
|
|
"fmt"
|
|
common "forge.cadoles.com/wpetit/kouiz/internal/http/handler/webui/common/component"
|
|
"forge.cadoles.com/wpetit/kouiz/internal/store"
|
|
"math"
|
|
"strconv"
|
|
)
|
|
|
|
type LeaderboardPageVModel struct {
|
|
Player *store.Player
|
|
Players []*store.Player
|
|
PlayerRank int
|
|
}
|
|
|
|
templ LeaderboardPage(vmodel LeaderboardPageVModel) {
|
|
@common.AppPage(common.WithPageOptions(
|
|
common.WithTitle("Tableau des scores"),
|
|
)) {
|
|
<h3 class="title">Podium</h3>
|
|
{{ podium := getPodium(vmodel.Players) }}
|
|
<div class="podium">
|
|
<div class="podium-position podium-second">
|
|
<div class="podium-player">
|
|
<span class="has-text-weight-bold is-uppercase">
|
|
for i, p := range podium[1] {
|
|
if i > 0 {
|
|
<br/>
|
|
}
|
|
<span>{ p.Name }</span>
|
|
}
|
|
</span>
|
|
<br/>
|
|
if len(podium[1]) > 0 {
|
|
<span class="has-text-grey is-size-7">{ fmt.Sprintf("%d", podium[1][0].Score) }pts</span>
|
|
}
|
|
</div>
|
|
<div class="podium-step">2ème</div>
|
|
</div>
|
|
<div class="podium-position podium-first">
|
|
<div class="podium-player">
|
|
<span class="icon is-size-4 has-text-warning"><i class="fas fa-trophy"></i></span>
|
|
<br/>
|
|
<span class="has-text-weight-bold is-uppercase">
|
|
for i, p := range podium[0] {
|
|
if i > 0 {
|
|
<br/>
|
|
}
|
|
<span>{ p.Name }</span>
|
|
}
|
|
</span>
|
|
<br/>
|
|
if len(podium[0]) > 0 {
|
|
<span class="has-text-grey is-size-7">{ fmt.Sprintf("%d", podium[0][0].Score) }pts</span>
|
|
}
|
|
</div>
|
|
<div class="podium-step">1er</div>
|
|
</div>
|
|
<div class="podium-position podium-third">
|
|
<div class="podium-player">
|
|
<span class="has-text-weight-bold is-uppercase">
|
|
for i, p := range podium[2] {
|
|
if i > 0 {
|
|
<br/>
|
|
}
|
|
<span>{ p.Name }</span>
|
|
}
|
|
</span>
|
|
<br/>
|
|
if len(podium[2]) > 0 {
|
|
<span class="has-text-grey is-size-7">{ fmt.Sprintf("%d", podium[2][0].Score) }pts</span>
|
|
}
|
|
</div>
|
|
<div class="podium-step">3ème</div>
|
|
</div>
|
|
</div>
|
|
<h3 class="title mt-5">Tableau des scores</h3>
|
|
<div class="table-container">
|
|
<table class="table is-fullwidth">
|
|
<thead>
|
|
<tr>
|
|
<th>Position</th>
|
|
<th>Pseudonyme</th>
|
|
<th>Score</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
for i, p := range vmodel.Players {
|
|
<tr
|
|
if p.ID == vmodel.Player.ID {
|
|
class="has-text-weight-bold is-info"
|
|
}
|
|
id={ fmt.Sprintf("player-%d", p.ID) }
|
|
>
|
|
<td>{ strconv.FormatInt(int64(i+1), 10) }</td>
|
|
<td>{ p.Name }</td>
|
|
<td>{ strconv.FormatInt(int64(p.Score), 10) }</td>
|
|
</tr>
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<style>
|
|
.podium {
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: flex-end;
|
|
justify-content: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.podium .podium-step {
|
|
width: 100px;
|
|
justify-content: center;
|
|
align-items: center;
|
|
display: flex;
|
|
font-weight: bold;
|
|
color: white;
|
|
text-shadow: 1px 1px #333;
|
|
}
|
|
|
|
.podium .podium-position {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.podium .podium-player {
|
|
text-shadow: none;
|
|
color: #333;
|
|
text-align: center;
|
|
}
|
|
|
|
.podium .podium-first .podium-step {
|
|
height: 70px;
|
|
background-color: hsl(141, 71%, 48%) ;
|
|
}
|
|
|
|
.podium .podium-second .podium-step {
|
|
height: 50px;
|
|
background-color: hsl(204, 86%, 53%);
|
|
}
|
|
|
|
.podium .podium-third .podium-step {
|
|
height: 30px;
|
|
background-color: #66d1ff;
|
|
}
|
|
</style>
|
|
}
|
|
}
|
|
|
|
func getPodium(players []*store.Player) [][]*store.Player {
|
|
score := math.MaxInt
|
|
podium := make([][]*store.Player, 3)
|
|
podiumIndex := -1
|
|
for _, p := range players {
|
|
if p.Score < score {
|
|
score = p.Score
|
|
podiumIndex++
|
|
if podiumIndex > 2 {
|
|
break
|
|
}
|
|
|
|
podium[podiumIndex] = append(podium[podiumIndex], p)
|
|
continue
|
|
}
|
|
|
|
if p.Score == score {
|
|
podium[podiumIndex] = append(podium[podiumIndex], p)
|
|
continue
|
|
}
|
|
}
|
|
|
|
return podium
|
|
}
|