feat: add login gate and admin navigation to App.vue
This commit is contained in:
@@ -1,10 +1,18 @@
|
|||||||
import { flushPromises, mount } from '@vue/test-utils'
|
import { flushPromises, mount } from '@vue/test-utils'
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import { createEmptyBook } from './domain/teachingDesign'
|
import { createEmptyBook } from './domain/teachingDesign'
|
||||||
import * as booksApi from './services/booksApi'
|
import * as booksApi from './services/booksApi'
|
||||||
|
|
||||||
vi.mock('./services/booksApi')
|
vi.mock('./services/booksApi')
|
||||||
|
vi.mock('./composables/useAuth', () => ({
|
||||||
|
useAuth: () => ({
|
||||||
|
isLoggedIn: computed(() => true),
|
||||||
|
fetchMe: vi.fn(),
|
||||||
|
user: ref(null),
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|
||||||
describe('App', () => {
|
describe('App', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@@ -17,7 +25,7 @@ describe('App', () => {
|
|||||||
const wrapper = mount(App)
|
const wrapper = mount(App)
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|
||||||
expect(wrapper.text()).toContain('教学设计整本')
|
expect(wrapper.text()).toContain('教学设计')
|
||||||
expect(wrapper.text()).toContain('新建整本')
|
expect(wrapper.text()).toContain('新建整本')
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -61,6 +69,6 @@ describe('App', () => {
|
|||||||
await wrapper.get('[data-testid="back"]').trigger('click')
|
await wrapper.get('[data-testid="back"]').trigger('click')
|
||||||
await flushPromises()
|
await flushPromises()
|
||||||
|
|
||||||
expect(wrapper.text()).toContain('教学设计整本')
|
expect(wrapper.text()).toContain('教学设计')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
34
src/App.vue
34
src/App.vue
@@ -1,20 +1,48 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
import AdminPage from './components/AdminPage.vue'
|
||||||
import BookListPage from './components/BookListPage.vue'
|
import BookListPage from './components/BookListPage.vue'
|
||||||
|
import LoginPage from './components/LoginPage.vue'
|
||||||
import WorkspaceView from './components/WorkspaceView.vue'
|
import WorkspaceView from './components/WorkspaceView.vue'
|
||||||
|
import { useAuth } from './composables/useAuth'
|
||||||
|
|
||||||
|
const { isLoggedIn, fetchMe } = useAuth()
|
||||||
const currentBookId = ref<string | null>(null)
|
const currentBookId = ref<string | null>(null)
|
||||||
|
const showAdmin = ref(false)
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await fetchMe()
|
||||||
|
})
|
||||||
|
|
||||||
function openBook(id: string): void {
|
function openBook(id: string): void {
|
||||||
currentBookId.value = id
|
currentBookId.value = id
|
||||||
|
showAdmin.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function backToList(): void {
|
function backToList(): void {
|
||||||
currentBookId.value = null
|
currentBookId.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openAdmin(): void {
|
||||||
|
showAdmin.value = true
|
||||||
|
currentBookId.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeAdmin(): void {
|
||||||
|
showAdmin.value = false
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<BookListPage v-if="!currentBookId" @open="openBook" />
|
<LoginPage v-if="!isLoggedIn" @success="fetchMe" />
|
||||||
<WorkspaceView v-else :key="currentBookId" :book-id="currentBookId" @back="backToList" />
|
<template v-else>
|
||||||
|
<AdminPage v-if="showAdmin" @back="closeAdmin" />
|
||||||
|
<WorkspaceView
|
||||||
|
v-else-if="currentBookId"
|
||||||
|
:key="currentBookId"
|
||||||
|
:book-id="currentBookId"
|
||||||
|
@back="backToList"
|
||||||
|
/>
|
||||||
|
<BookListPage v-else @open="openBook" @admin="openAdmin" />
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
4
src/components/AdminPage.vue
Normal file
4
src/components/AdminPage.vue
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
defineEmits<{ back: [] }>()
|
||||||
|
</script>
|
||||||
|
<template><div>Admin placeholder</div></template>
|
||||||
Reference in New Issue
Block a user