Planificacion y flashcard
This commit is contained in:
parent
29f818bf56
commit
2d9f9dd292
|
|
@ -77,7 +77,7 @@ public class SecurityConfig {
|
|||
// Panel de administración
|
||||
.requestMatchers("/admin/**").hasRole("ADMIN")
|
||||
// Contenido de pago
|
||||
.requestMatchers("/curso", "/curso/**", "/planning", "/flashcards.html", "/flashcards/**", "/api/**").hasAnyRole("PAGADO", "ADMIN")
|
||||
.requestMatchers("/curso", "/curso/**", "/planning", "/esquema.html", "/flashcards.html", "/flashcards/**", "/api/**").hasAnyRole("PAGADO", "ADMIN")
|
||||
// Cualquier otra ruta requiere autenticación
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: Arial, Helvetica, sans-serif; font-size: 11pt; color: #e8eaed; background: #1a1d23; min-height: 100vh; }
|
||||
header {
|
||||
background: #0d1117; color: #e8eaed;
|
||||
padding: 14px 24px; display: flex; align-items: center; gap: 16px;
|
||||
border-bottom: 1px solid #30363d;
|
||||
}
|
||||
header a { color: #58a6ff; font-size: 9.5pt; text-decoration: none; white-space: nowrap; }
|
||||
header a:hover { color: #e8eaed; text-decoration: underline; }
|
||||
header h1 { font-size: 13pt; font-weight: bold; line-height: 1.3; flex: 1; }
|
||||
header .bloque-badge {
|
||||
background: #1f6feb; color: #fff; font-size: 9pt;
|
||||
padding: 3px 10px; border-radius: 12px; white-space: nowrap;
|
||||
}
|
||||
main { max-width: 680px; margin: 28px auto; padding: 0 16px; }
|
||||
.nav-temas { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
|
||||
.nav-temas a {
|
||||
font-size: 9pt; padding: 4px 10px; border-radius: 14px;
|
||||
background: #21262d; color: #58a6ff; text-decoration: none; border: 1px solid #30363d;
|
||||
}
|
||||
.nav-temas a:hover, .nav-temas a.activo { background: #1f6feb; color: #fff; border-color: #1f6feb; }
|
||||
.card {
|
||||
background: #161b22; border-radius: 8px; box-shadow: 0 2px 12px rgba(0,0,0,.4);
|
||||
overflow: hidden; border: 1px solid #30363d;
|
||||
}
|
||||
.card-header {
|
||||
background: #0d1117; padding: 16px 20px; border-bottom: 1px solid #30363d;
|
||||
}
|
||||
.card-header h2 { font-size: 12pt; color: #58a6ff; margin-bottom: 4px; line-height: 1.4; }
|
||||
.card-header p { font-size: 9pt; color: #8b949e; }
|
||||
ul.epigrafes { list-style: none; padding: 0; }
|
||||
ul.epigrafes li { border-bottom: 1px solid #21262d; }
|
||||
ul.epigrafes li:last-child { border-bottom: none; }
|
||||
ul.epigrafes li a {
|
||||
display: block; padding: 10px 20px;
|
||||
font-size: 10pt; color: #c9d1d9; text-decoration: none; line-height: 1.35;
|
||||
}
|
||||
ul.epigrafes li a:hover { background: #21262d; color: #f85149; padding-left: 28px; transition: padding .12s; }
|
||||
.footer-btns { margin-top: 20px; display: flex; gap: 10px; flex-wrap: wrap; }
|
||||
.btn {
|
||||
display: inline-block; padding: 9px 18px; border-radius: 6px;
|
||||
font-size: 10pt; text-decoration: none; cursor: pointer; border: none; font-family: inherit;
|
||||
}
|
||||
.btn-primary { background: #1f6feb; color: #fff; }
|
||||
.btn-primary:hover { background: #388bfd; }
|
||||
.btn-secondary { background: #21262d; color: #58a6ff; border: 1px solid #30363d; }
|
||||
.btn-secondary:hover { background: #30363d; }
|
||||
#no-tema { text-align: center; padding: 60px 20px; color: #8b949e; }
|
||||
|
||||
/* Secciones principales desplegables */
|
||||
ul.epigrafes li.seccion-principal { border-bottom: 1px solid #30363d; }
|
||||
ul.epigrafes li.seccion-principal details summary {
|
||||
display: block; padding: 10px 20px;
|
||||
font-size: 10pt; font-weight: bold; color: #58a6ff;
|
||||
cursor: pointer; line-height: 1.35;
|
||||
background: #0d1117; user-select: none;
|
||||
}
|
||||
ul.epigrafes li.seccion-principal details summary::-webkit-details-marker { display: none; }
|
||||
ul.epigrafes li.seccion-principal details summary::before {
|
||||
content: '▶\00a0'; font-size: 8pt; color: #388bfd;
|
||||
}
|
||||
ul.epigrafes li.seccion-principal details[open] summary::before { content: '▼\00a0'; }
|
||||
ul.epigrafes li.seccion-principal details summary:hover { background: #21262d; color: #f85149; }
|
||||
ul.epigrafes li.seccion-principal details ul { list-style: none; padding: 0; }
|
||||
ul.epigrafes li.seccion-principal details ul li { border-bottom: 1px solid #21262d; }
|
||||
ul.epigrafes li.seccion-principal details ul li:last-child { border-bottom: none; }
|
||||
ul.epigrafes li.seccion-principal details ul li a {
|
||||
display: block; padding: 8px 20px 8px 36px;
|
||||
font-size: 9.5pt; color: #8b949e; text-decoration: none; line-height: 1.35;
|
||||
}
|
||||
ul.epigrafes li.seccion-principal details ul li a:hover { background: #21262d; color: #f85149; }
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Esquema de tema · TAI</title>
|
||||
<link rel="stylesheet" href="css/esquema.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<a href="/planning">← Planning</a>
|
||||
<h1 id="header-titulo">Esquema del tema</h1>
|
||||
<span class="bloque-badge" id="header-badge"></span>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<div class="nav-temas" id="nav-temas"></div>
|
||||
|
||||
<div class="card" id="card" style="display:none">
|
||||
<div class="card-header">
|
||||
<h2 id="card-titulo"></h2>
|
||||
<p id="card-subtitulo"></p>
|
||||
</div>
|
||||
<ul class="epigrafes" id="card-lista"></ul>
|
||||
</div>
|
||||
|
||||
<div id="no-tema">Selecciona un tema en el planning o en la navegación superior.</div>
|
||||
|
||||
<div class="footer-btns" id="footer-btns" style="display:none">
|
||||
<a class="btn btn-primary" id="btn-md" href="#">📄 Abrir apunte completo</a>
|
||||
<a class="btn btn-secondary" href="/planning">← Volver al planning</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script src="js/temas-data.js"></script>
|
||||
<script src="js/esquema.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
function render(key) {
|
||||
const t = TEMAS[key];
|
||||
const card = document.getElementById('card');
|
||||
const noTema = document.getElementById('no-tema');
|
||||
const footerBtns = document.getElementById('footer-btns');
|
||||
if (!t) { card.style.display='none'; noTema.style.display=''; footerBtns.style.display='none'; return; }
|
||||
document.title = key + '. ' + t.titulo.slice(0,60) + ' · TAI';
|
||||
document.getElementById('header-titulo').textContent = t.titulo;
|
||||
document.getElementById('header-badge').textContent = 'Bloque ' + t.bloque + ' · Tema ' + t.tema;
|
||||
document.getElementById('card-titulo').textContent = key + '. ' + t.titulo;
|
||||
document.getElementById('card-subtitulo').textContent = t.epigrafes.length + ' epígrafes';
|
||||
const ul = document.getElementById('card-lista');
|
||||
ul.innerHTML = '';
|
||||
|
||||
const fileParts = t.file.split('/');
|
||||
const relPath = fileParts.slice(-2).join('/'); // 'bloqueN/temaN.md'
|
||||
const verUrl = 'ver.html?f=' + relPath + '&tema=' + key;
|
||||
|
||||
let currentSubList = null;
|
||||
|
||||
t.epigrafes.forEach(function(h) {
|
||||
const isMainSection = /^\d+\.\s/.test(h);
|
||||
|
||||
if (isMainSection) {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'seccion-principal';
|
||||
const details = document.createElement('details');
|
||||
const summary = document.createElement('summary');
|
||||
summary.textContent = h;
|
||||
details.appendChild(summary);
|
||||
currentSubList = document.createElement('ul');
|
||||
details.appendChild(currentSubList);
|
||||
li.appendChild(details);
|
||||
ul.appendChild(li);
|
||||
} else if (currentSubList) {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.href = verUrl;
|
||||
a.target = '_blank';
|
||||
a.textContent = h;
|
||||
li.appendChild(a);
|
||||
currentSubList.appendChild(li);
|
||||
} else {
|
||||
const li = document.createElement('li');
|
||||
const a = document.createElement('a');
|
||||
a.href = verUrl;
|
||||
a.target = '_blank';
|
||||
a.textContent = h;
|
||||
li.appendChild(a);
|
||||
ul.appendChild(li);
|
||||
}
|
||||
});
|
||||
document.getElementById('btn-md').href = verUrl;
|
||||
card.style.display = '';
|
||||
noTema.style.display = 'none';
|
||||
footerBtns.style.display = '';
|
||||
document.querySelectorAll('.nav-temas a').forEach(function(a) {
|
||||
a.classList.toggle('activo', a.dataset.key === key);
|
||||
});
|
||||
}
|
||||
|
||||
function buildNav() {
|
||||
const nav = document.getElementById('nav-temas');
|
||||
[1,2,3,4].forEach(function(b) {
|
||||
Object.keys(TEMAS).filter(k => TEMAS[k].bloque === b).sort().forEach(function(key) {
|
||||
const a = document.createElement('a');
|
||||
a.href = '?tema=' + key;
|
||||
a.textContent = key;
|
||||
a.dataset.key = key;
|
||||
nav.appendChild(a);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
buildNav();
|
||||
const temaParam = new URLSearchParams(window.location.search).get('tema');
|
||||
if (temaParam) render(temaParam);
|
||||
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue