Primer commit

This commit is contained in:
2026-08-03 18:01:15 +02:00
commit 99b9fed37f
121 changed files with 18222 additions and 0 deletions

View File

@@ -0,0 +1,221 @@
<script setup>
import { ref } from 'vue';
import { Link, router } from '@inertiajs/vue3';
import { Modal } from 'bootstrap';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
defineProps({ projects: Array });
// 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="project in projects" :key="project.id" class="col-sm-6 col-lg-4">
<div class="card h-100 shadow-sm">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start gap-2 mb-3">
<Link :href="`/projects/${project.id}`" class="text-decoration-none text-dark flex-grow-1">
<h5 class="card-title mb-0">{{ project.name }}</h5>
</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(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(project)"
aria-label="Eliminar proyecto"
>
<i class="bi bi-trash fs-5"></i>
</button>
</div>
</div>
<p class="card-text text-muted mb-0">{{ project.description }}</p>
</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>