Files
thebet365/apps/player/src/components/desktop/DesktopShell.vue

155 lines
5.1 KiB
Vue

<script setup lang="ts">
import { computed, onMounted, watch } from 'vue';
import { useRoute, RouterView } from 'vue-router';
import { useI18n } from 'vue-i18n';
import DesktopTopNav from './DesktopTopNav.vue';
import DesktopOddsBetPopover from './DesktopOddsBetPopover.vue';
import SportsCategoryBar from './SportsCategoryBar.vue';
import LeagueSidebar from './LeagueSidebar.vue';
import MatchSidebar from './MatchSidebar.vue';
import DesktopBetSlipRail from './DesktopBetSlipRail.vue';
import FloatingMailbox from '../FloatingMailbox.vue';
import AnnouncementMarquee from '../AnnouncementMarquee.vue';
import { usePlayerHome } from '../../composables/usePlayerHome';
import { useAuthStore } from '../../stores/auth';
import { useBetSlipStore } from '../../stores/betSlip';
const route = useRoute();
const { locale } = useI18n();
const auth = useAuthStore();
const slip = useBetSlipStore();
const { load: loadPlayerHome, announcements } = usePlayerHome();
const layoutMode = computed<'betting' | 'account' | 'hub' | 'marketing'>(() => {
const p = route.path;
if (p === '/bet' || p.startsWith('/match/') || p.startsWith('/outright/')) {
return 'betting';
}
if (
p === '/bets' ||
p.startsWith('/bets/') ||
p.startsWith('/wallet') ||
p.startsWith('/profile')
) {
return 'account';
}
if (p.startsWith('/announcements')) {
return 'hub';
}
if (p.startsWith('/messages')) {
return 'hub';
}
return 'marketing';
});
const isMatchDetail = computed(() => route.path.startsWith('/match/'));
const isBettingDetail = computed(
() => route.path.startsWith('/match/') || route.path.startsWith('/outright/'),
);
const showBetSlipRail = computed(() => {
const p = route.path;
if (p === '/bets' || p.startsWith('/bets/')) return false;
if (p.startsWith('/wallet') || p.startsWith('/profile')) return false;
if (route.params.id && (p.startsWith('/announcements/') || p.startsWith('/messages/'))) {
return false;
}
return true;
});
onMounted(() => {
void loadPlayerHome(true);
});
watch(locale, (next, prev) => {
if (prev && next !== prev) void loadPlayerHome(true);
});
watch(
() => auth.token,
() => {
void loadPlayerHome(true);
},
);
</script>
<template>
<div
class="desktop-shell"
:class="{
'betslip-collapsed': showBetSlipRail && !slip.panelExpanded,
'betslip-hidden': !showBetSlipRail,
}"
>
<div v-if="announcements && announcements.length" class="desktop-marquee-wrap">
<AnnouncementMarquee :items="announcements" embedded />
</div>
<header class="desktop-header-wrap">
<DesktopTopNav />
</header>
<div class="desktop-body">
<div class="desktop-main-container">
<!-- Betting Layout -->
<div v-if="layoutMode === 'betting'" class="desktop-layout-betting-wrap">
<div class="desktop-betting-sports-row">
<SportsCategoryBar />
</div>
<div class="desktop-layout-betting">
<aside class="desktop-betting-left">
<LeagueSidebar v-if="!isMatchDetail" />
<MatchSidebar v-else />
</aside>
<main class="desktop-betting-center" :class="{ 'is-betting-detail': isBettingDetail }">
<RouterView v-slot="{ Component, route: viewRoute }">
<KeepAlive v-if="viewRoute.meta.keepAlive" :max="10">
<component :is="Component" :key="viewRoute.path" />
</KeepAlive>
<component v-else :is="Component" :key="viewRoute.fullPath" />
</RouterView>
</main>
</div>
</div>
<!-- Account Layout -->
<div v-else-if="layoutMode === 'account'" class="desktop-layout-account">
<main class="desktop-account-center">
<RouterView v-slot="{ Component, route: viewRoute }">
<KeepAlive v-if="viewRoute.meta.keepAlive" :max="10">
<component :is="Component" :key="viewRoute.path" />
</KeepAlive>
<component v-else :is="Component" :key="viewRoute.fullPath" />
</RouterView>
</main>
</div>
<!-- Hub Layout: Messages / Announcements split pane -->
<div v-else-if="layoutMode === 'hub'" class="desktop-layout-hub-outer">
<RouterView v-slot="{ Component, route: viewRoute }">
<KeepAlive v-if="viewRoute.meta.keepAlive" :max="10">
<component :is="Component" :key="viewRoute.path" />
</KeepAlive>
<component v-else :is="Component" :key="viewRoute.fullPath" />
</RouterView>
</div>
<!-- Marketing/Single Column Layout -->
<div v-else class="desktop-layout-marketing no-scrollbar">
<main class="desktop-marketing-content">
<RouterView v-slot="{ Component, route: viewRoute }">
<KeepAlive v-if="viewRoute.meta.keepAlive" :max="10">
<component :is="Component" :key="viewRoute.path" />
</KeepAlive>
<component v-else :is="Component" :key="viewRoute.fullPath" />
</RouterView>
</main>
</div>
</div>
<DesktopBetSlipRail v-if="showBetSlipRail" />
</div>
<FloatingMailbox />
<DesktopOddsBetPopover />
</div>
</template>