/
Codename-Nik
/
WebApp
Обзор
Документация
Войти
/
Codename-Nik
/
WebApp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
frontend/src/views/ProjectsView.vue
129 строк
4 KB
Nikolay Pokhodnya
first commit
03 ноя 2025, 19:47
03 ноя 2025, 19:47
a9fbdee
Код
Авторство
О чём код?
<template> <div> <v-row> <v-col cols="12"> <div class="d-flex justify-space-between align-center"> <h1 class="text-h4 font-weight-bold">Проекты</h1> <v-btn color="primary" prepend-icon="mdi-plus" @click="showCreateDialog = true"> Новый проект </v-btn> </div> </v-col> </v-row> <v-row v-if="projects.isLoading"> <v-col v-for="n in 4" :key="n" cols="12" sm="6" md="4" lg="3"> <v-skeleton-loader type="card"></v-skeleton-loader> </v-col> </v-row> <v-row v-else> <v-col v-for="project in projects.projects" :key="project.id" cols="12" sm="6" md="4" lg="3" > <v-card :color="project.color || 'primary'" variant="outlined"> <v-card-title class="d-flex justify-space-between"> {{ project.name }} <v-chip size="small"> {{ project.task_count }} задач </v-chip> </v-card-title> <v-card-text> <div class="text-body-2 mb-2">{{ project.description || 'Без описания' }}</div> <div class="text-caption"> Участников: {{ project.member_count }} </div> </v-card-text> <v-card-actions> <v-btn variant="text" :to="{ name: 'project-detail', params: { id: project.id } }"> Открыть </v-btn> </v-card-actions> </v-card> </v-col> </v-row> <v-card v-if="!projects.isLoading && projects.projects.length === 0"> <v-card-text class="text-center py-8"> <v-icon size="64" color="grey-lighten-1">mdi-folder</v-icon> <div class="text-h6 mt-2">Проекты отсутствуют</div> <div class="text-body-2 text-grey">Создайте первый проект</div> </v-card-text> </v-card> <v-dialog v-model="showCreateDialog" max-width="500"> <v-card> <v-card-title>Новый проект</v-card-title> <v-card-text> <v-form @submit.prevent="handleCreateProject"> <v-text-field v-model="projectForm.name" label="Название проекта" required ></v-text-field> <v-textarea v-model="projectForm.description" label="Описание" rows="3" ></v-textarea> <v-color-picker v-model="projectForm.color" label="Цвет" ></v-color-picker> </v-form> </v-card-text> <v-card-actions> <v-spacer></v-spacer> <v-btn @click="showCreateDialog = false">Отмена</v-btn> <v-btn color="primary" @click="handleCreateProject" :loading="projects.isLoading" > Создать </v-btn> </v-card-actions> </v-card> </v-dialog> </div> </template> <script setup lang="ts"> import { ref, reactive, onMounted } from 'vue' import { useProjectsStore } from '@/stores/projects' import type { ProjectCreateData } from '@/types/projects' const projects = useProjectsStore() const showCreateDialog = ref(false) const projectForm = reactive<ProjectCreateData>({ name: '', description: '', color: '#1976D2' }) const handleCreateProject = async () => { if (!projectForm.name.trim()) return try { await projects.createProject(projectForm) showCreateDialog.value = false Object.assign(projectForm, { name: '', description: '', color: '#1976D2' }) } catch (error) { // Ошибка обрабатывается в store } } onMounted(() => { projects.fetchProjects() }) </script>