Skip to content

Commit

Permalink
feat: admin
Browse files Browse the repository at this point in the history
Signed-off-by: ZTL-UwU <zhangtianli2006@163.com>
  • Loading branch information
ZTL-UwU committed Jun 11, 2024
1 parent 56f26c8 commit 96197eb
Show file tree
Hide file tree
Showing 9 changed files with 891 additions and 385 deletions.
2 changes: 2 additions & 0 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default defineNuxtConfig({
'@vueuse/nuxt',
'nuxt-icon',
'@nuxthub/core',
'@pinia/nuxt',
'@pinia-plugin-persistedstate/nuxt',
],
hub: {
database: true,
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"dependencies": {
"@nuxt/image": "^1.7.0",
"@nuxthub/core": "^0.6.10",
"@pinia/nuxt": "^0.5.1",
"@radix-icons/vue": "^1.0.0",
"@trpc/client": "^10.45.2",
"@trpc/server": "^10.45.2",
Expand All @@ -36,6 +37,7 @@
"devDependencies": {
"@antfu/eslint-config": "^2.21.0",
"@nuxtjs/tailwindcss": "^6.12.0",
"@pinia-plugin-persistedstate/nuxt": "^1.2.0",
"@tiptap/core": "^2.4.0",
"@tiptap/extension-color": "^2.4.0",
"@tiptap/extension-highlight": "^2.4.0",
Expand All @@ -52,6 +54,7 @@
"@unocss/eslint-plugin": "^0.60.4",
"@vueuse/core": "^10.10.0",
"@vueuse/nuxt": "^10.10.0",
"dotenv": "^16.4.5",
"drizzle-kit": "^0.22.6",
"eslint": "9.4.0",
"nuxt-icon": "^0.6.10",
Expand Down
4 changes: 2 additions & 2 deletions pages/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ const category = computed(
() => categoryMap.find(x => x.value === slugCategory) || categoryMap[0],
);

const guideList = await $api.guide.query({ primaryCategory: slugCategory });
const data: Map<TSecondaryCategory, RouterOutput['guide']> = new Map();
const guideList = await $api.guideList.query({ primaryCategory: slugCategory });
const data: Map<TSecondaryCategory, RouterOutput['guideList']> = new Map();
for (const c of categoryMap.find(x => x.value === slugCategory)?.secondary ?? []) {
data.set(
c.value,
Expand Down
67 changes: 67 additions & 0 deletions pages/admin.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<template>
<Card v-for="post in list" :key="post.id" class="mb-4">
<CardHeader class="flex flex-row">
<CardTitle class="text-lg">
{{ categoryMap.find(x => x.value === post.primaryCategory)?.name }}
<Icon name="lucide:chevron-right" class="mb-1.5" />
{{ categoryMap.find(x => x.value === post.primaryCategory)?.secondary.find(x => x.value === post.secondaryCategory)?.name }}
</CardTitle>
<div class="ml-auto space-x-2">
<Button size="icon" variant="outline" @click="approve(post.id)">
<Icon name="lucide:check" />
</Button>
<Button size="icon" variant="outline" @click="reject(post.id)">
<Icon name="lucide:x" />
</Button>
</div>
</CardHeader>
<CardContent>
<TiptapViewer :content="post.content" />
</CardContent>
</Card>
</template>

<script setup lang="ts">
import { useToast } from '~/components/ui/toast';
import { categoryMap } from '~/constants';
import { useAdminStore } from '~/store/admin';

const adminStore = useAdminStore();
const { toast } = useToast();
const { $api } = useNuxtApp();

const { data: list } = await $api.guideReviewList.useQuery({
password: adminStore.password,
});

async function approve(id: number) {
try {
await $api.modify.mutate({
id,
password: adminStore.password,
isReviewed: true,
});
toast({ title: '成功通过' });
list.value = await $api.guideReviewList.query({
password: adminStore.password,
});
} catch (err) {
toast({ title: '审核失败', variant: 'destructive' });
}
}

async function reject(id: number) {
try {
await $api.remove.mutate({
id,
password: adminStore.password,
});
toast({ title: '成功拒绝' });
list.value = await $api.guideReviewList.query({
password: adminStore.password,
});
} catch (err) {
toast({ title: '审核失败', variant: 'destructive' });
}
}
</script>
40 changes: 40 additions & 0 deletions pages/login.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<Card class="md:mx-auto md:w-1/2">
<CardHeader>
<CardTitle>
请输入管理员密码
</CardTitle>
<CardDescription>
登陆管理系统
</CardDescription>
</CardHeader>
<CardContent>
<Input v-model="inputPassword" />
<Button class="w-full mt-4" @click="checkPassword">
登陆
</Button>
</CardContent>
</Card>
</template>

<script setup lang="ts">
import { useToast } from '~/components/ui/toast';
import { useAdminStore } from '~/store/admin';
const adminStore = useAdminStore();
const inputPassword = ref('');
const { toast } = useToast();
const { $api } = useNuxtApp();
async function checkPassword() {
try {
await $api.checkPassword.query({ password: inputPassword.value });
adminStore.password = inputPassword.value;
toast({ title: '登陆成功' });
navigateTo('/admin');
} catch (err) {
toast({ variant: 'destructive', title: '密码错误' });
}
}
</script>
Loading

0 comments on commit 96197eb

Please sign in to comment.