feat(market): graph for fun

This commit is contained in:
2026-10-07 21:54:24 +02:00
parent 382ba01f3e
commit 8509be548e
11 changed files with 669 additions and 5 deletions
@@ -7,6 +7,8 @@ import { useMarketStore } from "../stores/market";
import { useEventPath } from "../composables/useEventPath";
import type { Market, MarketOption } from "../types";
import type { UserBetSchema } from "../api/types.gen";
import PayoutChart from "./charts/PayoutChart.vue";
import BetHistoryChart from "./charts/BetHistoryChart.vue";
const props = defineProps<{
market: Market;
@@ -19,7 +21,7 @@ const emit = defineEmits<{
const { t } = useI18n();
const eventPath = useEventPath();
const marketStore = useMarketStore();
const { userInfo, userBets } = storeToRefs(marketStore);
const { userInfo, userBets, userPoints } = storeToRefs(marketStore);
const selectedOption = ref<string | null>(null);
const betAmount = ref<number>(0);
@@ -29,6 +31,7 @@ const existingBet = ref<UserBetSchema | null>(null);
const showResolveModal = ref(false);
const selectedWinningOption = ref<string | null>(null);
const resolveLoading = ref(false);
const showCharts = ref(true);
const timeRemaining = computed(() => {
const endDate = new Date(props.market.end_date).getTime();
@@ -80,6 +83,19 @@ const getPotentialGain = (option: MarketOption) => {
return Math.round(existingBet.value.amount * multiplier * props.market.multiplier);
};
const selectedMarketOption = computed(() =>
props.market.options.find((opt) => opt.uuid === selectedOption.value) ?? null,
);
// Payout chart only makes sense while the user can still bet on the selected option
const showPayoutChart = computed(
() => props.market.status === "open" && !!userInfo.value?.is_authenticated && !!selectedMarketOption.value,
);
const existingAmountOnSelected = computed(() =>
existingBet.value && existingBet.value.option.uuid === selectedOption.value ? existingBet.value.amount : 0,
);
const closeMarket = async () => {
loading.value = true;
error.value = "";
@@ -147,7 +163,7 @@ const placeBet = async () => {
if (!response.error) {
// Reload user bets to reflect the new bet
await marketStore.loadUserBets(eventPath);
await Promise.all([marketStore.loadUserBets(eventPath), marketStore.loadUserPoints(eventPath)]);
updateExistingBet();
betAmount.value = 0;
} else {
@@ -286,6 +302,20 @@ const updateExistingBet = () => {
</div>
</div>
<!-- Charts -->
<div class="px-8 pb-2">
<button @click="showCharts = !showCharts" class="btn btn-ghost btn-xs">
<i :class="['mdi', showCharts ? 'mdi-chevron-up' : 'mdi-chart-line']"></i>
{{ showCharts ? t("components.marketCharts.hideCharts") : t("components.marketCharts.showCharts") }}
</button>
</div>
<div v-if="showCharts" class="card-body py-4 gap-6">
<PayoutChart v-if="showPayoutChart && selectedMarketOption" :market="market" :option="selectedMarketOption"
:existing-amount="existingAmountOnSelected" :stake="betAmount || 0"
:max-stake="existingAmountOnSelected + userPoints" />
<BetHistoryChart :market="market" />
</div>
<!-- Bet Input -->
<div v-if="market.status === 'open' && userInfo?.is_authenticated && selectedOption" class="card-body py-4">
<div class="form-control gap-3">