actualizaciones varias

This commit is contained in:
Tatiana Villa Ema 2026-06-16 21:59:11 +02:00
parent a1270096d1
commit 76ceaab343
3 changed files with 286 additions and 0 deletions

82
css/planning.css Normal file
View File

@ -0,0 +1,82 @@
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, minmax(0, 1fr));
gap: 0.75rem;
margin-top: 1.5rem;
}
.weekday-header,
.day {
padding: 1rem;
border-radius: 0.5rem;
background: var(--bg-alt);
border: 1px solid var(--border);
}
.weekday-header {
text-align: center;
color: var(--text-muted);
text-transform: uppercase;
font-size: 0.78rem;
letter-spacing: 0.08em;
background: linear-gradient(180deg, rgba(255,255,255,0.02), transparent);
}
.day {
min-height: 5rem;
display: flex;
flex-direction: column;
justify-content: flex-start;
color: var(--text);
}
.day.empty {
background: transparent;
box-shadow: none;
border: none;
}
.day-number {
font-weight: 700;
margin-bottom: 0.5rem;
color: var(--text);
}
.day.today {
border: 2px solid var(--accent);
background: rgba(0,0,0,0.12);
}
.day.other-month {
opacity: 0.45;
}
.day-content {
flex: 1;
}
.topic {
display: block;
padding: 0.4rem 0.6rem;
margin-bottom: 0.4rem;
background: var(--bg);
border-left: 3px solid var(--accent);
color: var(--text);
font-size: 0.85rem;
border-radius: 4px;
box-shadow: inset 0 -1px 0 rgba(255,255,255,0.02);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
@media (max-width: 720px) {
.calendar-grid {
gap: 0.5rem;
}
.weekday-header,
.day {
padding: 0.75rem;
}
}

159
js/planning.js Normal file
View File

@ -0,0 +1,159 @@
document.addEventListener('DOMContentLoaded', () => {
const calendarGrid = document.getElementById('calendarGrid');
const monthTitle = document.getElementById('monthTitle');
const prevMonthBtn = document.getElementById('prevMonth');
const nextMonthBtn = document.getElementById('nextMonth');
const autoScheduleBtn = document.getElementById('autoScheduleBtn');
const monthNames = [
'enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'
];
const weekdayNames = ['Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb', 'Dom'];
const today = new Date();
let currentYear = today.getFullYear();
let currentMonth = today.getMonth();
const STORAGE_KEY = 'tatvil_scheduled_topics_v1';
function renderCalendar(year, month) {
calendarGrid.innerHTML = '';
weekdayNames.forEach(name => {
const headerCell = document.createElement('div');
headerCell.className = 'weekday-header';
headerCell.textContent = name;
calendarGrid.appendChild(headerCell);
});
const firstDay = new Date(year, month, 1);
const startWeekday = (firstDay.getDay() + 6) % 7; // Lunes = 0
const daysInMonth = new Date(year, month + 1, 0).getDate();
const isCurrentMonth = year === today.getFullYear() && month === today.getMonth();
for (let i = 0; i < startWeekday; i += 1) {
const emptyCell = document.createElement('div');
emptyCell.className = 'day empty';
calendarGrid.appendChild(emptyCell);
}
for (let day = 1; day <= daysInMonth; day += 1) {
const dayCell = document.createElement('div');
dayCell.className = 'day';
if (isCurrentMonth && day === today.getDate()) {
dayCell.classList.add('today');
}
const dateStr = `${year}-${pad(month+1)}-${pad(day)}`;
dayCell.dataset.date = dateStr;
const dayNumber = document.createElement('div');
dayNumber.className = 'day-number';
dayNumber.textContent = day;
dayCell.appendChild(dayNumber);
const content = document.createElement('div');
content.className = 'day-content';
// populate scheduled topic if exists
const scheduled = loadScheduledTopics();
if (scheduled[dateStr]) {
const t = document.createElement('div');
t.className = 'topic';
t.textContent = scheduled[dateStr];
content.appendChild(t);
}
dayCell.appendChild(content);
calendarGrid.appendChild(dayCell);
}
const totalCells = startWeekday + daysInMonth;
const remaining = totalCells % 7;
if (remaining !== 0) {
const fillers = 7 - remaining;
for (let i = 0; i < fillers; i += 1) {
const emptyCell = document.createElement('div');
emptyCell.className = 'day empty';
calendarGrid.appendChild(emptyCell);
}
}
const title = `${monthNames[month].charAt(0).toUpperCase() + monthNames[month].slice(1)} ${year}`;
monthTitle.textContent = title;
}
function pad(n) { return String(n).padStart(2, '0'); }
function loadScheduledTopics() {
try { return JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}'); } catch (e) { return {}; }
}
function saveScheduledTopics(obj) { localStorage.setItem(STORAGE_KEY, JSON.stringify(obj)); }
function generateTopics() {
const blocks = [9,5,9,10];
const topics = [];
blocks.forEach((count, idx) => {
for (let i = 1; i <= count; i++) topics.push(`Bloque ${idx+1} — Tema ${i}`);
});
return topics;
}
function getNextMonday(fromDate) {
const d = new Date(fromDate);
const day = d.getDay(); // 0 Sun, 1 Mon
let diff = (1 + 7 - day) % 7;
if (diff === 0) diff = 7;
d.setDate(d.getDate() + diff);
return d;
}
function scheduleOnePerWeek(topics) {
const scheduled = loadScheduledTopics();
let date = getNextMonday(new Date());
for (let i = 0; i < topics.length; i++) {
const ds = date.toISOString().slice(0,10);
scheduled[ds] = topics[i];
date.setDate(date.getDate() + 7);
}
saveScheduledTopics(scheduled);
}
autoScheduleBtn?.addEventListener('click', () => {
if (!confirm('Programar 1 tema por semana empezando el próximo lunes?')) return;
const topics = generateTopics();
scheduleOnePerWeek(topics);
renderCalendar(currentYear, currentMonth);
alert('Temas programados. Navega meses para verlos.');
});
function goToPreviousMonth() {
currentMonth -= 1;
if (currentMonth < 0) {
currentMonth = 11;
currentYear -= 1;
}
renderCalendar(currentYear, currentMonth);
}
function goToNextMonth() {
currentMonth += 1;
if (currentMonth > 11) {
currentMonth = 0;
currentYear += 1;
}
renderCalendar(currentYear, currentMonth);
}
prevMonthBtn.addEventListener('click', goToPreviousMonth);
nextMonthBtn.addEventListener('click', goToNextMonth);
// If there is no scheduling stored yet, auto-schedule topics once
if (Object.keys(loadScheduledTopics()).length === 0) {
scheduleOnePerWeek(generateTopics());
}
renderCalendar(currentYear, currentMonth);
});

45
planning.html Normal file
View File

@ -0,0 +1,45 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Planning TAI — Agenda</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="css/planning.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
</head>
<body>
<div class="planning-container">
<h1><i class="fas fa-calendar-alt"></i> Mi Planning 2026</h1>
<!-- Header con navegación -->
<div class="planning-header">
<div class="month-nav">
<button class="nav-btn" id="prevMonth" title="Mes anterior"><i class="fas fa-chevron-left"></i></button>
<div class="month-title" id="monthTitle"></div>
<button class="nav-btn" id="nextMonth" title="Próximo mes"><i class="fas fa-chevron-right"></i></button>
</div>
<button class="reset-btn" id="resetBtn" title="Limpiar todo"><i class="fas fa-trash"></i> Limpiar todo</button>
<button class="btn btn-outline" id="autoScheduleBtn" title="Programar 1 tema por semana">Programar 1 tema/semana</button>
</div>
<!-- Formulario para agregar tareas -->
<form class="add-task-form" id="addTaskForm">
<input
type="text"
id="taskInput"
placeholder="Escribe una tarea..."
maxlength="80"
autocomplete="off"
>
<button type="submit"><i class="fas fa-plus"></i> Agregar</button>
</form>
<!-- Calendario -->
<div class="calendar-grid" id="calendarGrid"></div>
</div>
<script src="js/planning.js"></script>
</body>
</html>