|
6 | 6 | <style> |
7 | 7 | body { |
8 | 8 | font-family: sans-serif; |
9 | | - display: flex; |
10 | | - height: 100vh; |
11 | 9 | margin: 0; |
12 | | - } |
13 | | - #sidebar { |
14 | | - width: 300px; |
15 | | - background: #f4f4f4; |
16 | 10 | padding: 1rem; |
17 | | - overflow-y: auto; |
18 | | - border-right: 1px solid #ddd; |
| 11 | + background: #f7f7f7; |
| 12 | + } |
| 13 | + h1, h2 { |
| 14 | + text-align: center; |
| 15 | + } |
| 16 | + #container { |
| 17 | + display: flex; |
| 18 | + flex-wrap: wrap; |
| 19 | + justify-content: center; |
| 20 | + gap: 1rem; |
19 | 21 | } |
20 | | - #content { |
21 | | - flex: 1; |
| 22 | + .card { |
| 23 | + background: white; |
| 24 | + border-radius: 10px; |
| 25 | + box-shadow: 0 2px 6px rgba(0,0,0,0.1); |
22 | 26 | padding: 1rem; |
23 | | - overflow: auto; |
| 27 | + width: 200px; |
| 28 | + text-align: center; |
| 29 | + cursor: pointer; |
| 30 | + transition: transform 0.2s; |
24 | 31 | } |
25 | | - ul { |
26 | | - list-style-type: none; |
27 | | - padding-left: 1rem; |
| 32 | + .card:hover { |
| 33 | + transform: scale(1.05); |
28 | 34 | } |
29 | | - li { |
| 35 | + #backBtn { |
| 36 | + display: none; |
| 37 | + margin-bottom: 1rem; |
30 | 38 | cursor: pointer; |
31 | | - margin: 0.2rem 0; |
| 39 | + background: #ddd; |
| 40 | + border: none; |
| 41 | + padding: 0.5rem 1rem; |
| 42 | + border-radius: 5px; |
32 | 43 | } |
33 | 44 | pre { |
34 | 45 | background: #1e1e1e; |
35 | 46 | color: #dcdcdc; |
36 | 47 | padding: 1rem; |
37 | 48 | border-radius: 8px; |
38 | 49 | overflow-x: auto; |
| 50 | + white-space: pre-wrap; |
39 | 51 | } |
40 | 52 | </style> |
41 | 53 | <!-- Highlight.js --> |
|
44 | 56 | <script>hljs.highlightAll();</script> |
45 | 57 | </head> |
46 | 58 | <body> |
47 | | - <div id="sidebar"><strong>📁 תפריט קבצים</strong><div id="tree"></div></div> |
48 | | - <div id="content"><em>בחר קובץ מהתפריט כדי לצפות בקוד.</em></div> |
| 59 | + <h1>LeetCode Solutions</h1> |
| 60 | + <h2 id="pathTitle">Click to view solutions</h2> |
| 61 | + <button id="backBtn">⬅ Back</button> |
| 62 | + <div id="container"></div> |
| 63 | + <div id="codeViewer"></div> |
49 | 64 |
|
50 | 65 | <script> |
51 | 66 | const owner = "efrat-dev"; |
52 | 67 | const repo = "algo-ds-leetcode"; |
53 | 68 | const branch = "main"; |
54 | 69 | const baseUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/`; |
55 | 70 |
|
| 71 | + let fullTree = {}; |
| 72 | + let history = []; |
| 73 | + |
56 | 74 | fetch(`https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`) |
57 | 75 | .then(res => res.json()) |
58 | 76 | .then(data => { |
59 | 77 | const files = data.tree.filter(item => item.type === "blob" && item.path.endsWith(".cs")); |
60 | | - const treeData = buildTree(files.map(f => f.path)); |
61 | | - renderTree(treeData, document.getElementById("tree")); |
| 78 | + fullTree = buildTree(files.map(f => f.path)); |
| 79 | + renderLevel(fullTree, "Click to view solutions"); |
62 | 80 | }); |
63 | 81 |
|
64 | 82 | function buildTree(paths) { |
|
68 | 86 | let curr = root; |
69 | 87 | for (let i = 0; i < parts.length; i++) { |
70 | 88 | const part = parts[i]; |
71 | | - if (!curr[part]) curr[part] = (i === parts.length - 1) ? path : {}; |
| 89 | + if (!curr[part]) { |
| 90 | + curr[part] = (i === parts.length - 1) ? path : {}; |
| 91 | + } |
72 | 92 | curr = curr[part]; |
73 | 93 | } |
74 | 94 | } |
75 | 95 | return root; |
76 | 96 | } |
77 | 97 |
|
78 | | - function renderTree(tree, container) { |
79 | | - const ul = document.createElement("ul"); |
80 | | - for (const key in tree) { |
81 | | - const li = document.createElement("li"); |
82 | | - if (typeof tree[key] === "string") { |
83 | | - li.textContent = key; |
84 | | - li.onclick = () => loadFile(tree[key]); |
85 | | - } else { |
86 | | - li.innerHTML = `📁 ${key}`; |
87 | | - renderTree(tree[key], li); |
88 | | - } |
89 | | - ul.appendChild(li); |
| 98 | + function renderLevel(level, title) { |
| 99 | + const container = document.getElementById("container"); |
| 100 | + container.innerHTML = ""; |
| 101 | + document.getElementById("codeViewer").innerHTML = ""; |
| 102 | + document.getElementById("pathTitle").innerText = title; |
| 103 | + document.getElementById("backBtn").style.display = history.length ? "inline-block" : "none"; |
| 104 | + |
| 105 | + for (const key in level) { |
| 106 | + const card = document.createElement("div"); |
| 107 | + card.className = "card"; |
| 108 | + card.innerText = key.replace(/\.cs$/, ""); |
| 109 | + card.onclick = () => { |
| 110 | + if (typeof level[key] === "string") { |
| 111 | + loadFile(level[key]); |
| 112 | + } else { |
| 113 | + history.push({ level, title }); |
| 114 | + renderLevel(level[key], key); |
| 115 | + } |
| 116 | + }; |
| 117 | + container.appendChild(card); |
90 | 118 | } |
91 | | - container.appendChild(ul); |
92 | 119 | } |
93 | 120 |
|
94 | 121 | function loadFile(path) { |
95 | 122 | const url = baseUrl + path; |
96 | 123 | fetch(url) |
97 | 124 | .then(res => res.text()) |
98 | 125 | .then(code => { |
99 | | - document.getElementById("content").innerHTML = ` |
100 | | - <h3>${path}</h3> |
| 126 | + document.getElementById("container").innerHTML = ""; |
| 127 | + document.getElementById("pathTitle").innerText = path; |
| 128 | + document.getElementById("codeViewer").innerHTML = ` |
101 | 129 | <pre><code class="language-csharp">${escapeHtml(code)}</code></pre> |
102 | 130 | `; |
103 | 131 | hljs.highlightAll(); |
| 132 | + document.getElementById("backBtn").style.display = "inline-block"; |
104 | 133 | }); |
105 | 134 | } |
106 | 135 |
|
| 136 | + document.getElementById("backBtn").onclick = () => { |
| 137 | + const prev = history.pop(); |
| 138 | + renderLevel(prev.level, prev.title); |
| 139 | + }; |
| 140 | + |
107 | 141 | function escapeHtml(text) { |
108 | 142 | return text.replace(/[&<>"']/g, m => ({ |
109 | 143 | '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' |
|
0 commit comments