docs / index.html
ArunKr's picture
Update index.html
d0bd0a2 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>DocSite — Markdown Documentation</title>
<!-- Tailwind via CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Heroicons -->
<script src="https://unpkg.com/heroicons@2.0.18/dist/outline.js"></script>
<!-- Marked.js -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- Highlight.js -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/github.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
<style>
/* custom scrollbar */
.scrollbar-thin::-webkit-scrollbar { width: 6px; }
.scrollbar-thin::-webkit-scrollbar-thumb { background-color: rgba(100,100,100,0.4); border-radius: 3px; }
</style>
</head>
<body class="h-screen flex overflow-hidden font-sans">
<!-- Sidebar: File Tree -->
<aside id="sidebar" class="w-64 bg-gray-800 text-gray-200 p-4 flex flex-col transition-transform duration-300">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-semibold">Pages</h2>
<button id="newPageBtn" class="p-1 hover:bg-gray-700 rounded"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path d="M12 4v16m8-8H4"/></svg></button>
</div>
<ul id="fileTree" class="flex-1 overflow-auto scrollbar-thin space-y-1"></ul>
<button id="deletePageBtn" class="mt-4 px-3 py-2 bg-red-600 hover:bg-red-700 rounded-md">Delete Page</button>
</aside>
<!-- Main Content: Editor & Preview -->
<main class="flex-1 flex flex-col">
<!-- Top Controls -->
<div id="toolbar" class="flex items-center bg-gray-100 p-2 border-b transition-transform duration-300">
<button id="toggleSidebarBtn" class="p-1 mr-2 hover:bg-gray-200 rounded"><svg class="w-5 h-5 text-gray-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path d="M4 6h16M4 12h16M4 18h16"/></svg></button>
<button id="toggleEditorBtn" class="p-1 mr-2 hover:bg-gray-200 rounded"><svg class="w-5 h-5 text-gray-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path d="M8 4h8v16H8z"/></svg></button>
<input id="pageTitle" class="flex-1 px-2 py-1 border rounded focus:outline-none mr-2" placeholder="Page Title..." />
<button id="saveBtn" class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded">Save</button>
</div>
<!-- Editor & Preview Panes -->
<div class="flex flex-1 overflow-hidden">
<!-- Editor Pane -->
<div id="editorPane" class="relative w-1/2 transition-all duration-300">
<div id="editorToolbar" class="absolute top-2 left-2 flex space-x-1 z-10">
<button data-action="bold" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">B</button>
<button data-action="italic" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">I</button>
<button data-action="h1" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">H1</button>
<button data-action="ul" class="px-2 py-1 bg-gray-200 hover:bg-gray-300 rounded">• List</button>
</div>
<textarea id="editor" class="w-full h-full p-12 pt-10 text-sm font-mono outline-none border-r resize-none scrollbar-thin" placeholder="Write Markdown..."></textarea>
</div>
<!-- Preview Pane -->
<div id="previewPane" class="w-1/2 p-6 overflow-auto scrollbar-thin prose prose-indigo max-w-none transition-all duration-300"></div>
</div>
</main>
<script>
// Persistence
let pages = JSON.parse(localStorage.getItem('docPages') || '{}');
let currentId = null;
const AUTO_SAVE_INTERVAL = 5000;
// Elements
const sidebar = document.getElementById('sidebar');
const toolbarDiv = document.getElementById('toolbar');
const fileTree = document.getElementById('fileTree');
const newPageBtn = document.getElementById('newPageBtn');
const deletePageBtn = document.getElementById('deletePageBtn');
const saveBtn = document.getElementById('saveBtn');
const pageTitleInput = document.getElementById('pageTitle');
const editor = document.getElementById('editor');
const previewPane = document.getElementById('previewPane');
const toggleSidebarBtn = document.getElementById('toggleSidebarBtn');
const toggleEditorBtn = document.getElementById('toggleEditorBtn');
const editorToolbar = document.getElementById('editorToolbar');
const editorPane = document.getElementById('editorPane');
// Render file tree
function renderTree() {
fileTree.innerHTML = '';
for (let id of Object.keys(pages)) {
const li = document.createElement('li');
li.textContent = pages[id].title;
li.className = 'px-2 py-1 hover:bg-gray-700 rounded cursor-pointer ' + (id === currentId ? 'bg-gray-700' : '');
li.onclick = () => loadPage(id);
fileTree.append(li);
}
}
// Load a page
function loadPage(id) {
currentId = id;
const { title, content } = pages[id];
pageTitleInput.value = title;
editor.value = content;
updatePreview();
renderTree();
}
// Update preview with syntax highlighting
function updatePreview() {
const html = marked.parse(editor.value || '');
previewPane.innerHTML = html;
previewPane.querySelectorAll('pre code').forEach(block => hljs.highlightBlock(block));
}
// Save current page
function savePage() {
if (!currentId) return;
pages[currentId] = { title: pageTitleInput.value || 'Untitled', content: editor.value };
localStorage.setItem('docPages', JSON.stringify(pages));
renderTree();
}
// Create new page
newPageBtn.onclick = () => {
const id = Date.now().toString();
pages[id] = { title: 'Untitled', content: '' };
savePage(); loadPage(id);
};
// Delete page
deletePageBtn.onclick = () => {
if (!currentId) return;
delete pages[currentId];
localStorage.setItem('docPages', JSON.stringify(pages));
const ids = Object.keys(pages);
if (ids.length) loadPage(ids[0]);
else { currentId = null; editor.value = ''; pageTitleInput.value = ''; previewPane.innerHTML = ''; renderTree(); }
};
saveBtn.onclick = () => { savePage(); alert('Saved!'); };
// Auto-save every interval
setInterval(savePage, AUTO_SAVE_INTERVAL);
// Toggle sidebar visibility
toggleSidebarBtn.onclick = () => {
sidebar.classList.toggle('-translate-x-full');
toolbarDiv.classList.toggle('pl-0');
};
// Toggle editor visibility
toggleEditorBtn.onclick = () => {
const hidden = editorPane.classList.toggle('hidden');
if (hidden) previewPane.classList.replace('w-1/2', 'w-full');
else previewPane.classList.replace('w-full', 'w-1/2');
};
// Editor formatting toolbar
editorToolbar.onclick = e => {
if (!e.target.dataset.action) return;
const action = e.target.dataset.action;
const start = editor.selectionStart;
const end = editor.selectionEnd;
let selected = editor.value.slice(start, end);
let insert = '';
switch(action) {
case 'bold': insert = `**${selected || 'bold'}**`; break;
case 'italic': insert = `*${selected || 'italic'}*`; break;
case 'h1': insert = `# ${selected || 'Heading'}`; break;
case 'ul': insert = `- ${selected || 'List item'}`; break;
}
editor.setRangeText(insert, start, end, 'end');
updatePreview();
editor.focus();
};
editor.addEventListener('input', updatePreview);
// Initialize
renderTree();
if (!currentId && Object.keys(pages).length) loadPage(Object.keys(pages)[0]);
</script>
</body>
</html>