Jules was unable to complete the task in time. Please review the work done so far and provide feedback for Jules to continue.

This commit is contained in:
google-labs-jules[bot]
2025-05-30 06:41:49 +00:00
parent 2c43538db3
commit fe014b677b
15 changed files with 2563 additions and 24 deletions

View File

@@ -1,2 +1,181 @@
<template>
<div class="asistencia-card">
<div class="card-header">
<span class="empleado-id">Empleado ID: {{ asistencia.empleado_id }}</span>
<span :class="`estado-asistencia estado-${asistencia.estado?.toLowerCase().replace(/\s+/g, '-')}`">
{{ asistencia.estado || 'N/A' }}
</span>
</div>
<div class="card-body">
<p><strong>Entrada:</strong> {{ formatDateTime(asistencia.entrada) }}</p>
<p><strong>Salida:</strong> {{ asistencia.salida ? formatDateTime(asistencia.salida) : 'No registrada' }}</p>
<p v-if="asistencia.observacion" class="observacion">
<strong>Observación:</strong> {{ asistencia.observacion }}
</p>
<!-- Historial might be too complex for a card, but can be added if needed -->
<!-- <p v-if="asistencia.historial"><strong>Historial:</strong> {{ asistencia.historial }}</p> -->
</div>
<div class="card-actions">
<button @click="editAsistencia" class="action-button edit-button">Editar</button>
<button @click="confirmDeleteAsistencia" class="action-button delete-button">Eliminar</button>
</div>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { useAsistenciasStore } from '../../stores/useAsistencias';
const props = defineProps({
asistencia: {
type: Object,
required: true,
},
});
const emit = defineEmits(['edit']);
const asistenciasStore = useAsistenciasStore();
const formatDateTime = (dateTimeString) => {
if (!dateTimeString) return 'N/A';
const date = new Date(dateTimeString);
return date.toLocaleString('es-ES', { // Spanish locale
year: 'numeric',
month: '2-digit', // Using 2-digit for month for brevity in card
day: '2-digit', // Using 2-digit for day
hour: '2-digit',
minute: '2-digit',
// second: '2-digit', // Optional: include seconds
});
};
const editAsistencia = () => {
emit('edit', props.asistencia.id);
};
const confirmDeleteAsistencia = () => {
if (confirm(`¿Está seguro de que desea eliminar esta asistencia (ID: ${props.asistencia.id})?`)) {
deleteAsistenciaInternal();
}
};
const deleteAsistenciaInternal = async () => {
try {
await asistenciasStore.deleteAsistencia(props.asistencia.id);
// Optionally, emit 'deleted' or show notification
} catch (error) {
console.error('Error deleting asistencia:', error);
alert('Ocurrió un error al eliminar la asistencia.');
}
};
</script>
<style scoped>
.asistencia-card {
border: 1px solid #e0e0e0; /* Lighter border for a softer look */
padding: 16px;
margin-bottom: 16px;
border-radius: 8px;
background-color: #fff;
box-shadow: 0 2px 5px rgba(0,0,0,0.05); /* Softer shadow */
display: flex;
flex-direction: column;
transition: box-shadow 0.3s ease-in-out;
}
.asistencia-card:hover {
box-shadow: 0 4px 10px rgba(0,0,0,0.1); /* Enhanced shadow on hover */
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
padding-bottom: 10px; /* Increased padding */
border-bottom: 1px solid #f0f0f0; /* Even lighter border */
}
.empleado-id {
font-weight: bold;
color: #2c3e50; /* Dark blue/grey */
font-size: 1.05em;
}
.estado-asistencia {
padding: 5px 10px; /* Slightly more padding */
border-radius: 15px; /* Pill shape */
font-size: 0.8em;
font-weight: bold;
color: white;
text-transform: uppercase; /* Uppercase status */
letter-spacing: 0.5px;
}
.card-body p {
margin: 8px 0;
color: #555;
font-size: 0.95em;
line-height: 1.6; /* Improved line spacing */
}
.card-body p strong {
color: #333;
}
.observacion {
font-style: italic;
color: #666;
background-color: #f8f9fa; /* Very light grey background */
padding: 10px; /* More padding */
border-left: 3px solid #007bff; /* Blue accent line */
border-radius: 4px;
margin-top:10px;
font-size: 0.9em; /* Slightly smaller for observation */
}
.card-actions {
margin-top: auto;
padding-top: 16px; /* More space before actions */
display: flex;
justify-content: flex-end;
gap: 10px;
}
.action-button {
padding: 8px 15px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
font-weight: 500; /* Slightly bolder text on buttons */
transition: background-color 0.2s ease, transform 0.1s ease, box-shadow 0.2s ease;
}
.action-button:hover{
transform: translateY(-2px); /* More pronounced lift */
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.edit-button {
background-color: #007bff;
color: white;
}
.edit-button:hover {
background-color: #0056b3;
}
.delete-button {
background-color: #dc3545;
color: white;
}
.delete-button:hover {
background-color: #c82333;
}
/* Estado specific styling */
.estado-pendiente { background-color: #ffc107; color: #212529;} /* Amber, dark text */
.estado-presente,
.estado-confirmada { background-color: #28a745; color: white;} /* Green */
.estado-ausente { background-color: #dc3545; color: white;} /* Red */
.estado-justificada { background-color: #17a2b8; color: white;} /* Info Blue */
.estado-cancelada,
.estado-anulada { background-color: #6c757d; color: white;} /* Gray */
</style>

View File

@@ -1,2 +1,163 @@
<template>
<div class="tabla-asistencias-container">
<table class="tabla-asistencias">
<thead>
<tr>
<th>ID</th>
<th>Empleado ID</th>
<th>Entrada</th>
<th>Salida</th>
<th>Estado</th>
<th>Observación</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<tr v-if="!asistencias || asistencias.length === 0">
<td :colspan="7" style="text-align: center;">No hay asistencias para mostrar.</td>
</tr>
<tr v-for="asistencia in asistencias" :key="asistencia.id">
<td>{{ asistencia.id }}</td>
<td>{{ asistencia.empleado_id }}</td>
<td>{{ formatDateTime(asistencia.entrada) }}</td>
<td>{{ asistencia.salida ? formatDateTime(asistencia.salida) : 'N/A' }}</td>
<td><span :class="`estado-${asistencia.estado?.toLowerCase().replace(/\s+/g, '-')}`">{{ asistencia.estado }}</span></td>
<td :title="asistencia.observacion">{{ truncateText(asistencia.observacion, 50) }}</td>
<td>
<button @click="editAsistencia(asistencia.id)" class="action-button edit-button">Editar</button>
<button @click="confirmDeleteAsistencia(asistencia)" class="action-button delete-button">Eliminar</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { useAsistenciasStore } from '../../stores/useAsistencias';
const props = defineProps({
asistencias: {
type: Array,
required: true,
default: () => [],
},
});
const emit = defineEmits(['edit']);
const asistenciasStore = useAsistenciasStore();
const formatDateTime = (dateTimeString) => {
if (!dateTimeString) return 'N/A';
const date = new Date(dateTimeString);
// Using UTC methods to ensure consistency if dates are stored in UTC
const day = String(date.getUTCDate()).padStart(2, '0');
const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Months are 0-indexed
const year = date.getUTCFullYear();
const hours = String(date.getUTCHours()).padStart(2, '0');
const minutes = String(date.getUTCMinutes()).padStart(2, '0');
return `${day}/${month}/${year} ${hours}:${minutes}`;
};
const truncateText = (text, maxLength) => {
if (!text) return 'N/A';
if (text.length <= maxLength) return text;
return text.substring(0, maxLength) + '...';
};
const editAsistencia = (id) => {
emit('edit', id);
};
const confirmDeleteAsistencia = (asistencia) => {
if (confirm(`¿Está seguro de que desea eliminar la asistencia ID: ${asistencia.id} (Empleado: ${asistencia.empleado_id})?`)) {
deleteAsistenciaInternal(asistencia.id);
}
};
const deleteAsistenciaInternal = async (id) => {
try {
await asistenciasStore.deleteAsistencia(id);
// Optional: Show success notification or emit 'deleted' event
} catch (error) {
console.error(`Error deleting asistencia with id ${id}:`, error);
alert('Ocurrió un error al eliminar la asistencia.');
}
};
</script
<style scoped>
.tabla-asistencias-container {
overflow-x: auto;
}
.tabla-asistencias {
width: 100%;
border-collapse: collapse;
margin-top: 1em;
font-size: 0.9em;
}
.tabla-asistencias th,
.tabla-asistencias td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
vertical-align: middle; /* Good for table cells */
}
.tabla-asistencias th {
background-color: #f4f6f8; /* Light grey for header */
font-weight: 600; /* Bolder text for header */
color: #333;
}
.tabla-asistencias tr:nth-child(even) {
background-color: #f9fafb; /* Very light alternating row color */
}
.tabla-asistencias tr:hover {
background-color: #f0f0f0; /* Hover effect */
}
.action-button {
padding: 6px 10px;
margin-right: 6px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.85em;
transition: background-color 0.2s ease, transform 0.1s ease;
}
.action-button:hover {
transform: translateY(-1px); /* Slight lift effect */
}
.edit-button {
background-color: #007bff; /* Blue */
color: white;
}
.edit-button:hover {
background-color: #0056b3;
}
.delete-button {
background-color: #dc3545; /* Red */
color: white;
}
.delete-button:hover {
background-color: #c82333;
}
/* Estado specific styling (using text color for tables is often cleaner) */
.estado-pendiente { color: #ffc107; font-weight: bold; } /* Amber */
.estado-presente,
.estado-confirmada { color: #28a745; font-weight: bold; } /* Green */
.estado-ausente { color: #dc3545; font-weight: bold; } /* Red */
.estado-justificada { color: #17a2b8; font-weight: bold; } /* Info Blue */
.estado-cancelada,
.estado-anulada { color: #6c757d; font-weight: bold; } /* Gray */
/* If you prefer background colors like in cards, copy those styles here, but they can be visually heavy in tables. */
</style>

View File

@@ -1,2 +1,134 @@
<template>
<div class="planilla-card">
<h3>{{ planilla.titulo }}</h3>
<p><strong>Empleado ID:</strong> {{ planilla.empleado_id }}</p>
<p><strong>Desde:</strong> {{ formatDate(planilla.fecha_desde) }}</p>
<p><strong>Hasta:</strong> {{ formatDate(planilla.fecha_hasta) }}</p>
<p><strong>Total:</strong> {{ formatCurrency(planilla.total) }}</p>
<p><strong>Estado:</strong> <span :class="`estado-${planilla.estado?.toLowerCase()}`">{{ planilla.estado }}</span></p>
<div class="actions">
<button @click="editPlanilla">Editar</button>
<button @click="confirmDeletePlanilla">Eliminar</button>
</div>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { usePlanillasStore } from '../../stores/usePlanillas';
const props = defineProps({
planilla: {
type: Object,
required: true,
},
});
const emit = defineEmits(['edit']);
const planillasStore = usePlanillasStore();
const formatDate = (dateString) => {
if (!dateString) return 'N/A';
const date = new Date(dateString);
return date.toLocaleDateString('es-ES', { // Using Spanish locale for date
year: 'numeric',
month: 'long',
day: 'numeric',
});
};
const formatCurrency = (value) => {
if (value == null) return 'N/A'; // Handle null or undefined totals
// Assuming the value is a number or can be converted to one.
// Adjust 'es-PY' and currency 'PYG' (Paraguayan Guarani) as needed.
return Number(value).toLocaleString('es-PY', {
style: 'currency',
currency: 'PYG'
});
};
const editPlanilla = () => {
emit('edit', props.planilla.id);
};
const confirmDeletePlanilla = () => {
// In a real app, you'd use a confirmation dialog here
if (confirm(`¿Está seguro de que desea eliminar la planilla "${props.planilla.titulo}"?`)) {
deletePlanilla();
}
};
const deletePlanilla = async () => {
try {
await planillasStore.deletePlanilla(props.planilla.id);
// Optionally, emit an event or show a notification upon successful deletion
// For example: emit('deleted', props.planilla.id);
} catch (error) {
console.error('Error deleting planilla:', error);
// Handle error (e.g., show a notification to the user)
}
};
</script>
<style scoped>
.planilla-card {
border: 1px solid #ccc;
padding: 16px;
margin-bottom: 16px;
border-radius: 8px;
background-color: #f9f9f9;
}
.planilla-card h3 {
margin-top: 0;
color: #333;
}
.planilla-card p {
margin: 8px 0;
color: #555;
}
.planilla-card .actions {
margin-top: 12px;
display: flex;
gap: 8px;
}
.planilla-card button {
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
}
.planilla-card button:hover {
opacity: 0.8;
}
.actions button:first-child { /* Edit button */
background-color: #007bff;
color: white;
}
.actions button:last-child { /* Delete button */
background-color: #dc3545;
color: white;
}
/* Example status styling */
.estado-pagado {
color: green;
font-weight: bold;
}
.estado-pendiente {
color: orange;
font-weight: bold;
}
.estado-anulado {
color: red;
font-weight: bold;
text-decoration: line-through;
}
</style>

View File

@@ -1,2 +1,167 @@
<template>
<div class="tabla-planillas-container">
<table class="tabla-planillas">
<thead>
<tr>
<th>ID</th>
<th>Título</th>
<th>Empleado ID</th>
<th>Fecha Desde</th>
<th>Fecha Hasta</th>
<th>Total</th>
<th>Estado</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<tr v-if="planillas && planillas.length === 0">
<td :colspan="8" style="text-align: center;">No hay planillas para mostrar.</td>
</tr>
<tr v-for="planilla in planillas" :key="planilla.id">
<td>{{ planilla.id }}</td>
<td>{{ planilla.titulo }}</td>
<td>{{ planilla.empleado_id }}</td>
<td>{{ formatDate(planilla.fecha_desde) }}</td>
<td>{{ formatDate(planilla.fecha_hasta) }}</td>
<td>{{ formatCurrency(planilla.total) }}</td>
<td><span :class="`estado-${planilla.estado?.toLowerCase()}`">{{ planilla.estado }}</span></td>
<td>
<button @click="editPlanilla(planilla.id)" class="action-button edit-button">Editar</button>
<button @click="confirmDeletePlanilla(planilla)" class="action-button delete-button">Eliminar</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { usePlanillasStore } from '../../stores/usePlanillas';
const props = defineProps({
planillas: {
type: Array,
required: true,
default: () => [],
},
});
const emit = defineEmits(['edit']); // Removed 'delete' as it's handled internally
const planillasStore = usePlanillasStore();
const formatDate = (dateString) => {
if (!dateString) return 'N/A';
const date = new Date(dateString);
return date.toLocaleDateString('es-ES', {
year: 'numeric',
month: '2-digit', // Changed to 2-digit for table compactness
day: '2-digit', // Changed to 2-digit for table compactness
});
};
const formatCurrency = (value) => {
if (value == null) return 'N/A';
return Number(value).toLocaleString('es-PY', {
style: 'currency',
currency: 'PYG',
});
};
const editPlanilla = (id) => {
emit('edit', id);
};
const confirmDeletePlanilla = (planilla) => {
if (confirm(`¿Está seguro de que desea eliminar la planilla "${planilla.titulo}" (ID: ${planilla.id})?`)) {
deletePlanillaInternal(planilla.id);
}
};
const deletePlanillaInternal = async (id) => {
try {
await planillasStore.deletePlanilla(id);
// Optional: Show success notification
// No need to emit 'delete' if the store handles list updates and parent components react to store changes
} catch (error) {
console.error(`Error deleting planilla with id ${id}:`, error);
// Optional: Show error notification
}
};
</script>
<style scoped>
.tabla-planillas-container {
overflow-x: auto; /* Allows table to be scrolled horizontally if needed */
}
.tabla-planillas {
width: 100%;
border-collapse: collapse;
margin-top: 1em;
font-size: 0.9em;
}
.tabla-planillas th,
.tabla-planillas td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
.tabla-planillas th {
background-color: #f2f2f2;
font-weight: bold;
}
.tabla-planillas tr:nth-child(even) {
background-color: #f9f9f9;
}
.tabla-planillas tr:hover {
background-color: #f1f1f1;
}
.action-button {
padding: 5px 10px;
margin-right: 5px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9em;
}
.edit-button {
background-color: #007bff;
color: white;
}
.edit-button:hover {
background-color: #0056b3;
}
.delete-button {
background-color: #dc3545;
color: white;
}
.delete-button:hover {
background-color: #c82333;
}
/* Status styling (similar to cardPlanilla) */
.estado-pagado {
color: green;
font-weight: bold;
}
.estado-pendiente {
color: orange;
font-weight: bold;
}
.estado-anulado {
color: red;
font-weight: bold;
/* text-decoration: line-through; */ /* Optional for table view */
}
</style>

View File

@@ -1,2 +1,159 @@
<template>
<div class="tarea-card">
<h4>{{ tarea.titulo }}</h4>
<p><strong>Empleado ID:</strong> {{ tarea.empleado_id }}</p>
<p><strong>Fecha:</strong> {{ formatDate(tarea.fecha) }}</p>
<p><strong>Estado:</strong> <span :class="`estado-${tarea.estado?.toLowerCase().replace(/\s+/g, '-')}`">{{ tarea.estado }}</span></p>
<p><strong>Tipo:</strong> {{ tarea.tipo || 'N/A' }}</p>
<p v-if="tarea.precio != null"><strong>Precio:</strong> {{ formatCurrency(tarea.precio) }}</p>
<p v-if="tarea.observacion"><strong>Observación:</strong> {{ tarea.observacion }}</p>
<div class="actions">
<button @click="editTarea" class="action-button edit-button">Editar</button>
<button @click="confirmDeleteTarea" class="action-button delete-button">Eliminar</button>
</div>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { useTareasStore } from '../../stores/useTareas';
const props = defineProps({
tarea: {
type: Object,
required: true,
},
});
const emit = defineEmits(['edit']);
const tareasStore = useTareasStore();
const formatDate = (dateString) => {
if (!dateString) return 'N/A';
const date = new Date(dateString);
return date.toLocaleDateString('es-ES', { // Spanish locale
year: 'numeric',
month: 'long',
day: 'numeric',
});
};
const formatCurrency = (value) => {
if (value == null) return '';
return Number(value).toLocaleString('es-PY', { // Paraguayan Guarani
style: 'currency',
currency: 'PYG',
});
};
const editTarea = () => {
emit('edit', props.tarea.id);
};
const confirmDeleteTarea = () => {
if (confirm(`¿Está seguro de que desea eliminar la tarea "${props.tarea.titulo}"?`)) {
deleteTareaInternal();
}
};
const deleteTareaInternal = async () => {
try {
await tareasStore.deleteTarea(props.tarea.id);
// Optionally, emit a 'deleted' event: emit('deleted', props.tarea.id);
// Or show a success notification.
} catch (error) {
console.error('Error deleting tarea:', error);
alert('Ocurrió un error al eliminar la tarea. Por favor, intente de nuevo.');
// Potentially show a more user-friendly notification.
}
};
</script>
<style scoped>
.tarea-card {
border: 1px solid #e0e0e0;
padding: 16px;
margin-bottom: 16px;
border-radius: 8px;
background-color: #ffffff;
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
transition: box-shadow 0.3s ease-in-out;
}
.tarea-card:hover {
box-shadow: 0 4px 8px rgba(0,0,0,0.08);
}
.tarea-card h4 {
margin-top: 0;
margin-bottom: 12px;
color: #333;
font-size: 1.15em; /* Slightly smaller than a typical h3 */
}
.tarea-card p {
margin: 6px 0;
color: #555;
font-size: 0.95em;
line-height: 1.5;
}
.tarea-card p strong {
color: #444;
}
.actions {
margin-top: 16px;
display: flex;
gap: 10px;
}
.action-button {
padding: 8px 12px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.9em;
transition: background-color 0.2s ease, opacity 0.2s ease;
}
.edit-button {
background-color: #007bff; /* Primary blue */
color: white;
}
.edit-button:hover {
background-color: #0056b3; /* Darker blue */
}
.delete-button {
background-color: #dc3545; /* Red */
color: white;
}
.delete-button:hover {
background-color: #c82333; /* Darker red */
}
/* Status styling: Added .replace(/\s+/g, '-') for multi-word statuses */
.estado-pendiente {
color: #ff9800; /* Orange */
font-weight: bold;
}
.estado-realizada,
.estado-completada, /* Common synonyms for 'done' */
.estado-hecho {
color: #4caf50; /* Green */
font-weight: bold;
}
.estado-en-progreso { /* Example for 'in progress' */
color: #2196f3; /* Blue */
font-weight: bold;
}
.estado-anulada,
.estado-cancelada {
color: #f44336; /* Red */
font-weight: bold;
/* text-decoration: line-through; */ /* Optional */
}
</style>

View File

@@ -1,2 +1,167 @@
<template>
<div class="tabla-tareas-container">
<table class="tabla-tareas">
<thead>
<tr>
<th>ID</th>
<th>Título</th>
<th>Empleado ID</th>
<th>Fecha</th>
<th>Estado</th>
<th>Tipo</th>
<th>Precio</th>
<th>Planilla ID</th>
<th>Acciones</th>
</tr>
</thead>
<tbody>
<tr v-if="!tareas || tareas.length === 0">
<td :colspan="9" style="text-align: center;">No hay tareas para mostrar.</td>
</tr>
<tr v-for="tarea in tareas" :key="tarea.id">
<td>{{ tarea.id }}</td>
<td>{{ tarea.titulo }}</td>
<td>{{ tarea.empleado_id }}</td>
<td>{{ formatDate(tarea.fecha) }}</td>
<td><span :class="`estado-${tarea.estado?.toLowerCase().replace(/\s+/g, '-')}`">{{ tarea.estado }}</span></td>
<td>{{ tarea.tipo || 'N/A' }}</td>
<td>{{ tarea.precio != null ? formatCurrency(tarea.precio) : 'N/A' }}</td>
<td>{{ tarea.planilla_id || 'N/A' }}</td>
<td>
<button @click="editTarea(tarea.id)" class="action-button edit-button">Editar</button>
<button @click="confirmDeleteTarea(tarea)" class="action-button delete-button">Eliminar</button>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template></template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { useTareasStore } from '../../stores/useTareas';
const props = defineProps({
tareas: {
type: Array,
required: true,
default: () => [],
},
});
const emit = defineEmits(['edit']);
const tareasStore = useTareasStore();
const formatDate = (dateString) => {
if (!dateString) return 'N/A';
// Assuming dateString might be a full ISO string, ensure it's handled correctly by Date constructor
const date = new Date(dateString);
const day = String(date.getUTCDate()).padStart(2, '0'); // Use getUTCDate for consistency if dates are stored in UTC
const month = String(date.getUTCMonth() + 1).padStart(2, '0'); // Months are 0-indexed
const year = date.getUTCFullYear();
return `${day}/${month}/${year}`;
};
const formatCurrency = (value) => {
if (value == null) return 'N/A';
return Number(value).toLocaleString('es-PY', { // Paraguayan Guarani
style: 'currency',
currency: 'PYG',
});
};
const editTarea = (id) => {
emit('edit', id);
};
const confirmDeleteTarea = (tarea) => {
if (confirm(`¿Está seguro de que desea eliminar la tarea "${tarea.titulo}" (ID: ${tarea.id})?`)) {
deleteTareaInternal(tarea.id);
}
};
const deleteTareaInternal = async (id) => {
try {
await tareasStore.deleteTarea(id);
// Optional: Show success notification or emit 'deleted' event
} catch (error) {
console.error(`Error deleting tarea with id ${id}:`, error);
alert('Ocurrió un error al eliminar la tarea.');
// Optional: Show error notification
}
};
</script>
<style scoped>
.tabla-tareas-container {
overflow-x: auto;
}
.tabla-tareas {
width: 100%;
border-collapse: collapse;
margin-top: 1em;
font-size: 0.9em;
}
.tabla-tareas th,
.tabla-tareas td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
vertical-align: middle;
}
.tabla-tareas th {
background-color: #f4f6f8;
font-weight: 600;
color: #333;
}
.tabla-tareas tr:nth-child(even) {
background-color: #f9fafb;
}
.tabla-tareas tr:hover {
background-color: #f0f0f0;
}
.action-button {
padding: 6px 10px;
margin-right: 6px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 0.85em;
transition: background-color 0.2s ease, transform 0.1s ease;
}
.action-button:hover {
transform: translateY(-1px);
}
.edit-button {
background-color: #007bff; /* Blue */
color: white;
}
.edit-button:hover {
background-color: #0056b3;
}
.delete-button {
background-color: #dc3545; /* Red */
color: white;
}
.delete-button:hover {
background-color: #c82333;
}
/* Status styling (consistent with cardTarea) */
.estado-pendiente { color: #ff9800; font-weight: bold; } /* Orange */
.estado-realizada,
.estado-completada, /* Synonyms */
.estado-hecho { color: #4caf50; font-weight: bold; } /* Green */
.estado-en-progreso { color: #2196f3; font-weight: bold; } /* Blue */
.estado-anulada,
.estado-cancelada { color: #f44336; font-weight: bold; } /* Red */
</style>