109 lines
3.9 KiB
Vue
109 lines
3.9 KiB
Vue
<script setup>
|
|
import { onMounted } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useNotesStore } from '@/stores/notes'
|
|
import { useWorkspaceStore } from '@/stores/workspace'
|
|
import { FileText, LayoutGrid, List } from 'lucide-vue-next'
|
|
|
|
const router = useRouter()
|
|
const notesStore = useNotesStore()
|
|
const workspaceStore = useWorkspaceStore()
|
|
|
|
onMounted(async () => {
|
|
if (workspaceStore.path) {
|
|
await notesStore.fetchNotes()
|
|
}
|
|
})
|
|
|
|
function openNote(note) {
|
|
router.push({ name: 'note-detail', params: { id: note.id } })
|
|
}
|
|
|
|
function toggleView() {
|
|
notesStore.viewMode = notesStore.viewMode === 'list' ? 'grid' : 'list'
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="h-full flex flex-col">
|
|
<!-- 头部 -->
|
|
<div
|
|
class="flex items-center justify-between px-6 py-4 border-b"
|
|
:style="{ borderColor: 'var(--p-surface-200)' }"
|
|
>
|
|
<h1 class="text-lg font-semibold" :style="{ color: 'var(--p-surface-800)' }">全部笔记</h1>
|
|
<button
|
|
class="p-1.5 rounded-md transition-colors"
|
|
:style="{ color: 'var(--p-surface-500)' }"
|
|
@click="toggleView"
|
|
:title="notesStore.viewMode === 'list' ? '卡片视图' : '列表视图'"
|
|
>
|
|
<component :is="notesStore.viewMode === 'list' ? LayoutGrid : List" :size="18" />
|
|
</button>
|
|
</div>
|
|
|
|
<!-- 内容区 -->
|
|
<div class="flex-1 overflow-y-auto p-6">
|
|
<!-- 无笔记提示 -->
|
|
<div
|
|
v-if="notesStore.filteredNotes.length === 0"
|
|
class="flex flex-col items-center justify-center h-full"
|
|
>
|
|
<div
|
|
class="w-16 h-16 rounded-xl flex items-center justify-center mb-4"
|
|
:style="{ backgroundColor: 'var(--p-surface-100)', color: 'var(--p-surface-400)' }"
|
|
>
|
|
<FileText :size="32" />
|
|
</div>
|
|
<p class="text-sm" :style="{ color: 'var(--p-surface-500)' }">
|
|
{{ workspaceStore.path ? '暂无笔记,点击左侧 + 创建' : '请先选择工作目录' }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- 列表视图 -->
|
|
<div v-else-if="notesStore.viewMode === 'list'" class="space-y-1">
|
|
<div
|
|
v-for="note in notesStore.filteredNotes"
|
|
:key="note.id"
|
|
class="flex items-center gap-3 px-4 py-3 rounded-lg cursor-pointer transition-colors"
|
|
:style="{ color: 'var(--p-surface-700)' }"
|
|
@click="openNote(note)"
|
|
@mouseenter="$event.currentTarget.style.backgroundColor = 'var(--p-surface-50)'"
|
|
@mouseleave="$event.currentTarget.style.backgroundColor = 'transparent'"
|
|
>
|
|
<FileText :size="18" :style="{ color: 'var(--p-surface-400)' }" />
|
|
<div class="flex-1 min-w-0">
|
|
<div class="text-sm font-medium truncate">{{ note.title }}</div>
|
|
<div class="text-xs mt-0.5" :style="{ color: 'var(--p-surface-400)' }">
|
|
{{ note.filePath }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 卡片视图 -->
|
|
<div v-else class="grid grid-cols-2 lg:grid-cols-3 gap-4">
|
|
<div
|
|
v-for="note in notesStore.filteredNotes"
|
|
:key="note.id"
|
|
class="p-4 rounded-xl border cursor-pointer transition-colors"
|
|
:style="{ borderColor: 'var(--p-surface-200)', backgroundColor: 'var(--p-surface-50)' }"
|
|
@click="openNote(note)"
|
|
@mouseenter="$event.currentTarget.style.borderColor = 'var(--p-primary-300)'"
|
|
@mouseleave="$event.currentTarget.style.borderColor = 'var(--p-surface-200)'"
|
|
>
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<FileText :size="16" :style="{ color: 'var(--p-primary-500)' }" />
|
|
<span class="text-sm font-medium truncate" :style="{ color: 'var(--p-surface-700)' }">
|
|
{{ note.title }}
|
|
</span>
|
|
</div>
|
|
<p class="text-xs truncate" :style="{ color: 'var(--p-surface-400)' }">
|
|
{{ note.filePath }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|