Skip to content

Commit 60ba718

Browse files
committed
feat: add pagination to index.html with max 12 cards per tab
1 parent be3750c commit 60ba718

2 files changed

Lines changed: 205 additions & 3 deletions

File tree

generate_index.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ def generate_index(self) -> None:
191191
.file-link {{ text-decoration: none; color: #2c3e50; font-weight: 500; display: block; }}
192192
.file-path {{ font-size: 0.8em; color: #7f8c8d; margin-top: 5px; display: block; word-break: break-all; }}
193193
footer {{ margin-top: 50px; text-align: center; font-size: 0.9em; color: #777; border-top: 1px solid #ddd; padding-top: 20px; }}
194+
.pagination {{ display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 30px; padding-bottom: 20px; }}
195+
.page-button {{ padding: 8px 12px; border: 1px solid #ddd; background: white; cursor: pointer; border-radius: 5px; color: #007bff; font-weight: 500; transition: all 0.2s; }}
196+
.page-button.active {{ background: #007bff; color: white; border-color: #007bff; }}
197+
.page-button:hover:not(.active):not(:disabled) {{ background: #f0f8ff; }}
198+
.page-button:disabled {{ opacity: 0.5; cursor: not-allowed; color: #999; border-color: #eee; }}
199+
.hidden-item {{ display: none !important; }}
194200
</style>
195201
</head>
196202
<body>
@@ -214,6 +220,99 @@ def generate_index(self) -> None:
214220
</footer>
215221
216222
<script>
223+
const ITEMS_PER_PAGE = 12;
224+
let currentPages = {{}};
225+
226+
function initPagination() {{
227+
const tabs = document.querySelectorAll('.tab-content');
228+
tabs.forEach(tab => {{
229+
currentPages[tab.id] = 1;
230+
renderPage(tab.id);
231+
}});
232+
}}
233+
234+
function renderPage(tabId) {{
235+
const tab = document.getElementById(tabId);
236+
const items = tab.querySelectorAll('.file-item');
237+
const totalItems = items.length;
238+
const totalPages = Math.ceil(totalItems / ITEMS_PER_PAGE);
239+
const currentPage = currentPages[tabId];
240+
241+
items.forEach((item, index) => {{
242+
const start = (currentPage - 1) * ITEMS_PER_PAGE;
243+
const end = start + ITEMS_PER_PAGE;
244+
if (index >= start && index < end) {{
245+
item.classList.remove('hidden-item');
246+
}} else {{
247+
item.classList.add('hidden-item');
248+
}}
249+
}});
250+
251+
renderPaginationControls(tabId, totalPages, currentPage);
252+
}}
253+
254+
function renderPaginationControls(tabId, totalPages, currentPage) {{
255+
const tab = document.getElementById(tabId);
256+
let paginationContainer = tab.querySelector('.pagination');
257+
258+
if (!paginationContainer) {{
259+
paginationContainer = document.createElement('div');
260+
paginationContainer.className = 'pagination';
261+
tab.appendChild(paginationContainer);
262+
}}
263+
264+
paginationContainer.innerHTML = '';
265+
266+
if (totalPages <= 1) return;
267+
268+
const prevBtn = document.createElement('button');
269+
prevBtn.className = 'page-button';
270+
prevBtn.innerHTML = '&laquo; Prev';
271+
prevBtn.disabled = currentPage === 1;
272+
prevBtn.onclick = () => {{
273+
currentPages[tabId]--;
274+
renderPage(tabId);
275+
window.scrollTo({{ top: 0, behavior: 'smooth' }});
276+
}};
277+
paginationContainer.appendChild(prevBtn);
278+
279+
for (let i = 1; i <= totalPages; i++) {{
280+
// Optional: Ellipsis logic for many pages
281+
if (totalPages > 7) {{
282+
if (i !== 1 && i !== totalPages && Math.abs(i - currentPage) > 1) {{
283+
if (i === 2 || i === totalPages - 1) {{
284+
const ellipsis = document.createElement('span');
285+
ellipsis.textContent = '...';
286+
paginationContainer.appendChild(ellipsis);
287+
}}
288+
continue;
289+
}}
290+
}}
291+
292+
const pageBtn = document.createElement('button');
293+
pageBtn.className = 'page-button';
294+
pageBtn.textContent = i;
295+
if (i === currentPage) pageBtn.classList.add('active');
296+
pageBtn.onclick = () => {{
297+
currentPages[tabId] = i;
298+
renderPage(tabId);
299+
window.scrollTo({{ top: 0, behavior: 'smooth' }});
300+
}};
301+
paginationContainer.appendChild(pageBtn);
302+
}}
303+
304+
const nextBtn = document.createElement('button');
305+
nextBtn.className = 'page-button';
306+
nextBtn.innerHTML = 'Next &raquo;';
307+
nextBtn.disabled = currentPage === totalPages;
308+
nextBtn.onclick = () => {{
309+
currentPages[tabId]++;
310+
renderPage(tabId);
311+
window.scrollTo({{ top: 0, behavior: 'smooth' }});
312+
}};
313+
paginationContainer.appendChild(nextBtn);
314+
}}
315+
217316
function openTab(evt, categoryName) {{
218317
var i, tabcontent, tablinks;
219318
tabcontent = document.getElementsByClassName("tab-content");
@@ -229,6 +328,8 @@ def generate_index(self) -> None:
229328
document.getElementById(categoryName).classList.add("active");
230329
evt.currentTarget.className += " active";
231330
}}
331+
332+
window.addEventListener('DOMContentLoaded', initPagination);
232333
</script>
233334
</body>
234335
</html>"""

public/index.html

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@
2020
.file-link { text-decoration: none; color: #2c3e50; font-weight: 500; display: block; }
2121
.file-path { font-size: 0.8em; color: #7f8c8d; margin-top: 5px; display: block; word-break: break-all; }
2222
footer { margin-top: 50px; text-align: center; font-size: 0.9em; color: #777; border-top: 1px solid #ddd; padding-top: 20px; }
23+
.pagination { display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 30px; padding-bottom: 20px; }
24+
.page-button { padding: 8px 12px; border: 1px solid #ddd; background: white; cursor: pointer; border-radius: 5px; color: #007bff; font-weight: 500; transition: all 0.2s; }
25+
.page-button.active { background: #007bff; color: white; border-color: #007bff; }
26+
.page-button:hover:not(.active):not(:disabled) { background: #f0f8ff; }
27+
.page-button:disabled { opacity: 0.5; cursor: not-allowed; color: #999; border-color: #eee; }
28+
.hidden-item { display: none !important; }
2329
</style>
2430
</head>
2531
<body>
@@ -181,8 +187,8 @@ <h1>Algorithm Study Index</h1>
181187
<li class="file-item"><a class="file-link" href="Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html">Moving Tiles - 重なり面積の時間逆算<span class="file-path">Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html</span></a></li>
182188
<li class="file-item"><a class="file-link" href="Mathematics/Combination%20Calculation/leetcode/62.%20Unique%20Paths/Claude/README.html">Robot Unique Paths - 技術解説<span class="file-path">Mathematics/Combination Calculation/leetcode/62. Unique Paths/Claude/README.html</span></a></li>
183189
<li class="file-item"><a class="file-link" href="Mathematics/Finite%20State%20Machine/leetcode/65.%20Valid%20Number/Claude/README.html">Valid Number Problem - 有限状態機械アルゴリズム解説<span class="file-path">Mathematics/Finite State Machine/leetcode/65. Valid Number/Claude/README.html</span></a></li>
184-
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README%20detailed.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README detailed.html</span></a></li>
185190
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README.html</span></a></li>
191+
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README%20detailed.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README detailed.html</span></a></li>
186192
<li class="file-item"><a class="file-link" href="Mathematics/Number%20Theory/HackerRank/Easy/Primitive_Problem.html">原始根の発見 - HackerRank問題解説<span class="file-path">Mathematics/Number Theory/HackerRank/Easy/Primitive_Problem.html</span></a></li>
187193
<li class="file-item"><a class="file-link" href="Mathematics/Other/atcoder/B45/README.html">整数を全て0にする問題 - 可視化デモ<span class="file-path">Mathematics/Other/atcoder/B45/README.html</span></a></li>
188194
<li class="file-item"><a class="file-link" href="Mathematics/Multiply%20Strings/leetcode/43.%20Multiply%20Strings/Claude/README.html">文字列掛け算アルゴリズムの詳細解析<span class="file-path">Mathematics/Multiply Strings/leetcode/43. Multiply Strings/Claude/README.html</span></a></li>
@@ -354,8 +360,8 @@ <h1>Algorithm Study Index</h1>
354360
<li class="file-item"><a class="file-link" href="Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html">Moving Tiles - 重なり面積の時間逆算<span class="file-path">Mathematics/Fundamentals/HackerRank/Claude/Easy/moving-tiles-visualization.html</span></a></li>
355361
<li class="file-item"><a class="file-link" href="Mathematics/Combination%20Calculation/leetcode/62.%20Unique%20Paths/Claude/README.html">Robot Unique Paths - 技術解説<span class="file-path">Mathematics/Combination Calculation/leetcode/62. Unique Paths/Claude/README.html</span></a></li>
356362
<li class="file-item"><a class="file-link" href="Mathematics/Finite%20State%20Machine/leetcode/65.%20Valid%20Number/Claude/README.html">Valid Number Problem - 有限状態機械アルゴリズム解説<span class="file-path">Mathematics/Finite State Machine/leetcode/65. Valid Number/Claude/README.html</span></a></li>
357-
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README%20detailed.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README detailed.html</span></a></li>
358363
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README.html</span></a></li>
364+
<li class="file-item"><a class="file-link" href="Mathematics/Exponentiation%20by%20Squaring/leetcode/50.%20Pow%28x%2C%20n%29/Claude/README%20detailed.html">pow(x, n) アルゴリズム解析<span class="file-path">Mathematics/Exponentiation by Squaring/leetcode/50. Pow(x, n)/Claude/README detailed.html</span></a></li>
359365
<li class="file-item"><a class="file-link" href="Mathematics/Number%20Theory/HackerRank/Easy/Primitive_Problem.html">原始根の発見 - HackerRank問題解説<span class="file-path">Mathematics/Number Theory/HackerRank/Easy/Primitive_Problem.html</span></a></li>
360366
<li class="file-item"><a class="file-link" href="Mathematics/Other/atcoder/B45/README.html">整数を全て0にする問題 - 可視化デモ<span class="file-path">Mathematics/Other/atcoder/B45/README.html</span></a></li>
361367
<li class="file-item"><a class="file-link" href="Mathematics/Multiply%20Strings/leetcode/43.%20Multiply%20Strings/Claude/README.html">文字列掛け算アルゴリズムの詳細解析<span class="file-path">Mathematics/Multiply Strings/leetcode/43. Multiply Strings/Claude/README.html</span></a></li>
@@ -371,10 +377,103 @@ <h1>Algorithm Study Index</h1>
371377

372378

373379
<footer>
374-
Generated on 2026-02-20 02:18:49 UTC
380+
Generated on 2026-02-20 02:46:07 UTC
375381
</footer>
376382

377383
<script>
384+
const ITEMS_PER_PAGE = 12;
385+
let currentPages = {};
386+
387+
function initPagination() {
388+
const tabs = document.querySelectorAll('.tab-content');
389+
tabs.forEach(tab => {
390+
currentPages[tab.id] = 1;
391+
renderPage(tab.id);
392+
});
393+
}
394+
395+
function renderPage(tabId) {
396+
const tab = document.getElementById(tabId);
397+
const items = tab.querySelectorAll('.file-item');
398+
const totalItems = items.length;
399+
const totalPages = Math.ceil(totalItems / ITEMS_PER_PAGE);
400+
const currentPage = currentPages[tabId];
401+
402+
items.forEach((item, index) => {
403+
const start = (currentPage - 1) * ITEMS_PER_PAGE;
404+
const end = start + ITEMS_PER_PAGE;
405+
if (index >= start && index < end) {
406+
item.classList.remove('hidden-item');
407+
} else {
408+
item.classList.add('hidden-item');
409+
}
410+
});
411+
412+
renderPaginationControls(tabId, totalPages, currentPage);
413+
}
414+
415+
function renderPaginationControls(tabId, totalPages, currentPage) {
416+
const tab = document.getElementById(tabId);
417+
let paginationContainer = tab.querySelector('.pagination');
418+
419+
if (!paginationContainer) {
420+
paginationContainer = document.createElement('div');
421+
paginationContainer.className = 'pagination';
422+
tab.appendChild(paginationContainer);
423+
}
424+
425+
paginationContainer.innerHTML = '';
426+
427+
if (totalPages <= 1) return;
428+
429+
const prevBtn = document.createElement('button');
430+
prevBtn.className = 'page-button';
431+
prevBtn.innerHTML = '&laquo; Prev';
432+
prevBtn.disabled = currentPage === 1;
433+
prevBtn.onclick = () => {
434+
currentPages[tabId]--;
435+
renderPage(tabId);
436+
window.scrollTo({ top: 0, behavior: 'smooth' });
437+
};
438+
paginationContainer.appendChild(prevBtn);
439+
440+
for (let i = 1; i <= totalPages; i++) {
441+
// Optional: Ellipsis logic for many pages
442+
if (totalPages > 7) {
443+
if (i !== 1 && i !== totalPages && Math.abs(i - currentPage) > 1) {
444+
if (i === 2 || i === totalPages - 1) {
445+
const ellipsis = document.createElement('span');
446+
ellipsis.textContent = '...';
447+
paginationContainer.appendChild(ellipsis);
448+
}
449+
continue;
450+
}
451+
}
452+
453+
const pageBtn = document.createElement('button');
454+
pageBtn.className = 'page-button';
455+
pageBtn.textContent = i;
456+
if (i === currentPage) pageBtn.classList.add('active');
457+
pageBtn.onclick = () => {
458+
currentPages[tabId] = i;
459+
renderPage(tabId);
460+
window.scrollTo({ top: 0, behavior: 'smooth' });
461+
};
462+
paginationContainer.appendChild(pageBtn);
463+
}
464+
465+
const nextBtn = document.createElement('button');
466+
nextBtn.className = 'page-button';
467+
nextBtn.innerHTML = 'Next &raquo;';
468+
nextBtn.disabled = currentPage === totalPages;
469+
nextBtn.onclick = () => {
470+
currentPages[tabId]++;
471+
renderPage(tabId);
472+
window.scrollTo({ top: 0, behavior: 'smooth' });
473+
};
474+
paginationContainer.appendChild(nextBtn);
475+
}
476+
378477
function openTab(evt, categoryName) {
379478
var i, tabcontent, tablinks;
380479
tabcontent = document.getElementsByClassName("tab-content");
@@ -390,6 +489,8 @@ <h1>Algorithm Study Index</h1>
390489
document.getElementById(categoryName).classList.add("active");
391490
evt.currentTarget.className += " active";
392491
}
492+
493+
window.addEventListener('DOMContentLoaded', initPagination);
393494
</script>
394495
</body>
395496
</html>

0 commit comments

Comments
 (0)