feat: first back recording and display (#12)
All checks were successful
pipeline / lint-and-format (push) Successful in 4m35s
pipeline / build-and-push-images (push) Successful in 1m39s

Record first backs, group them by item sets and show the most popular ones, with gold and %, in the frontend.
This commit is contained in:
2026-04-28 20:10:20 +02:00
parent 7712abe3f0
commit db2ca353c5
6 changed files with 452 additions and 6 deletions

View File

@@ -0,0 +1,107 @@
<script setup lang="ts">
defineProps<{
firstBacks: FirstBackGroup[]
itemMap: Map<number, Item>
}>()
</script>
<template>
<div v-if="firstBacks && firstBacks.length > 0" class="item-row">
<span class="item-row-label">First Back</span>
<div class="first-back-content">
<div v-for="(group, index) in firstBacks" :key="index" class="first-back-option">
<span class="gold-cost">{{ group.itemSet.totalGold }}g</span>
<div class="option-items">
<template v-for="item in group.itemSet.items" :key="item.itemId">
<div class="item-with-count">
<ItemIcon
v-if="itemMap.get(item.itemId)"
:item="itemMap.get(item.itemId)!"
:size="36"
class="item-cell"
/>
<span v-if="item.count > 1" class="item-count">x{{ item.count }}</span>
</div>
</template>
</div>
<span class="pickrate">{{ (group.pickrate * 100).toFixed(0) }}%</span>
</div>
</div>
</div>
</template>
<style scoped>
.item-row {
display: flex;
flex-direction: column;
gap: 4px;
max-width: 400px;
}
.item-row-label {
font-size: 0.8rem;
font-weight: 500;
color: var(--color-on-surface);
opacity: 0.6;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.first-back-content {
display: flex;
flex-wrap: wrap;
gap: 16px;
overflow-x: hidden;
}
.first-back-option {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
flex-shrink: 0;
}
.option-items {
display: flex;
gap: 2px;
}
.item-with-count {
position: relative;
display: flex;
align-items: center;
}
.item-cell {
flex-shrink: 0;
}
.item-count {
position: absolute;
bottom: -1px;
right: -1px;
background: rgba(0, 0, 0, 0.85);
color: #fff;
font-size: 0.55rem;
font-weight: 600;
padding: 0 2px;
border-radius: 2px;
min-width: 12px;
text-align: center;
}
.pickrate {
font-size: 0.65rem;
color: var(--color-on-surface);
opacity: 0.6;
white-space: nowrap;
}
.gold-cost {
font-size: 0.6rem;
color: #ffd700;
opacity: 0.8;
white-space: nowrap;
}
</style>