Files

252 lines
9.3 KiB
Vue

<script setup>
import { computed, ref } from 'vue';
import { Link, router } from '@inertiajs/vue3';
import { Modal } from 'bootstrap';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
const props = defineProps({ projects: Array });
const projectStats = computed(() => props.projects.map((project) => {
const tasks = Array.isArray(project.tasks) ? project.tasks : [];
const totalTasks = tasks.length;
const completedTasks = tasks.filter(task => task.status === 'done').length;
return {
project,
totalTasks,
completedTasks,
progress: totalTasks ? Math.round((completedTasks / totalTasks) * 100) : 0,
};
}));
// Referencia al elemento del DOM para manejar el modal de Bootstrap
const modalElement = ref(null);
let modalInstance = null;
const deleteModalElement = ref(null);
let deleteModalInstance = null;
const name = ref('');
const description = ref('');
const isEditMode = ref(false);
const descripcion = ref('');
const id = ref(null);
const projectToDelete = ref(null);
const abrirCrear = () => {
isEditMode.value = false;
id.value = null;
name.value = ''; // Limpiar formulario
descripcion.value = ''; // Limpiar formulario
mostrarModal();
};
const abrirEditar = (item) => {
isEditMode.value = true;
id.value = item.id;
name.value = item.name;
descripcion.value = item.description;
mostrarModal();
};
const eliminarProyecto = (item) => {
projectToDelete.value = item;
if (!deleteModalElement.value) {
return;
}
if (!deleteModalInstance) {
deleteModalInstance = new Modal(deleteModalElement.value);
}
deleteModalInstance.show();
};
const confirmarEliminacion = () => {
if (!projectToDelete.value) {
return;
}
const projectId = projectToDelete.value.id;
deleteModalInstance?.hide();
router.delete(`/projects/${projectId}`, {
preserveScroll: true,
onSuccess: () => {
projectToDelete.value = null;
},
});
};
const mostrarModal = () => {
if (!modalElement.value) {
return;
}
if (!modalInstance) {
modalInstance = new Modal(modalElement.value);
}
modalInstance.show();
};
const ocultarModal = () => {
modalInstance?.hide();
};
const guardarRegistro = async () => {
try {
if (isEditMode.value) {
router.put(`/projects/${id.value}`, { name: name.value, description: descripcion.value }, {
onSuccess: () => {
name.value = '';
descripcion.value = '';
ocultarModal();
},
});
return;
}
router.post('/projects', { name: name.value, description: descripcion.value }, {
onSuccess: () => {
name.value = '';
descripcion.value = '';
ocultarModal();
},
});
} catch (error) {
console.error('Error al guardar:', error);
}
};
</script>
<template>
<AuthenticatedLayout>
<template #header>
<h2 class="h4 mb-0">Mis proyectos</h2>
</template>
<div class="container py-4">
<div class="d-flex justify-content-between align-items-center mb-4">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" @click="abrirCrear">
Crear proyecto
</button>
</div>
<div class="row g-3">
<div v-for="item in projectStats" :key="item.project.id" class="col-sm-6 col-lg-4">
<div class="project-card card h-100 rounded-4 shadow-sm border-0 overflow-hidden">
<div class="project-card-top"></div>
<div class="card-body">
<div class="d-flex justify-content-between align-items-start gap-2 mb-3">
<Link :href="`/projects/${item.project.id}`" class="text-decoration-none text-dark flex-grow-1">
<div class="d-flex align-items-center gap-2 mb-2">
<span class="project-icon-badge">
<i class="bi bi-kanban"></i>
</span>
<h5 class="card-title mb-0">{{ item.project.name }}</h5>
</div>
</Link>
<div class="d-flex align-items-center gap-2">
<button
type="button"
class="btn btn-link text-dark text-decoration-none p-0"
@click.stop="abrirEditar(item.project)"
aria-label="Editar proyecto"
>
<i class="bi bi-pencil-square fs-5"></i>
</button>
<button
type="button"
class="btn btn-link text-danger text-decoration-none p-0"
@click.stop="eliminarProyecto(item.project)"
aria-label="Eliminar proyecto"
>
<i class="bi bi-trash fs-5"></i>
</button>
</div>
</div>
<p class="card-text text-muted mb-3">
{{ item.project.description || 'Sin descripción' }}
</p>
<div class="d-flex justify-content-between align-items-center small text-muted mb-2">
<span>{{ item.totalTasks }} tareas</span>
<span>{{ item.completedTasks }} completas</span>
</div>
<div class="progress" role="progressbar" aria-label="Progreso del proyecto" aria-valuemin="0" aria-valuemax="100">
<div class="progress-bar" :style="{ width: `${item.progress}%` }"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal para crear y editar proyectos -->
<div class="modal fade" id="proyectoModal" tabindex="-1" aria-hidden="true" ref="modalElement">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">
{{ isEditMode ? 'EDITAR PROYECTO' : 'NUEVO PROYECTO' }}
</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form @submit.prevent="guardarRegistro">
<div class="modal-body">
<div class="mb-3">
<label for="name" class="form-label">Nombre</label>
<input type="text" class="form-control" id="name" v-model="name" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Descripción</label>
<input type="text" class="form-control" id="description" v-model="description">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">{{ isEditMode ? 'Actualizar proyecto' : 'Crear proyecto' }}</button>
</div>
</form>
</div>
</div>
</div>
<!-- Modal para eliminar proyecto -->
<div
class="modal fade"
id="confirmDeleteModal"
tabindex="-1"
aria-labelledby="confirmDeleteModalLabel"
aria-hidden="true"
ref="deleteModalElement"
>
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h1 id="confirmDeleteModalLabel" class="modal-title fs-5">Eliminar proyecto</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Cerrar"></button>
</div>
<div class="modal-body">
¿Seguro que quieres eliminar el proyecto
<strong>{{ projectToDelete?.name }}</strong>?
Esta accion eliminara todas las tareas asociadas al proyecto y no se podra deshacer.
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancelar</button>
<button type="button" class="btn btn-danger" @click="confirmarEliminacion">
<i class="bi bi-trash me-1"></i>
Eliminar
</button>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
</template>