actualizaciones varias
This commit is contained in:
parent
3367d4ede7
commit
5a83a52e3f
|
|
@ -0,0 +1,275 @@
|
||||||
|
class PlanningCalendar {
|
||||||
|
constructor() {
|
||||||
|
this.currentDate = new Date();
|
||||||
|
this.tasks = this.loadTasks();
|
||||||
|
this.draggedTask = null;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.setupEventListeners();
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
setupEventListeners() {
|
||||||
|
document.getElementById('prevMonth').addEventListener('click', () => this.previousMonth());
|
||||||
|
document.getElementById('nextMonth').addEventListener('click', () => this.nextMonth());
|
||||||
|
document.getElementById('addTaskForm').addEventListener('submit', (e) => this.addTask(e));
|
||||||
|
document.getElementById('resetBtn').addEventListener('click', () => this.resetAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
previousMonth() {
|
||||||
|
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
nextMonth() {
|
||||||
|
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
this.renderMonthTitle();
|
||||||
|
this.renderCalendar();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderMonthTitle() {
|
||||||
|
const options = { month: 'long', year: 'numeric' };
|
||||||
|
const title = this.currentDate.toLocaleDateString('es-ES', options);
|
||||||
|
document.getElementById('monthTitle').textContent = title.charAt(0).toUpperCase() + title.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderCalendar() {
|
||||||
|
const grid = document.getElementById('calendarGrid');
|
||||||
|
grid.innerHTML = '';
|
||||||
|
|
||||||
|
// Encabezados de días
|
||||||
|
const dayNames = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
|
||||||
|
dayNames.forEach(day => {
|
||||||
|
const header = document.createElement('div');
|
||||||
|
header.className = 'day-header';
|
||||||
|
header.textContent = day;
|
||||||
|
grid.appendChild(header);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Obtener primer y último día del mes
|
||||||
|
const year = this.currentDate.getFullYear();
|
||||||
|
const month = this.currentDate.getMonth();
|
||||||
|
const firstDay = new Date(year, month, 1);
|
||||||
|
const lastDay = new Date(year, month + 1, 0);
|
||||||
|
|
||||||
|
// Ajustar para que lunes sea 0
|
||||||
|
let dayOfWeek = firstDay.getDay() - 1;
|
||||||
|
if (dayOfWeek === -1) dayOfWeek = 6;
|
||||||
|
|
||||||
|
// Días del mes anterior
|
||||||
|
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
||||||
|
for (let i = dayOfWeek - 1; i >= 0; i--) {
|
||||||
|
const cell = this.createDayCell(prevMonthLastDay - i, 'other-month');
|
||||||
|
grid.appendChild(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Días del mes actual
|
||||||
|
for (let day = 1; day <= lastDay.getDate(); day++) {
|
||||||
|
const date = new Date(year, month, day);
|
||||||
|
const cell = this.createDayCell(day, '', date);
|
||||||
|
grid.appendChild(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Días del próximo mes
|
||||||
|
const remainingCells = grid.children.length - 7; // 7 headers
|
||||||
|
const totalCells = Math.ceil(remainingCells / 7) * 7;
|
||||||
|
for (let day = 1; day <= totalCells - remainingCells; day++) {
|
||||||
|
const cell = this.createDayCell(day, 'other-month');
|
||||||
|
grid.appendChild(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createDayCell(day, extraClass, date = null) {
|
||||||
|
const cell = document.createElement('div');
|
||||||
|
cell.className = `day-cell ${extraClass}`;
|
||||||
|
|
||||||
|
if (extraClass === 'other-month') {
|
||||||
|
cell.classList.add('empty');
|
||||||
|
} else {
|
||||||
|
// Es día del mes actual
|
||||||
|
const isToday = date && this.isToday(date);
|
||||||
|
const isWeekend = date && (date.getDay() === 0 || date.getDay() === 6);
|
||||||
|
|
||||||
|
if (isToday) cell.classList.add('today');
|
||||||
|
if (isWeekend) cell.classList.add('weekend');
|
||||||
|
|
||||||
|
const dayNumber = document.createElement('div');
|
||||||
|
dayNumber.className = 'day-number' + (isWeekend ? ' weekend' : '');
|
||||||
|
dayNumber.textContent = day;
|
||||||
|
cell.appendChild(dayNumber);
|
||||||
|
|
||||||
|
const dateKey = this.getDateKey(date);
|
||||||
|
const dayTasks = this.tasks[dateKey] || [];
|
||||||
|
|
||||||
|
const tasksList = document.createElement('div');
|
||||||
|
tasksList.className = 'tasks-list';
|
||||||
|
|
||||||
|
dayTasks.forEach(task => {
|
||||||
|
const taskEl = this.createTaskElement(task, dateKey);
|
||||||
|
tasksList.appendChild(taskEl);
|
||||||
|
});
|
||||||
|
|
||||||
|
cell.appendChild(tasksList);
|
||||||
|
|
||||||
|
// Agregar zona de drop
|
||||||
|
const dropZone = document.createElement('div');
|
||||||
|
dropZone.className = 'drop-zone';
|
||||||
|
cell.appendChild(dropZone);
|
||||||
|
|
||||||
|
// Event listeners para drag & drop
|
||||||
|
cell.addEventListener('dragover', (e) => this.handleDragOver(e));
|
||||||
|
cell.addEventListener('drop', (e) => this.handleDrop(e, dateKey));
|
||||||
|
cell.addEventListener('dragleave', (e) => this.handleDragLeave(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
createTaskElement(task, dateKey) {
|
||||||
|
const taskEl = document.createElement('div');
|
||||||
|
taskEl.className = 'task-item';
|
||||||
|
taskEl.draggable = true;
|
||||||
|
taskEl.textContent = task.text;
|
||||||
|
|
||||||
|
const deleteBtn = document.createElement('button');
|
||||||
|
deleteBtn.type = 'button';
|
||||||
|
deleteBtn.className = 'task-delete-btn';
|
||||||
|
deleteBtn.textContent = '✕';
|
||||||
|
deleteBtn.addEventListener('click', (e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.deleteTask(task.id, dateKey);
|
||||||
|
});
|
||||||
|
|
||||||
|
taskEl.appendChild(deleteBtn);
|
||||||
|
|
||||||
|
taskEl.addEventListener('dragstart', (e) => this.handleDragStart(e, task.id, dateKey));
|
||||||
|
taskEl.addEventListener('dragend', (e) => this.handleDragEnd(e));
|
||||||
|
|
||||||
|
return taskEl;
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragStart(e, taskId, fromDateKey) {
|
||||||
|
this.draggedTask = { taskId, fromDateKey };
|
||||||
|
e.target.classList.add('dragging');
|
||||||
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragEnd(e) {
|
||||||
|
e.target.classList.remove('dragging');
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragOver(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.dataTransfer.dropEffect = 'move';
|
||||||
|
e.target.closest('.day-cell').classList.add('drag-over');
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDragLeave(e) {
|
||||||
|
e.target.closest('.day-cell').classList.remove('drag-over');
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDrop(e, toDateKey) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.target.closest('.day-cell').classList.remove('drag-over');
|
||||||
|
|
||||||
|
if (!this.draggedTask) return;
|
||||||
|
|
||||||
|
const { taskId, fromDateKey } = this.draggedTask;
|
||||||
|
this.moveTask(taskId, fromDateKey, toDateKey);
|
||||||
|
this.draggedTask = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
addTask(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const input = document.getElementById('taskInput');
|
||||||
|
const text = input.value.trim();
|
||||||
|
|
||||||
|
if (!text) return;
|
||||||
|
|
||||||
|
const today = this.getDateKey(new Date());
|
||||||
|
const task = {
|
||||||
|
id: Date.now(),
|
||||||
|
text: text,
|
||||||
|
date: today
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!this.tasks[today]) {
|
||||||
|
this.tasks[today] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tasks[today].push(task);
|
||||||
|
this.saveTasks();
|
||||||
|
input.value = '';
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteTask(taskId, dateKey) {
|
||||||
|
if (this.tasks[dateKey]) {
|
||||||
|
this.tasks[dateKey] = this.tasks[dateKey].filter(t => t.id !== taskId);
|
||||||
|
if (this.tasks[dateKey].length === 0) {
|
||||||
|
delete this.tasks[dateKey];
|
||||||
|
}
|
||||||
|
this.saveTasks();
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveTask(taskId, fromDateKey, toDateKey) {
|
||||||
|
if (!this.tasks[fromDateKey]) return;
|
||||||
|
|
||||||
|
const taskIndex = this.tasks[fromDateKey].findIndex(t => t.id === taskId);
|
||||||
|
if (taskIndex === -1) return;
|
||||||
|
|
||||||
|
const task = this.tasks[fromDateKey][taskIndex];
|
||||||
|
this.tasks[fromDateKey].splice(taskIndex, 1);
|
||||||
|
|
||||||
|
if (this.tasks[fromDateKey].length === 0) {
|
||||||
|
delete this.tasks[fromDateKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.tasks[toDateKey]) {
|
||||||
|
this.tasks[toDateKey] = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tasks[toDateKey].push(task);
|
||||||
|
this.saveTasks();
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
getDateKey(date) {
|
||||||
|
return date.toISOString().split('T')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
isToday(date) {
|
||||||
|
const today = new Date();
|
||||||
|
return date.toDateString() === today.toDateString();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTasks() {
|
||||||
|
localStorage.setItem('planningTasks', JSON.stringify(this.tasks));
|
||||||
|
}
|
||||||
|
|
||||||
|
loadTasks() {
|
||||||
|
const stored = localStorage.getItem('planningTasks');
|
||||||
|
return stored ? JSON.parse(stored) : {};
|
||||||
|
}
|
||||||
|
|
||||||
|
resetAll() {
|
||||||
|
if (confirm('¿Estás seguro de que deseas limpiar todas las tareas?')) {
|
||||||
|
this.tasks = {};
|
||||||
|
this.saveTasks();
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inicializar cuando el DOM esté listo
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
new PlanningCalendar();
|
||||||
|
});
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Planning TAI — Agenda</title>
|
<title>Planning TAI — Agenda</title>
|
||||||
<link rel="stylesheet" th:href="@{/css/style.css}">
|
<link rel="stylesheet" th:href="@{/css/style.css}">
|
||||||
|
<link rel="stylesheet" th:href="@{/css/planning.css}">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -60,286 +61,6 @@
|
||||||
<div class="calendar-grid" id="calendarGrid"></div>
|
<div class="calendar-grid" id="calendarGrid"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script th:src="@{/js/planningdinamico.js}"></script>
|
||||||
// ════════════════════════════════════════════════════════════════
|
|
||||||
// Planning Customizable - Calendario con Drag & Drop
|
|
||||||
// ════════════════════════════════════════════════════════════════
|
|
||||||
|
|
||||||
class PlanningCalendar {
|
|
||||||
constructor() {
|
|
||||||
this.currentDate = new Date();
|
|
||||||
this.tasks = this.loadTasks();
|
|
||||||
this.draggedTask = null;
|
|
||||||
this.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.setupEventListeners();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
setupEventListeners() {
|
|
||||||
document.getElementById('prevMonth').addEventListener('click', () => this.previousMonth());
|
|
||||||
document.getElementById('nextMonth').addEventListener('click', () => this.nextMonth());
|
|
||||||
document.getElementById('addTaskForm').addEventListener('submit', (e) => this.addTask(e));
|
|
||||||
document.getElementById('resetBtn').addEventListener('click', () => this.resetAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
previousMonth() {
|
|
||||||
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
nextMonth() {
|
|
||||||
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
this.renderMonthTitle();
|
|
||||||
this.renderCalendar();
|
|
||||||
}
|
|
||||||
|
|
||||||
renderMonthTitle() {
|
|
||||||
const options = { month: 'long', year: 'numeric' };
|
|
||||||
const title = this.currentDate.toLocaleDateString('es-ES', options);
|
|
||||||
document.getElementById('monthTitle').textContent = title.charAt(0).toUpperCase() + title.slice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
renderCalendar() {
|
|
||||||
const grid = document.getElementById('calendarGrid');
|
|
||||||
grid.innerHTML = '';
|
|
||||||
|
|
||||||
// Encabezados de días
|
|
||||||
const dayNames = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
|
|
||||||
dayNames.forEach(day => {
|
|
||||||
const header = document.createElement('div');
|
|
||||||
header.className = 'day-header';
|
|
||||||
header.textContent = day;
|
|
||||||
grid.appendChild(header);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Obtener primer y último día del mes
|
|
||||||
const year = this.currentDate.getFullYear();
|
|
||||||
const month = this.currentDate.getMonth();
|
|
||||||
const firstDay = new Date(year, month, 1);
|
|
||||||
const lastDay = new Date(year, month + 1, 0);
|
|
||||||
|
|
||||||
// Ajustar para que lunes sea 0
|
|
||||||
let dayOfWeek = firstDay.getDay() - 1;
|
|
||||||
if (dayOfWeek === -1) dayOfWeek = 6;
|
|
||||||
|
|
||||||
// Días del mes anterior
|
|
||||||
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
|
||||||
for (let i = dayOfWeek - 1; i >= 0; i--) {
|
|
||||||
const cell = this.createDayCell(prevMonthLastDay - i, 'other-month');
|
|
||||||
grid.appendChild(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Días del mes actual
|
|
||||||
for (let day = 1; day <= lastDay.getDate(); day++) {
|
|
||||||
const date = new Date(year, month, day);
|
|
||||||
const cell = this.createDayCell(day, '', date);
|
|
||||||
grid.appendChild(cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Días del próximo mes
|
|
||||||
const remainingCells = grid.children.length - 7; // 7 headers
|
|
||||||
const totalCells = Math.ceil(remainingCells / 7) * 7;
|
|
||||||
for (let day = 1; day <= totalCells - remainingCells; day++) {
|
|
||||||
const cell = this.createDayCell(day, 'other-month');
|
|
||||||
grid.appendChild(cell);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createDayCell(day, extraClass, date = null) {
|
|
||||||
const cell = document.createElement('div');
|
|
||||||
cell.className = `day-cell ${extraClass}`;
|
|
||||||
|
|
||||||
if (extraClass === 'other-month') {
|
|
||||||
cell.classList.add('empty');
|
|
||||||
} else {
|
|
||||||
// Es día del mes actual
|
|
||||||
const isToday = date && this.isToday(date);
|
|
||||||
const isWeekend = date && (date.getDay() === 0 || date.getDay() === 6);
|
|
||||||
|
|
||||||
if (isToday) cell.classList.add('today');
|
|
||||||
if (isWeekend) cell.classList.add('weekend');
|
|
||||||
|
|
||||||
const dayNumber = document.createElement('div');
|
|
||||||
dayNumber.className = 'day-number' + (isWeekend ? ' weekend' : '');
|
|
||||||
dayNumber.textContent = day;
|
|
||||||
cell.appendChild(dayNumber);
|
|
||||||
|
|
||||||
const dateKey = this.getDateKey(date);
|
|
||||||
const dayTasks = this.tasks[dateKey] || [];
|
|
||||||
|
|
||||||
const tasksList = document.createElement('div');
|
|
||||||
tasksList.className = 'tasks-list';
|
|
||||||
|
|
||||||
dayTasks.forEach(task => {
|
|
||||||
const taskEl = this.createTaskElement(task, dateKey);
|
|
||||||
tasksList.appendChild(taskEl);
|
|
||||||
});
|
|
||||||
|
|
||||||
cell.appendChild(tasksList);
|
|
||||||
|
|
||||||
// Agregar zona de drop
|
|
||||||
const dropZone = document.createElement('div');
|
|
||||||
dropZone.className = 'drop-zone';
|
|
||||||
cell.appendChild(dropZone);
|
|
||||||
|
|
||||||
// Event listeners para drag & drop
|
|
||||||
cell.addEventListener('dragover', (e) => this.handleDragOver(e));
|
|
||||||
cell.addEventListener('drop', (e) => this.handleDrop(e, dateKey));
|
|
||||||
cell.addEventListener('dragleave', (e) => this.handleDragLeave(e));
|
|
||||||
}
|
|
||||||
|
|
||||||
return cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
createTaskElement(task, dateKey) {
|
|
||||||
const taskEl = document.createElement('div');
|
|
||||||
taskEl.className = 'task-item';
|
|
||||||
taskEl.draggable = true;
|
|
||||||
taskEl.textContent = task.text;
|
|
||||||
|
|
||||||
const deleteBtn = document.createElement('button');
|
|
||||||
deleteBtn.type = 'button';
|
|
||||||
deleteBtn.className = 'task-delete-btn';
|
|
||||||
deleteBtn.textContent = '✕';
|
|
||||||
deleteBtn.addEventListener('click', (e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
this.deleteTask(task.id, dateKey);
|
|
||||||
});
|
|
||||||
|
|
||||||
taskEl.appendChild(deleteBtn);
|
|
||||||
|
|
||||||
taskEl.addEventListener('dragstart', (e) => this.handleDragStart(e, task.id, dateKey));
|
|
||||||
taskEl.addEventListener('dragend', (e) => this.handleDragEnd(e));
|
|
||||||
|
|
||||||
return taskEl;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragStart(e, taskId, fromDateKey) {
|
|
||||||
this.draggedTask = { taskId, fromDateKey };
|
|
||||||
e.target.classList.add('dragging');
|
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragEnd(e) {
|
|
||||||
e.target.classList.remove('dragging');
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragOver(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.dataTransfer.dropEffect = 'move';
|
|
||||||
e.target.closest('.day-cell').classList.add('drag-over');
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDragLeave(e) {
|
|
||||||
e.target.closest('.day-cell').classList.remove('drag-over');
|
|
||||||
}
|
|
||||||
|
|
||||||
handleDrop(e, toDateKey) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.target.closest('.day-cell').classList.remove('drag-over');
|
|
||||||
|
|
||||||
if (!this.draggedTask) return;
|
|
||||||
|
|
||||||
const { taskId, fromDateKey } = this.draggedTask;
|
|
||||||
this.moveTask(taskId, fromDateKey, toDateKey);
|
|
||||||
this.draggedTask = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
addTask(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const input = document.getElementById('taskInput');
|
|
||||||
const text = input.value.trim();
|
|
||||||
|
|
||||||
if (!text) return;
|
|
||||||
|
|
||||||
const today = this.getDateKey(new Date());
|
|
||||||
const task = {
|
|
||||||
id: Date.now(),
|
|
||||||
text: text,
|
|
||||||
date: today
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.tasks[today]) {
|
|
||||||
this.tasks[today] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tasks[today].push(task);
|
|
||||||
this.saveTasks();
|
|
||||||
input.value = '';
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteTask(taskId, dateKey) {
|
|
||||||
if (this.tasks[dateKey]) {
|
|
||||||
this.tasks[dateKey] = this.tasks[dateKey].filter(t => t.id !== taskId);
|
|
||||||
if (this.tasks[dateKey].length === 0) {
|
|
||||||
delete this.tasks[dateKey];
|
|
||||||
}
|
|
||||||
this.saveTasks();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
moveTask(taskId, fromDateKey, toDateKey) {
|
|
||||||
if (!this.tasks[fromDateKey]) return;
|
|
||||||
|
|
||||||
const taskIndex = this.tasks[fromDateKey].findIndex(t => t.id === taskId);
|
|
||||||
if (taskIndex === -1) return;
|
|
||||||
|
|
||||||
const task = this.tasks[fromDateKey][taskIndex];
|
|
||||||
this.tasks[fromDateKey].splice(taskIndex, 1);
|
|
||||||
|
|
||||||
if (this.tasks[fromDateKey].length === 0) {
|
|
||||||
delete this.tasks[fromDateKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.tasks[toDateKey]) {
|
|
||||||
this.tasks[toDateKey] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tasks[toDateKey].push(task);
|
|
||||||
this.saveTasks();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
|
|
||||||
getDateKey(date) {
|
|
||||||
return date.toISOString().split('T')[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
isToday(date) {
|
|
||||||
const today = new Date();
|
|
||||||
return date.toDateString() === today.toDateString();
|
|
||||||
}
|
|
||||||
|
|
||||||
saveTasks() {
|
|
||||||
localStorage.setItem('planningTasks', JSON.stringify(this.tasks));
|
|
||||||
}
|
|
||||||
|
|
||||||
loadTasks() {
|
|
||||||
const stored = localStorage.getItem('planningTasks');
|
|
||||||
return stored ? JSON.parse(stored) : {};
|
|
||||||
}
|
|
||||||
|
|
||||||
resetAll() {
|
|
||||||
if (confirm('¿Estás seguro de que deseas limpiar todas las tareas?')) {
|
|
||||||
this.tasks = {};
|
|
||||||
this.saveTasks();
|
|
||||||
this.render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inicializar cuando el DOM esté listo
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
new PlanningCalendar();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue