feat(ui): overhaul interface with Nuxt UI
Integrate the Nuxt UI component library and completely revamp the application's user interface to improve usability, aesthetics, and maintainability. - Replace all custom components and native browser dialogs (`alert`, `prompt`, `confirm`) with Nuxt UI components like `UCard`, `UButton`, `UModal`, and `UNotifications`. - Refactor the main page by extracting the sidebar into dedicated panel components: `CategoryPanel`, `BoardSummaryPanel`, and `HistoryPanel`. - Redesign all major components (Toolbar, Board, Stage, Task) for a cleaner layout and improved information hierarchy. - Implement user-friendly modals for all creation, editing, and deletion flows, providing a more consistent user experience. - Add toast notifications to provide immediate feedback for user actions.
This commit is contained in:
76
components/dialogs/StageModal.vue
Normal file
76
components/dialogs/StageModal.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<UModal v-model="open">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<div class="flex items-center gap-2">
|
||||
<UIcon name="i-heroicons-plus-circle-20-solid" class="h-5 w-5 text-sky-400" />
|
||||
<span class="font-semibold">添加阶段</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<form class="space-y-4" @submit.prevent="handleSubmit">
|
||||
<UFormGroup label="阶段名称" name="title">
|
||||
<UInput v-model="form.title" placeholder="例如:待办、进行中、已完成…" autofocus />
|
||||
</UFormGroup>
|
||||
|
||||
<UFormGroup v-if="columnOptions.length" label="放置到列" name="column">
|
||||
<USelectMenu
|
||||
v-model="form.column"
|
||||
:options="columnOptions"
|
||||
value-attribute="value"
|
||||
option-attribute="label"
|
||||
/>
|
||||
</UFormGroup>
|
||||
<p v-else class="text-xs text-slate-400">
|
||||
尚未创建列,新增阶段时系统会自动建立第一列。
|
||||
</p>
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
<UButton color="neutral" variant="ghost" @click="open = false">取消</UButton>
|
||||
<UButton type="submit" color="primary">创建阶段</UButton>
|
||||
</div>
|
||||
</form>
|
||||
</UCard>
|
||||
</UModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useBoardStore } from '~/stores/board'
|
||||
|
||||
const store = useBoardStore()
|
||||
const toast = useToast()
|
||||
|
||||
const props = defineProps<{ defaultColumn?: number }>()
|
||||
const open = defineModel<boolean>('open', { required: true })
|
||||
const emit = defineEmits<{ (e: 'submit', payload: { title: string; column: number }): void }>()
|
||||
|
||||
const form = reactive({
|
||||
title: '',
|
||||
column: 0
|
||||
})
|
||||
|
||||
const columnOptions = computed(() =>
|
||||
(store.board.layout?.columns || []).map((_, index) => ({
|
||||
label: `列 ${index + 1}`,
|
||||
value: index
|
||||
}))
|
||||
)
|
||||
|
||||
watch(
|
||||
() => open.value,
|
||||
(value) => {
|
||||
if (!value) return
|
||||
form.title = ''
|
||||
const defaultColumn = props.defaultColumn ?? 0
|
||||
form.column = columnOptions.value[defaultColumn] ? defaultColumn : 0
|
||||
}
|
||||
)
|
||||
|
||||
function handleSubmit() {
|
||||
if (!form.title.trim()) {
|
||||
toast.add({ color: 'rose', title: '请输入阶段名称' })
|
||||
return
|
||||
}
|
||||
emit('submit', { title: form.title.trim(), column: form.column })
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user