Fuxi/application/pages/challenges/[id].vue
2023-12-12 20:20:36 +08:00

130 lines
3.4 KiB
Vue

<template>
<div class="md:max-w-[720px] mx-auto">
<n-card segmented>
<template #header>
<n-page-header @back="navigateTo('/')">
<template #title>Challenge #{{ challenge?.id }}</template>
<template #subtitle>
<div class="flex items-center gap-2">
<n-tag size="small" class="case-capital">{{ challenge?.status?.replaceAll("-", " ") }}</n-tag>
</div>
</template>
</n-page-header>
</template>
<section>
<problem-solution-program
v-if="problem.type === 'programming'"
v-model:answers="answers"
:challenge="challenge"
:problem="problem"
/>
</section>
<template #action>
<div class="w-full flex justify-between">
<div class="flex gap-2">
<n-button secondary circle class="rounded-[4px]" type="warning" :disabled="submitting" @click="save">
<template #icon>
<n-icon :component="Save" />
</template>
</n-button>
</div>
<div class="flex gap-2">
<n-button secondary type="error" :disabled="submitting" @click="abandon">放弃</n-button>
<n-button type="primary" :disabled="submitting" @click="submit">提交</n-button>
</div>
</div>
</template>
</n-card>
</div>
</template>
<script setup lang="ts">
import { NButton, NCard, NPageHeader, NTag, NIcon, useDialog, useMessage } from "naive-ui";
import { Save } from "@vicons/carbon";
const route = useRoute();
const client = useSupabaseClient();
const message = useMessage();
const dialog = useDialog();
const submitting = ref(false);
const { data: challenge } = await client
.from("challenges")
.select<any, any>("*")
.eq("id", route.params.id)
.single();
const { data: problem } = await client
.from("problems")
.select<any, any>("*")
.eq("id", challenge?.problem)
.single();
useHead({
title: challenge ? `挑战 #${challenge.id}` : "挑战 #404"
});
const answers = ref(challenge?.answers ?? {});
async function save() {
submitting.value = true;
const instance = message.loading("正在保存,请稍后……");
const { error } = await client
.from("challenges")
// @ts-ignore
.update<any>({
answers: answers.value
})
.eq("id", challenge.id);
if (error != null) {
message.error(`Something went wrong... ${error.message}`);
}
instance.destroy();
submitting.value = false;
}
onMounted(() => {
document.addEventListener("keydown", (event) => {
const prefixKey = navigator.platform.indexOf("Mac") == 0 ? event.metaKey : event.ctrlKey;
if (prefixKey && event.key == "s") {
event.preventDefault();
save();
}
});
});
function abandon() {
const instance = dialog.warning({
title: "警告",
content: "你确定要放弃该次挑战?这会让该挑战立刻转化为放弃状态,并且扣除 5 点社会信用点,三思而后行!",
positiveText: "确定",
negativeText: "再试试",
onPositiveClick: async () => {
await client
.from("challenges")
// @ts-ignore
.update<any>({ status: "abandoned" })
.eq("id", challenge.id);
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
instance.loading = true;
message.info("已放弃挑战该题");
await delay(1850);
window.close();
}
});
}
async function submit() {
}
</script>