🎉 Initial Commit
This commit is contained in:
parent
7dba4810ef
commit
16aed743d9
4
application/.prettierrc
Normal file
4
application/.prettierrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 2
|
||||
}
|
12
application/app.vue
Normal file
12
application/app.vue
Normal file
@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<n-message-provider>
|
||||
<nuxt-layout>
|
||||
<nuxt-page />
|
||||
</nuxt-layout>
|
||||
</n-message-provider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NMessageProvider } from "naive-ui";
|
||||
import "@/assets/css/index.css";
|
||||
</script>
|
15
application/assets/css/index.css
Normal file
15
application/assets/css/index.css
Normal file
@ -0,0 +1,15 @@
|
||||
@import "@ibm/plex/css/ibm-plex.css";
|
||||
|
||||
.font-mono {
|
||||
font-family: "IBM Plex Mono", monospace;
|
||||
}
|
||||
|
||||
.font-sans {
|
||||
font-family: "IBM Plex Sans", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "IBM Plex Sans", sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
BIN
application/bun.lockb
Executable file
BIN
application/bun.lockb
Executable file
Binary file not shown.
3
application/components/brand/header.vue
Normal file
3
application/components/brand/header.vue
Normal file
@ -0,0 +1,3 @@
|
||||
<template>
|
||||
<div>Fuxi</div>
|
||||
</template>
|
5
application/components/helpful-links.vue
Normal file
5
application/components/helpful-links.vue
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<nuxt-link to="/about">About</nuxt-link>
|
||||
</div>
|
||||
</template>
|
30
application/components/problems/list.vue
Normal file
30
application/components/problems/list.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-card segmented content-style="padding: 0">
|
||||
<template #header>
|
||||
<div>Problems</div>
|
||||
<div class="text-xs font-normal">每天进步一点点!</div>
|
||||
</template>
|
||||
<n-list clickable hoverable>
|
||||
<n-list-item v-for="item in (problems as any[])" class="px-[24px]">
|
||||
<n-thing :title="item?.title">
|
||||
<template #description>
|
||||
<div class="text-xs flex gap-2">
|
||||
<n-tag size="tiny" class="case-capital">{{ item?.type }}</n-tag>
|
||||
<div>Published at {{ new Date(item?.created_at).toLocaleString() }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NCard, NList, NListItem, NThing, NTag } from "naive-ui";
|
||||
|
||||
const client = useSupabaseClient();
|
||||
|
||||
const { data: problems } = await client.from("problems").select(`*`).limit(20);
|
||||
</script>
|
23
application/layouts/default.vue
Normal file
23
application/layouts/default.vue
Normal file
@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<n-layout>
|
||||
<n-layout-header class="py-[18.5px] px-[36px]" bordered>
|
||||
<nuxt-link class="brand-header" to="/">
|
||||
<brand-header />
|
||||
</nuxt-link>
|
||||
</n-layout-header>
|
||||
<n-layout-content class="h-[calc(100vh-70px)]" content-style="padding: 24px">
|
||||
<slot />
|
||||
</n-layout-content>
|
||||
</n-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NLayout, NLayoutHeader, NLayoutContent } from "naive-ui";
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.brand-header {
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
24
application/nuxt.config.ts
Normal file
24
application/nuxt.config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
devtools: { enabled: true },
|
||||
modules: ["@unocss/nuxt", '@pinia/nuxt', '@nuxtjs/supabase'],
|
||||
build: {
|
||||
transpile:
|
||||
process.env.NODE_ENV === 'production'
|
||||
? [
|
||||
'naive-ui',
|
||||
'vueuc',
|
||||
'@css-render/vue3-ssr',
|
||||
'@juggle/resize-observer'
|
||||
]
|
||||
: ['@juggle/resize-observer']
|
||||
},
|
||||
vite: {
|
||||
optimizeDeps: {
|
||||
include:
|
||||
process.env.NODE_ENV === 'development'
|
||||
? ['naive-ui', 'vueuc', 'date-fns-tz/formatInTimeZone']
|
||||
: []
|
||||
}
|
||||
}
|
||||
})
|
@ -11,8 +11,18 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/devtools": "latest",
|
||||
"@nuxtjs/supabase": "latest",
|
||||
"@pinia/nuxt": "latest",
|
||||
"@unocss/nuxt": "^0.58.0",
|
||||
"@vicons/carbon": "^0.12.0",
|
||||
"naive-ui": "^2.35.0",
|
||||
"nuxt": "^3.8.2",
|
||||
"unocss": "^0.58.0",
|
||||
"vue": "^3.3.10",
|
||||
"vue-router": "^4.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ibm/plex": "^6.3.0",
|
||||
"@supabase/supabase-js": "^2.39.0"
|
||||
}
|
||||
}
|
5
application/pages/index.vue
Normal file
5
application/pages/index.vue
Normal file
@ -0,0 +1,5 @@
|
||||
<template>
|
||||
<div class="md:max-w-[720px] mx-auto">
|
||||
<problems-list />
|
||||
</div>
|
||||
</template>
|
60
application/pages/login.vue
Normal file
60
application/pages/login.vue
Normal file
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="h-full w-full flex flex-col gap-5 justify-center items-center">
|
||||
<brand-header />
|
||||
<n-card segmented class="w-[380px]">
|
||||
<template #header>
|
||||
<div class="text-center">Sign in</div>
|
||||
<div class="text-center text-xs font-normal">With your email</div>
|
||||
</template>
|
||||
|
||||
<n-form @submit.prevent="submit">
|
||||
<n-form-item label="Email">
|
||||
<n-input v-model:value="payload.email" placeholder="Your email" />
|
||||
</n-form-item>
|
||||
<n-form-item label="Password">
|
||||
<n-input v-model:value="payload.password" type="password" placeholder="Your password" />
|
||||
</n-form-item>
|
||||
<n-button :loading="loading" attr-type="submit" class="w-full" type="primary">Login</n-button>
|
||||
</n-form>
|
||||
</n-card>
|
||||
|
||||
<div class="flex w-[360px] justify-between">
|
||||
<nuxt-link>Haven't an account?</nuxt-link>
|
||||
<helpful-links />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { NCard, NForm, NFormItem, NInput, NButton } from "naive-ui";
|
||||
import { useMessage } from "naive-ui";
|
||||
import { ref } from "vue";
|
||||
|
||||
const client = useSupabaseClient();
|
||||
const message = useMessage();
|
||||
|
||||
const loading = ref(false);
|
||||
const payload = ref({
|
||||
email: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
async function submit() {
|
||||
if (!payload.value.email || !payload.value.password) return;
|
||||
|
||||
try {
|
||||
loading.value = true;
|
||||
const { error } = await client.auth.signInWithPassword({
|
||||
email: payload.value.email,
|
||||
password: payload.value.password,
|
||||
});
|
||||
if (error) throw error;
|
||||
message.success("Welcome back!");
|
||||
navigateTo("/");
|
||||
} catch (err: any) {
|
||||
message.error(err.error_description || err.message);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
</script>
|
31
application/plugins/naive-ui.ts
Normal file
31
application/plugins/naive-ui.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { setup } from '@css-render/vue3-ssr'
|
||||
import { defineNuxtPlugin } from '#app'
|
||||
|
||||
export default defineNuxtPlugin((nuxtApp) => {
|
||||
if (process.server) {
|
||||
const { collect } = setup(nuxtApp.vueApp)
|
||||
const originalRenderMeta = nuxtApp.ssrContext?.renderMeta
|
||||
nuxtApp.ssrContext = nuxtApp.ssrContext || {}
|
||||
nuxtApp.ssrContext.renderMeta = () => {
|
||||
if (!originalRenderMeta) {
|
||||
return {
|
||||
headTags: collect()
|
||||
}
|
||||
}
|
||||
const originalMeta = originalRenderMeta()
|
||||
if ('then' in originalMeta) {
|
||||
return originalMeta.then((resolvedOriginalMeta) => {
|
||||
return {
|
||||
...resolvedOriginalMeta,
|
||||
headTags: resolvedOriginalMeta['headTags'] + collect()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
...originalMeta,
|
||||
headTags: originalMeta['headTags'] + collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
5
application/uno.config.ts
Normal file
5
application/uno.config.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { defineConfig, presetUno } from "unocss";
|
||||
|
||||
export default defineConfig({
|
||||
presets: [presetUno({ preflight: false })],
|
||||
});
|
@ -1,75 +0,0 @@
|
||||
# Nuxt 3 Minimal Starter
|
||||
|
||||
Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||
|
||||
## Setup
|
||||
|
||||
Make sure to install the dependencies:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm install
|
||||
|
||||
# pnpm
|
||||
pnpm install
|
||||
|
||||
# yarn
|
||||
yarn install
|
||||
|
||||
# bun
|
||||
bun install
|
||||
```
|
||||
|
||||
## Development Server
|
||||
|
||||
Start the development server on `http://localhost:3000`:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run dev
|
||||
|
||||
# pnpm
|
||||
pnpm run dev
|
||||
|
||||
# yarn
|
||||
yarn dev
|
||||
|
||||
# bun
|
||||
bun run dev
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
Build the application for production:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run build
|
||||
|
||||
# pnpm
|
||||
pnpm run build
|
||||
|
||||
# yarn
|
||||
yarn build
|
||||
|
||||
# bun
|
||||
bun run build
|
||||
```
|
||||
|
||||
Locally preview production build:
|
||||
|
||||
```bash
|
||||
# npm
|
||||
npm run preview
|
||||
|
||||
# pnpm
|
||||
pnpm run preview
|
||||
|
||||
# yarn
|
||||
yarn preview
|
||||
|
||||
# bun
|
||||
bun run preview
|
||||
```
|
||||
|
||||
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
@ -1,5 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<NuxtWelcome />
|
||||
</div>
|
||||
</template>
|
@ -1,4 +0,0 @@
|
||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
devtools: { enabled: true }
|
||||
})
|
5418
display/yarn.lock
5418
display/yarn.lock
File diff suppressed because it is too large
Load Diff
19
supabase/migrations/20231210071647_profiles.sql
Normal file
19
supabase/migrations/20231210071647_profiles.sql
Normal file
@ -0,0 +1,19 @@
|
||||
create table public.profiles (
|
||||
id uuid not null references auth.users on delete cascade,
|
||||
username varchar(64),
|
||||
nickname varchar(256),
|
||||
school_id int8,
|
||||
|
||||
primary key (id)
|
||||
);
|
||||
|
||||
alter table public.profiles enable row level security;
|
||||
|
||||
create policy "Public profiles are viewable by everyone." on profiles
|
||||
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 update own profile." on profiles
|
||||
for update using (auth.uid() = id);
|
19
supabase/migrations/20231210071842_problems.sql
Normal file
19
supabase/migrations/20231210071842_problems.sql
Normal file
@ -0,0 +1,19 @@
|
||||
create table
|
||||
public.problems (
|
||||
id bigint generated by default as identity,
|
||||
title text not null,
|
||||
description text not null,
|
||||
type character varying not null,
|
||||
tags character varying[] null,
|
||||
author uuid null,
|
||||
is_draft boolean null default true,
|
||||
is_hidden boolean null default false,
|
||||
created_at timestamp with time zone null default now(),
|
||||
constraint problems_pkey primary key (id),
|
||||
constraint problems_author_fkey foreign key (author) references auth.users (id)
|
||||
) tablespace pg_default;
|
||||
|
||||
alter table public.problems enable row level security;
|
||||
|
||||
create policy "Public problems are viewable by everyone." on problems
|
||||
for select using (true);
|
Loading…
Reference in New Issue
Block a user