Problems

This commit is contained in:
LittleSheep 2023-12-10 22:54:04 +08:00
parent 16aed743d9
commit caff256949
10 changed files with 134 additions and 49 deletions

View File

@ -1,6 +1,7 @@
<template> <template>
<n-message-provider> <n-message-provider>
<nuxt-layout> <nuxt-layout>
<nuxt-loading-indicator />
<nuxt-page /> <nuxt-page />
</nuxt-layout> </nuxt-layout>
</n-message-provider> </n-message-provider>

View File

@ -13,3 +13,11 @@ body {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
code, pre {
font-family: "IBM Plex Mono", monospace;
}
pre {
border-radius: 4px;
}

Binary file not shown.

View File

@ -6,7 +6,7 @@
<div class="text-xs font-normal">每天进步一点点</div> <div class="text-xs font-normal">每天进步一点点</div>
</template> </template>
<n-list clickable hoverable> <n-list clickable hoverable>
<n-list-item v-for="item in (problems as any[])" class="px-[24px]"> <n-list-item v-for="item in problems" class="px-[24px]" @click="jump(item)">
<n-thing :title="item?.title"> <n-thing :title="item?.title">
<template #description> <template #description>
<div class="text-xs flex gap-2"> <div class="text-xs flex gap-2">
@ -26,5 +26,9 @@ import { NCard, NList, NListItem, NThing, NTag } from "naive-ui";
const client = useSupabaseClient(); const client = useSupabaseClient();
const { data: problems } = await client.from("problems").select(`*`).limit(20); const { data: problems } = await client.from("problems").select<any, any>("*").limit(20);
function jump(item: any) {
navigateTo(`/problems/${item.id}`)
}
</script> </script>

View File

@ -1,24 +1,22 @@
// https://nuxt.com/docs/api/configuration/nuxt-config // https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({ export default defineNuxtConfig({
devtools: { enabled: true }, devtools: { enabled: true },
modules: ["@unocss/nuxt", '@pinia/nuxt', '@nuxtjs/supabase'], modules: ["@unocss/nuxt", "@pinia/nuxt", "@nuxtjs/supabase", "@nuxtjs/mdc"],
app: {
head: {
title: "Fuxi Programming",
titleTemplate: "%s | Fuxi",
},
},
build: { build: {
transpile: transpile:
process.env.NODE_ENV === 'production' process.env.NODE_ENV === "production"
? [ ? ["naive-ui", "vueuc", "@css-render/vue3-ssr", "@juggle/resize-observer"]
'naive-ui', : ["@juggle/resize-observer"],
'vueuc',
'@css-render/vue3-ssr',
'@juggle/resize-observer'
]
: ['@juggle/resize-observer']
}, },
vite: { vite: {
optimizeDeps: { optimizeDeps: {
include: include: process.env.NODE_ENV === "development" ? ["naive-ui", "vueuc", "date-fns-tz/formatInTimeZone"] : [],
process.env.NODE_ENV === 'development' },
? ['naive-ui', 'vueuc', 'date-fns-tz/formatInTimeZone'] },
: [] });
}
}
})

View File

@ -23,6 +23,8 @@
}, },
"dependencies": { "dependencies": {
"@ibm/plex": "^6.3.0", "@ibm/plex": "^6.3.0",
"@supabase/supabase-js": "^2.39.0" "@nuxtjs/mdc": "^0.2.8",
"@supabase/supabase-js": "^2.39.0",
"prismjs": "^1.29.0"
} }
} }

View File

@ -0,0 +1,52 @@
<template>
<div class="md:max-w-[720px] mx-auto">
<n-card segmented>
<template #header>
<n-page-header @back="navigateTo('/')">
<template #title>{{ problem?.title }}</template>
<template #subtitle>
<div class="flex items-center gap-2">
<n-tag size="small" class="case-capital">{{ problem?.type }}</n-tag>
</div>
</template>
</n-page-header>
</template>
<m-d-c :value="problem?.description" class="problem-description" tag="article" />
<n-divider class="mx-[-24px] w-[calc(100%+48px)]" />
<section>
<div v-if="example" class="grid gap-4 -md:gird-cols-1 md:grid-cols-2">
<div>
<div>Example Input</div>
<pre class="language-text" v-if="example?.spec?.stdin">{{ example?.spec?.stdin }}</pre>
<pre class="language-text font-italic" v-else>本题无输入</pre>
</div>
<div>
<div>Example Output</div>
<pre class="language-text" v-if="example?.answer?.stdout">{{ example?.answer?.stdout }}</pre>
<pre class="language-text font-italic" v-else>本题无输出</pre>
</div>
</div>
<n-empty v-else description="本题无公开样例" />
</section>
</n-card>
</div>
</template>
<script setup lang="ts">
import { NCard, NTag, NPageHeader, NDivider, NEmpty } from "naive-ui";
import "prismjs/themes/prism.css";
import "prismjs/prism";
const client = useSupabaseClient();
const route = useRoute();
const { data: problem } = await client.from("problems").select<any, any>("*").eq("id", route.params.id).single();
const { data: example } = await client
.from("problem_cases")
.select<any, any>("*")
.eq("problem", route.params.id)
.single();
</script>

View File

@ -2,18 +2,13 @@ create table public.profiles (
id uuid not null references auth.users on delete cascade, id uuid not null references auth.users on delete cascade,
username varchar(64), username varchar(64),
nickname varchar(256), nickname varchar(256),
school_id int8, school int8,
primary key (id) primary key (id)
); );
alter table public.profiles enable row level security; alter table public.profiles enable row level security;
create policy "Public profiles are viewable by everyone." on profiles for
create policy "Public profiles are viewable by everyone." on profiles select using (true);
for select using (true); create policy "Users can insert their own profile." on profiles for
insert with check (auth.uid() = id);
create policy "Users can insert their own profile." on profiles create policy "Users can update own profile." on profiles for
for insert with check (auth.uid() = id); update using (auth.uid() = id);
create policy "Users can update own profile." on profiles
for update using (auth.uid() = id);

View File

@ -1,19 +1,30 @@
create table create table public.problems (
public.problems ( id bigint generated by default as identity,
id bigint generated by default as identity, title text not null,
title text not null, description text not null,
description text not null, type character varying not null,
type character varying not null, tags character varying [] null,
tags character varying[] null, author uuid null,
author uuid null, metadata jsonb null,
is_draft boolean null default true, is_draft boolean null default true,
is_hidden boolean null default false, is_hidden boolean null default false,
created_at timestamp with time zone null default now(), created_at timestamp with time zone null default now(),
constraint problems_pkey primary key (id), constraint problems_pkey primary key (id),
constraint problems_author_fkey foreign key (author) references auth.users (id) constraint problems_author_fkey foreign key (author) references auth.users (id)
) tablespace pg_default; ) tablespace pg_default;
alter table public.problems enable row level security; alter table public.problems enable row level security;
create policy "Public problems are viewable by everyone." on problems for
create policy "Public problems are viewable by everyone." on problems select using (true);
for select using (true); create table public.problem_cases (
id bigint generated by default as identity,
spec jsonb not null,
limitations jsonb not null,
answer jsonb not null,
problem int8 not null,
is_hidden bool not null default true,
constraint problem_cases_pkey primary key (id),
constraint problem_cases_author_fkey foreign key (problem) references public.problems (id)
) tablespace pg_default;
alter table public.problem_cases enable row level security;
create policy "Public problem cases are viewable by everyone." on problem_cases for
select using (is_hidden = false);

View File

@ -0,0 +1,14 @@
create table public.challenges (
id bigint generated by default as identity,
answers jsonb not null,
details jsonb not null,
author uuid not null,
problem int8 not null,
status varchar(256) not null,
created_at timestamp with time zone null default now(),
constraint challenges_pkey primary key (id),
constraint challenges_author_fkey foreign key (author) references auth.users (id),
constraint challenges_problem_fkey foreign key (problem) references public.problems (id)
) tablespace pg_default;
alter table public.challenges enable row level security;
create policy "The challagers can see their challenges" on "public"."challenges" for select to public using (auth.uid() = author) with check (true)