Files
planilla/ui/src/views/tareas/TareasIndex.vue
2025-06-10 00:21:39 -06:00

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>