|
|
@@ -0,0 +1,113 @@
|
|
|
+{{showFile "templates/design/sections/head.tmpl"}}
|
|
|
+<body class="bg-zinc-950 text-zinc-200 h-screen overflow-hidden flex">
|
|
|
+{{showFile "templates/design/sections/nav_small.tmpl"}}
|
|
|
+{{showFile "templates/design/sections/nav_big.tmpl"}}
|
|
|
+
|
|
|
+
|
|
|
+ <main class="flex-1 flex flex-col relative bg-zinc-900/20 overflow-auto">
|
|
|
+ {{showFile "templates/design/sections/nav_header.tmpl"}}
|
|
|
+
|
|
|
+ <div class="flex-1 flex">
|
|
|
+ <section class="flex-1 overflow-y-auto custom-scrollbar p-12">
|
|
|
+ <div class="w-full grid grid-cols-2 gap-0 border border-zinc-700">
|
|
|
+
|
|
|
+
|
|
|
+ <div class="h-[85vh] bg-[#446454]">
|
|
|
+ <textarea
|
|
|
+ id="editor"
|
|
|
+ placeholder="Start typing..."
|
|
|
+ class="p-6 w-full h-full bg-transparent text-zinc-100 text-[14px] focus:outline-none resize-none custom-scrollbar"
|
|
|
+ ></textarea>
|
|
|
+ </div>
|
|
|
+ <div id="preview" class="border-r border-zinc-700 h-[85vh] bg-[#454644] p-2 text-zinc-100 overflow-y-auto font-sans prose prose-invert prose-zinc max-w-none
|
|
|
+ /* --- Code Blocks (Pre) --- */
|
|
|
+ [&_pre]:bg-zinc-900/80 [&_pre]:p-4 [&_pre]:rounded-lg [&_pre]:border [&_pre]:border-zinc-700
|
|
|
+ [&_pre]:my-6 [&_pre]:overflow-x-auto [&_pre]:shadow-inner
|
|
|
+
|
|
|
+ /* --- Inline Code (<code>) --- */
|
|
|
+ [&_code]:font-mono [&_code]:text-indigo-300 [&_code]:bg-zinc-800/50
|
|
|
+ [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[0.9em]
|
|
|
+ /* Evităm background-ul dublu când codul este în interiorul unui <pre> */
|
|
|
+ [&_pre_code]:bg-transparent [&_pre_code]:p-0 [&_pre_code]:text-zinc-200 [&_pre_code]:text-[0.85em]
|
|
|
+
|
|
|
+ /* --- Stiluri Blockquote --- */
|
|
|
+ [&_blockquote]:border-l-4 [&_blockquote]:border-indigo-500 [&_blockquote]:bg-zinc-800/30
|
|
|
+ [&_blockquote]:py-2 [&_blockquote]:px-5 [&_blockquote]:my-4 [&_blockquote]:italic [&_blockquote]:text-zinc-300
|
|
|
+
|
|
|
+ /* --- Stiluri Bold & Italic --- */
|
|
|
+ [&_strong]:text-white [&_strong]:font-bold
|
|
|
+ [&_em]:text-indigo-200 [&_em]:italic
|
|
|
+
|
|
|
+ /* --- Stiluri pentru Tabele --- */
|
|
|
+ [&_table]:w-full [&_table]:my-6 [&_table]:border-collapse [&_table]:border [&_table]:border-zinc-600
|
|
|
+ [&_thead]:bg-zinc-800/50
|
|
|
+ [&_th]:border [&_th]:border-zinc-600 [&_th]:p-3 [&_th]:text-left [&_th]:text-indigo-300 [&_th]:uppercase [&_th]:text-[11px]
|
|
|
+ [&_td]:border [&_td]:border-zinc-600 [&_td]:p-3 [&_td]:text-sm
|
|
|
+ [&_tr:nth-child(even)]:bg-zinc-700/30
|
|
|
+
|
|
|
+ /* --- Stiluri pentru Liste & Headings --- */
|
|
|
+ [&_ul]:list-disc [&_ul]:ml-6 [&_ol]:list-decimal [&_ol]:ml-6
|
|
|
+ [&_h1]:text-3xl [&_h1]:font-bold [&_h1]:border-b [&_h1]:border-zinc-600 [&_h1]:pb-2 [&_h1]:mb-4
|
|
|
+ [&_h2]:text-xl [&_h2]:font-semibold [&_h2]:text-indigo-400 [&_h2]:mt-6 custom-scrollbar">
|
|
|
+ Your preview will appear here...
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</section>
|
|
|
+
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </main>
|
|
|
+
|
|
|
+<script>
|
|
|
+ const editor = document.getElementById('editor');
|
|
|
+const preview = document.getElementById('preview');
|
|
|
+
|
|
|
+// Debounce helper
|
|
|
+function debounce(func, delay) {
|
|
|
+ let timeout;
|
|
|
+ return function(...args) {
|
|
|
+ clearTimeout(timeout);
|
|
|
+ timeout = setTimeout(() => func.apply(this, args), delay);
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+// The API Call
|
|
|
+const updatePreview = async () => {
|
|
|
+ const content = editor.value;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await fetch('/live_preview/', {
|
|
|
+ method: 'POST',
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
+ body: JSON.stringify({ markdown: content })
|
|
|
+ });
|
|
|
+
|
|
|
+ if (response.ok) {
|
|
|
+ const htmlResult = await response.text();
|
|
|
+ preview.innerHTML = htmlResult;
|
|
|
+
|
|
|
+ // 1. Aplică etichetele de limbaj (codul de mai devreme)
|
|
|
+ preview.querySelectorAll('pre code').forEach((codeBlock) => {
|
|
|
+ const pre = codeBlock.parentElement;
|
|
|
+ const langClass = Array.from(codeBlock.classList).find(c => c.startsWith('language-'));
|
|
|
+ if (langClass) {
|
|
|
+ pre.setAttribute('data-language', langClass.replace('language-', ''));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. Declanșează evidențierea sintaxei
|
|
|
+ hljs.highlightElement(codeBlock);
|
|
|
+ });
|
|
|
+
|
|
|
+ console.log("Remote Preview & Highlighting Updated!");
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error("Error:", error);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// Listen for input, trigger every 500ms of "pause"
|
|
|
+editor.addEventListener('input', debounce(updatePreview, 500));
|
|
|
+</script>
|
|
|
+
|
|
|
+</body>
|
|
|
+</html>
|