✨ Challenges Modification
This commit is contained in:
		| @@ -1,11 +1,70 @@ | |||||||
| <template> | <template> | ||||||
|  |   <client-only> | ||||||
|  |     <vue-monaco-editor | ||||||
|  |       :options="options" | ||||||
|  |       :language="answers.language ?? 'text'" | ||||||
|  |       v-model:value="answers.code" | ||||||
|  |       class="min-h-[360px] code-editor" | ||||||
|  |     /> | ||||||
|  |   </client-only> | ||||||
|  |  | ||||||
|  |   <n-divider class="mx-[-24px] w-[calc(100%+48px)] divider-below-code" /> | ||||||
|  |  | ||||||
|  |   <section> | ||||||
|  |     <n-space> | ||||||
|  |       <n-select | ||||||
|  |         :options="languages" | ||||||
|  |         v-model:value="answers.language" | ||||||
|  |         placeholder="Programming Language" | ||||||
|  |         class="w-120" | ||||||
|  |       /> | ||||||
|  |     </n-space> | ||||||
|  |   </section> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
|  | import { NDivider, NSpace, NSelect } from "naive-ui"; | ||||||
|  | import { VueMonacoEditor } from "@guolao/vue-monaco-editor"; | ||||||
|  |  | ||||||
|  | const props = defineProps<{ | ||||||
|  |   challenge: any, | ||||||
|  |   problem: any, | ||||||
|  |   answers: any, | ||||||
|  | }>(); | ||||||
|  | const emits = defineEmits(["update:answers"]); | ||||||
|  |  | ||||||
|  | const answers = ref(props.challenge?.answers ?? {}); | ||||||
|  |  | ||||||
|  | watch(answers, (v) => { | ||||||
|  |   emits("update:answers", v); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | const options = { | ||||||
|  |   minimap: { enabled: false } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const languageWhitelist: string[] = props.problem?.languageWhitelist ?? []; | ||||||
|  | const languageBlacklist: string[] = props.problem?.languageBlacklist ?? []; | ||||||
|  |  | ||||||
|  | const languages = [ | ||||||
|  |   { label: "C", value: "c" }, | ||||||
|  |   { label: "C++", value: "cpp" }, | ||||||
|  |   { label: "JSON", value: "json" }, // Huh? | ||||||
|  | ].filter((item) => { | ||||||
|  |   return languageWhitelist.filter((x) => new RegExp(x, item.value)).length > 0 || | ||||||
|  |     !(languageBlacklist.filter((x) => new RegExp(x, item.value)).length > 0); | ||||||
|  | }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style scoped> | <style scoped> | ||||||
|  | .code-editor { | ||||||
|  |   min-width: calc(100% + 48px); | ||||||
|  |   margin-top: -20px; | ||||||
|  |   margin-left: -24px; | ||||||
|  |   margin-right: -24px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .divider-below-code { | ||||||
|  |   margin-top: 0 !important; | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
| @@ -12,15 +12,14 @@ | |||||||
|         </n-page-header> |         </n-page-header> | ||||||
|       </template> |       </template> | ||||||
|  |  | ||||||
|       <client-only> |       <section> | ||||||
|         <vue-monaco-editor |         <problem-solution-program | ||||||
|           :options="options" |           v-if="problem.type === 'programming'" | ||||||
|           v-model:value="answer.code" |           v-model:answers="answers" | ||||||
|           class="min-h-[360px] code-editor" |           :challenge="challenge" | ||||||
|  |           :problem="problem" | ||||||
|         /> |         /> | ||||||
|       </client-only> |       </section> | ||||||
|  |  | ||||||
|       <n-divider class="mx-[-24px] w-[calc(100%+48px)] divider-below-code" /> |  | ||||||
|  |  | ||||||
|       <template #action> |       <template #action> | ||||||
|         <div class="w-full flex justify-between"> |         <div class="w-full flex justify-between"> | ||||||
| @@ -42,8 +41,7 @@ | |||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { NButton, NCard, NDivider, NPageHeader, NTag, NIcon, useDialog, useMessage } from "naive-ui"; | import { NButton, NCard, NPageHeader, NTag, NIcon, useDialog, useMessage } from "naive-ui"; | ||||||
| import { VueMonacoEditor } from "@guolao/vue-monaco-editor"; |  | ||||||
| import { Save } from "@vicons/carbon"; | import { Save } from "@vicons/carbon"; | ||||||
|  |  | ||||||
| const route = useRoute(); | const route = useRoute(); | ||||||
| @@ -51,10 +49,6 @@ const client = useSupabaseClient(); | |||||||
| const message = useMessage(); | const message = useMessage(); | ||||||
| const dialog = useDialog(); | const dialog = useDialog(); | ||||||
|  |  | ||||||
| const options = { |  | ||||||
|   minimap: { enabled: false } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| const submitting = ref(false); | const submitting = ref(false); | ||||||
|  |  | ||||||
| const { data: challenge } = await client | const { data: challenge } = await client | ||||||
| @@ -63,16 +57,48 @@ const { data: challenge } = await client | |||||||
|   .eq("id", route.params.id) |   .eq("id", route.params.id) | ||||||
|   .single(); |   .single(); | ||||||
|  |  | ||||||
|  | const { data: problem } = await client | ||||||
|  |   .from("problems") | ||||||
|  |   .select<any, any>("*") | ||||||
|  |   .eq("id", challenge?.problem) | ||||||
|  |   .single(); | ||||||
|  |  | ||||||
| useHead({ | useHead({ | ||||||
|   title: challenge ? `挑战 #${challenge.id}` : "挑战 #404" |   title: challenge ? `挑战 #${challenge.id}` : "挑战 #404" | ||||||
| }); | }); | ||||||
|  |  | ||||||
| const answer = ref(challenge?.answer ?? {}); | const answers = ref(challenge?.answers ?? {}); | ||||||
|  |  | ||||||
| async function save() { | 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() { | function abandon() { | ||||||
|   const instance = dialog.warning({ |   const instance = dialog.warning({ | ||||||
|     title: "警告", |     title: "警告", | ||||||
| @@ -88,7 +114,7 @@ function abandon() { | |||||||
|  |  | ||||||
|       const delay = (ms: number) => new Promise(res => setTimeout(res, ms)); |       const delay = (ms: number) => new Promise(res => setTimeout(res, ms)); | ||||||
|  |  | ||||||
|       instance.loading = true |       instance.loading = true; | ||||||
|       message.info("已放弃挑战该题"); |       message.info("已放弃挑战该题"); | ||||||
|  |  | ||||||
|       await delay(1850); |       await delay(1850); | ||||||
| @@ -101,16 +127,3 @@ async function submit() { | |||||||
|  |  | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <style scoped> |  | ||||||
| .code-editor { |  | ||||||
|   min-width: calc(100% + 48px); |  | ||||||
|   margin-top: -20px; |  | ||||||
|   margin-left: -24px; |  | ||||||
|   margin-right: -24px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .divider-below-code { |  | ||||||
|   margin-top: 0 !important; |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
|   | |||||||
| @@ -32,5 +32,5 @@ policy "Enable update access for users' own items" on "public"."challenges" | |||||||
| as permissive for | as permissive for | ||||||
| update | update | ||||||
|     to public |     to public | ||||||
|     using (author = auth.uid()) |     using (author = auth.uid() and status = 'in-progress') | ||||||
| with check (author = auth.uid()) | with check (author = auth.uid()) | ||||||
		Reference in New Issue
	
	Block a user