add contest detail.

This commit is contained in:
2023-01-23 22:56:50 +08:00
parent b060262f70
commit 7def5a4d83
8 changed files with 118 additions and 11 deletions

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { Contest } from "~/utils/types"
import { ContestType } from "~/utils/constants"
defineProps<{ contest: Contest }>()
</script>
@@ -8,7 +9,7 @@ defineProps<{ contest: Contest }>()
<span>{{ contest.title }}</span>
<n-icon
class="lockIcon"
v-if="contest.contest_type === 'Password Protected'"
v-if="contest.contest_type === ContestType.private"
>
<i-ep-lock />
</n-icon>

View File

@@ -1,7 +1,79 @@
<script setup lang="ts">
const route = useRoute()
import { Contest } from "utils/types"
import { CONTEST_STATUS, ContestStatus, ContestType } from "utils/constants"
import { parseTime } from "utils/functions"
import { getContest, getContestAccess } from "../api"
import { isDesktop } from "~/shared/composables/breakpoints"
const props = defineProps<{
contestID: string
}>()
const contest = ref<Contest>()
async function init() {
const res = await getContest(props.contestID)
contest.value = res.data
if (contest.value?.contest_type === ContestType.private) {
const res = await getContestAccess(props.contestID)
// TODO: 这里 access 的逻辑不清楚
console.log(res.data)
}
}
onMounted(init)
</script>
<template></template>
<template>
<n-card v-if="contest">
<template #header>
<n-space align="center">
<n-tag :type="CONTEST_STATUS[contest.status]['type']">
{{ CONTEST_STATUS[contest.status]["name"] }}
</n-tag>
<span>{{ contest.title }}</span>
<n-icon
v-if="contest.contest_type === ContestType.private"
class="lockIcon"
>
<i-ep-lock />
</n-icon>
</n-space>
</template>
<div v-html="contest.description"></div>
<n-descriptions bordered :column="isDesktop ? 5 : 2">
<n-descriptions-item
:span="isDesktop ? 1 : 2"
v-if="contest.status !== ContestStatus.finished"
>
<template #label>
<span v-if="contest.status === ContestStatus.not_started">
距离比赛开始还有
</span>
<span v-if="contest.status === ContestStatus.underway">
距离比赛结束还有
</span>
</template>
<n-space align="center">
<n-tag :type="CONTEST_STATUS[contest.status]['type']">
<n-countdown :duration="500000" />
</n-tag>
</n-space>
</n-descriptions-item>
<n-descriptions-item label="开始时间">
{{ parseTime(contest.start_time, "YYYY年M月D日 hh:mm:ss") }}
</n-descriptions-item>
<n-descriptions-item label="结束时间">
{{ parseTime(contest.end_time, "YYYY年M月D日 hh:mm:ss") }}
</n-descriptions-item>
<n-descriptions-item label="比赛类型">
{{ contest.contest_type === ContestType.private ? "需要密码" : "公开" }}
</n-descriptions-item>
<n-descriptions-item label="发起人">
{{ contest.created_by.username }}
</n-descriptions-item>
</n-descriptions>
</n-card>
</template>
<style scoped></style>
<style scoped>
.lockIcon {
transform: translateY(2px);
}
</style>

View File

@@ -4,7 +4,7 @@ import { getContestList } from "oj/api"
import Pagination from "~/shared/Pagination.vue"
import { filterEmptyValue, parseTime, duration } from "utils/functions"
import { Contest } from "utils/types"
import { CONTEST_STATUS } from "~/utils/constants"
import { ContestType, CONTEST_STATUS } from "~/utils/constants"
import ContestTitle from "./components/ContestTitle.vue"
import { useUserStore } from "~/shared/store/user"
import { toggleLogin } from "~/shared/composables/modal"
@@ -108,7 +108,7 @@ function rowProps(row: Contest) {
return {
style: "cursor: pointer",
onClick() {
if (!userStore.isAuthed && row.contest_type === "Password Protected") {
if (!userStore.isAuthed && row.contest_type === ContestType.private) {
toggleLogin(true)
} else {
router.push("/contest/" + row.id)