205 lines
5.9 KiB
Vue
205 lines
5.9 KiB
Vue
<template>
|
|
<div class="tareas-index-container">
|
|
<header class="page-header">
|
|
<h1>Gestión de Tareas</h1>
|
|
<button @click="navigateToCreateForm" class="btn-create">
|
|
Crear Nueva Tarea
|
|
</button>
|
|
</header>
|
|
|
|
<!-- View Toggle Buttons -->
|
|
<div class="mb-4 flex justify-end space-x-2">
|
|
<button
|
|
@click="currentView = 'table'"
|
|
:class="btnViewClass('table')"
|
|
aria-label="Table View"
|
|
title="Table View"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 10h16M4 14h16M4 18h16" /></svg>
|
|
</button>
|
|
<button
|
|
@click="currentView = 'card'"
|
|
:class="btnViewClass('card')"
|
|
aria-label="Card View"
|
|
title="Card View"
|
|
>
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" /></svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div v-if="isLoading" class="loading-message">
|
|
Cargando tareas...
|
|
</div>
|
|
|
|
<div v-else-if="errorLoading" class="error-message-full">
|
|
<p>Ocurrió un error al cargar las tareas. Por favor, intente de nuevo más tarde.</p>
|
|
<p v-if="errorMessage">Detalle: {{ errorMessage }}</p>
|
|
</div>
|
|
|
|
<div v-else>
|
|
<!-- Vista de Tabla -->
|
|
<div v-if="currentView === 'table'">
|
|
<tabla-tareas
|
|
:tareas="tareasList"
|
|
@edit="handleEditTarea"
|
|
/>
|
|
<div v-if="tareasList.length === 0 && !isLoading" class="no-data-message">
|
|
No hay tareas para mostrar en la vista de tabla.
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Vista de Tarjetas -->
|
|
<div v-if="currentView === 'card'">
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
<CardTarea
|
|
v-for="tarea in tareasList"
|
|
:key="tarea.id"
|
|
:tarea="tarea"
|
|
@edit="handleEditTarea"
|
|
/>
|
|
</div>
|
|
<div v-if="tareasList.length === 0 && !isLoading" class="no-data-message">
|
|
No hay tareas para mostrar en la vista de tarjetas.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, computed, onMounted } from 'vue';
|
|
import { useTareasStore } from '../../stores/useTareas';
|
|
import { useUi } from '../../stores/useUi'; // Import useUi
|
|
import { useRouter } from 'vue-router';
|
|
import TablaTareas from '../../components/tareas/tablaTareas.vue';
|
|
import CardTarea from '../../components/tareas/cardTarea.vue';
|
|
|
|
const tareasStore = useTareasStore();
|
|
const ui = useUi(); // Access the ui store
|
|
const router = useRouter();
|
|
|
|
const isLoading = ref(true);
|
|
const errorLoading = ref(false);
|
|
const errorMessage = ref('');
|
|
|
|
// Initialize currentView from the store's default setting for tareas
|
|
const currentView = ref(ui.defaultViewTareas);
|
|
|
|
// Display tareas sorted by id descending
|
|
const tareasList = computed(() =>
|
|
[...(tareasStore.tareas || [])].sort((a, b) => b.id - a.id)
|
|
);
|
|
|
|
onMounted(async () => {
|
|
try {
|
|
isLoading.value = true;
|
|
errorLoading.value = false;
|
|
errorMessage.value = '';
|
|
await tareasStore.fetchTareas();
|
|
} catch (error) {
|
|
console.error("Error fetching tareas on mount:", error);
|
|
errorLoading.value = true;
|
|
errorMessage.value = error.message || 'Error desconocido al cargar tareas.';
|
|
} finally {
|
|
isLoading.value = false;
|
|
}
|
|
});
|
|
|
|
const navigateToCreateForm = () => {
|
|
// Assuming route for creating a new tarea is named 'TareaFormNew'
|
|
router.push({ name: 'tareas-new' });
|
|
};
|
|
|
|
const handleEditTarea = (tareaId) => {
|
|
// Assuming route for editing is named 'TareaFormEdit'
|
|
router.push({ name: 'tareas-edit', params: { id: tareaId } });
|
|
};
|
|
|
|
const btnViewClass = (viewType) => {
|
|
const base = 'p-2 rounded-md transition-colors duration-150 ease-in-out';
|
|
if (currentView.value === viewType) {
|
|
return `${base} bg-[var(--accent-color-tareas)] text-white shadow-lg`;
|
|
}
|
|
return `${base} bg-gray-200 text-gray-700 hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600`;
|
|
};
|
|
|
|
</script>
|
|
|
|
<style scoped>
|
|
.tareas-index-container {
|
|
padding: 20px;
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
|
}
|
|
|
|
.page-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 25px;
|
|
padding-bottom: 15px;
|
|
border-bottom: 1px solid #e0e0e0;
|
|
}
|
|
|
|
.page-header h1 {
|
|
color: var(--accent-color-tareas); /* Accent color for page title */
|
|
font-size: 2em;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.btn-create {
|
|
background-color: var(--accent-color-tareas);
|
|
color: white;
|
|
padding: 12px 20px;
|
|
border: none;
|
|
border-radius: 5px;
|
|
font-size: 1em;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease, filter 0.2s ease;
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.btn-create:hover {
|
|
filter: brightness(0.9);
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.loading-message,
|
|
.error-message-full,
|
|
.no-data-message {
|
|
text-align: center;
|
|
padding: 25px;
|
|
margin-top: 25px;
|
|
border-radius: 8px;
|
|
font-size: 1.1em;
|
|
}
|
|
|
|
.loading-message {
|
|
color: #555;
|
|
}
|
|
|
|
.error-message-full {
|
|
background-color: #f8d7da;
|
|
color: #721c24;
|
|
border: 1px solid #f5c6cb;
|
|
}
|
|
.error-message-full p {
|
|
margin: 5px 0;
|
|
}
|
|
|
|
.no-data-message {
|
|
background-color: #e9ecef;
|
|
color: #495057;
|
|
border: 1px solid #ced4da;
|
|
}
|
|
|
|
/* Added for view toggle buttons */
|
|
.view-toggle-active-tareas {
|
|
background-color: var(--accent-color-tareas);
|
|
box-shadow: 0 0 0 2px var(--background-color, #fff), 0 0 0 4px var(--accent-color-tareas);
|
|
}
|
|
</style>
|