Notebook1 / index.html
Sinketji's picture
Update index.html
6d9b88d verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Premium AI Notebook</title>
<style>
/* Base Styling - Sharp & Clean (VS Code Style) */
*, *::before, *::after { box-sizing: border-box; }
body, html { margin: 0; padding: 0; height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background-color: #1e1e1e; color: #d4d4d4; overflow: hidden; display: flex; flex-direction: column; }
/* Header */
.header { background-color: #252526; padding: 12px 20px; border-bottom: 1px solid #3c3c3c; display: flex; justify-content: space-between; align-items: center; z-index: 10; }
.header h2 { margin: 0; font-size: 16px; color: #cccccc; font-weight: 600; letter-spacing: 0.5px; }
.header-buttons button { background-color: #0e639c; color: white; border: none; padding: 6px 12px; cursor: pointer; border-radius: 2px; font-size: 13px; margin-left: 8px; }
.header-buttons button:hover { background-color: #1177bb; }
/* Main Container */
.main-container { display: flex; flex-direction: column; flex: 1; height: calc(100% - 45px); }
/* Notebook Section */
.notebook-panel { flex: 1; overflow-y: auto; padding: 20px; background-color: #1e1e1e; }
.cell { background: #1e1e1e; border: 1px solid #3c3c3c; border-radius: 2px; margin-bottom: 20px; display: flex; flex-direction: column; }
.cell-toolbar { background: #252526; padding: 6px 10px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #3c3c3c; }
.cell-title { font-size: 12px; color: #858585; font-family: monospace; }
.cell-actions button { background: transparent; color: #cccccc; border: 1px solid #3c3c3c; padding: 4px 8px; cursor: pointer; border-radius: 2px; font-size: 11px; margin-left: 5px; }
.cell-actions button.run-btn { background: #007acc; color: white; border-color: #007acc; }
.cell-actions button.run-btn:hover { background: #005f9e; }
.cell-actions button:hover:not(.run-btn) { background: #333333; }
.code-input { width: 100%; height: 120px; background: #1e1e1e; color: #9cdcfe; border: none; padding: 12px; font-family: 'Consolas', monospace; font-size: 14px; resize: vertical; outline: none; line-height: 1.5; }
/* Input Data Field for python input() */
.input-data-row { background: #2d2d2d; border-top: 1px solid #3c3c3c; padding: 6px 12px; display: flex; align-items: center; }
.input-data-row label { font-size: 11px; color: #858585; margin-right: 10px; font-family: monospace; }
.input-data-field { flex: 1; background: #1e1e1e; border: 1px solid #3c3c3c; color: #d4d4d4; padding: 4px 8px; font-size: 12px; font-family: monospace; outline: none; border-radius: 2px; }
.input-data-field:focus { border-color: #007acc; }
.code-output { background: #111111; color: #cecece; padding: 12px; font-family: 'Consolas', monospace; font-size: 13px; white-space: pre-wrap; border-top: 1px solid #3c3c3c; display: none; margin: 0; line-height: 1.5; }
/* Draggable Resizer */
.resizer { height: 5px; background-color: #252526; cursor: ns-resize; border-top: 1px solid #3c3c3c; border-bottom: 1px solid #3c3c3c; z-index: 10; transition: background 0.2s; }
.resizer:hover { background-color: #007acc; border-color: #007acc; }
/* Terminal Section */
.terminal-panel { height: 300px; background-color: #111111; display: flex; flex-direction: column; min-height: 100px; }
.terminal-header { background: #252526; color: #cccccc; padding: 6px 15px; font-size: 11px; font-family: sans-serif; border-bottom: 1px solid #3c3c3c; letter-spacing: 0.5px; }
.terminal-content { flex: 1; overflow-y: auto; padding: 10px; font-family: 'Consolas', monospace; font-size: 13px; color: #cccccc; }
.terminal-history { white-space: pre-wrap; margin-bottom: 5px; }
.terminal-input-wrapper { display: flex; align-items: center; }
.terminal-prompt { color: #4caf50; margin-right: 8px; }
.terminal-input { flex: 1; background: transparent; border: none; color: #ffffff; font-family: 'Consolas', monospace; font-size: 13px; outline: none; }
</style>
</head>
<body>
<div class="header">
<h2>Priyanshu's Notebook</h2>
<div class="header-buttons">
<button onclick="addCell()">+ Add Cell</button>
</div>
</div>
<div class="main-container">
<div class="notebook-panel" id="notebook"></div>
<div class="resizer" id="dragMe"></div>
<div class="terminal-panel" id="terminalPanel">
<div class="terminal-header">TERMINAL</div>
<div class="terminal-content" id="term-content" onclick="document.getElementById('term-in').focus()">
<div class="terminal-history" id="term-history">bash v1.0 connected...</div>
<div class="terminal-input-wrapper">
<span class="terminal-prompt">~/project$</span>
<input type="text" class="terminal-input" id="term-in" onkeydown="runTerminal(event)" autocomplete="off">
</div>
</div>
</div>
</div>
<script>
let cellCount = 0;
function addCell() {
cellCount++;
const id = cellCount;
const cellHtml = `
<div class="cell" id="cell-${id}">
<div class="cell-toolbar">
<span class="cell-title">Cell [${id}]</span>
<div class="cell-actions">
<button onclick="clearOutput(${id})">Clear</button>
<button onclick="deleteCell(${id})">Delete</button>
<button class="run-btn" onclick="runCode(${id})">▶ Run</button>
</div>
</div>
<textarea class="code-input" id="code-${id}" placeholder="print('Hello World')"></textarea>
<div class="input-data-row">
<label>Expected input():</label>
<input type="text" class="input-data-field" id="inputs-${id}" placeholder="Comma separated values (e.g. Priyanshu, 25)">
</div>
<pre class="code-output" id="output-${id}"></pre>
</div>
`;
document.getElementById("notebook").insertAdjacentHTML('beforeend', cellHtml);
}
function deleteCell(id) {
document.getElementById(`cell-${id}`).remove();
}
function clearOutput(id) {
const outputEl = document.getElementById(`output-${id}`);
outputEl.style.display = "none";
outputEl.innerText = "";
}
async function runCode(id) {
const code = document.getElementById(`code-${id}`).value;
const inputText = document.getElementById(`inputs-${id}`).value;
const outputEl = document.getElementById(`output-${id}`);
// Inputs ko array mein convert karna
const inputsArray = inputText ? inputText.split(',').map(item => item.trim()) : [];
outputEl.style.display = "block";
outputEl.innerText = "[*] Executing...";
try {
const res = await fetch("/run_code", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code: code, inputs: inputsArray })
});
const data = await res.json();
outputEl.innerText = data.output || "[Done] No output.";
} catch (err) {
outputEl.innerText = "Execution Failed: " + err;
}
}
async function runTerminal(e) {
if (e.key === "Enter") {
const cmd = e.target.value;
if (!cmd.trim()) return;
const historyEl = document.getElementById("term-history");
const contentEl = document.getElementById("term-content");
historyEl.innerText += `\n~/project$ ${cmd}`;
e.target.value = "Running...";
e.target.disabled = true;
try {
const res = await fetch("/run_terminal", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ cmd })
});
const data = await res.json();
if(data.output.trim() !== "") {
historyEl.innerText += `\n${data.output.trim()}`;
}
} catch (err) {
historyEl.innerText += `\nCommand error.`;
}
e.target.value = "";
e.target.disabled = false;
e.target.focus();
contentEl.scrollTop = contentEl.scrollHeight;
}
}
// Resizer Logic
const resizer = document.getElementById('dragMe');
const terminalPanel = document.getElementById('terminalPanel');
let isResizing = false;
resizer.addEventListener('mousedown', function(e) {
isResizing = true;
document.body.style.cursor = 'ns-resize';
});
document.addEventListener('mousemove', function(e) {
if (!isResizing) return;
const newHeight = window.innerHeight - e.clientY;
if (newHeight > 50 && newHeight < window.innerHeight - 100) {
terminalPanel.style.height = newHeight + 'px';
}
});
document.addEventListener('mouseup', function() {
isResizing = false;
document.body.style.cursor = 'default';
});
window.onload = addCell;
</script>
</body>
</html>