Mercurial
view mrjunejune/src/editor/index.html @ 201:6cdee35a7ba9
[MrJuneJune] notes
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Sun, 15 Feb 2026 07:07:50 -0800 |
| parents | |
| children |
line wrap: on
line source
<!DOCTYPE html> <html lang="en"> <head> {{/parts/base_head.html}} <title>Editor | MrJuneJune</title> <style> .editor-page { max-width: 900px; margin: 0 auto; padding: 20px; } .editor-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .editor-header h1 { margin: 0; } .doc-selector { display: flex; gap: 10px; align-items: center; } .doc-selector input { padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } .doc-selector button { padding: 8px 16px; background: #0078ff; color: white; border: none; border-radius: 4px; cursor: pointer; } .doc-selector button:hover { background: #0066dd; } .auth-section { margin-bottom: 20px; padding: 16px; background: #f5f5f5; border-radius: 4px; } .auth-section input { width: 300px; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 14px; } .auth-section label { display: block; margin-bottom: 8px; font-weight: bold; } </style> </head> <body> {{/parts/header.html}} <main class="editor-page"> <div class="editor-header"> <h1>Rich Editor</h1> <div class="doc-selector"> <input type="text" id="doc-id" placeholder="Document ID" value="default"> <button onclick="loadDocument()">Load</button> </div> </div> <div class="auth-section"> <label for="auth-token">Auth Token:</label> <input type="password" id="auth-token" placeholder="Enter your auth token"> </div> <div id="editor-container"></div> </main> {{/parts/footer.html}} <script src="/public/js/rich_editor.js"></script> <script> let editor = null; function getAuthToken() { return document.getElementById('auth-token').value; } function getDocId() { return document.getElementById('doc-id').value || 'default'; } async function uploadFile(file) { const token = getAuthToken(); if (!token) { alert('Please enter your auth token'); throw new Error('No auth token'); } // Get presigned upload URL const response = await fetch('/api/s3/upload-url', { method: 'POST', headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }, body: JSON.stringify({ filename: file.name, content_type: file.type }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to get upload URL'); } const data = await response.json(); // Upload file directly to S3 const uploadResponse = await fetch(data.upload_url, { method: 'PUT', headers: { 'Content-Type': file.type }, body: file }); if (!uploadResponse.ok) { throw new Error('Failed to upload file to S3'); } return { url: data.public_url, key: data.key }; } async function saveContent(content) { const token = getAuthToken(); if (!token) { console.warn('No auth token, skipping save'); return; } const response = await fetch('/api/editor/save', { method: 'POST', headers: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }, body: JSON.stringify({ doc_id: getDocId(), content: content }) }); if (!response.ok) { const error = await response.json(); throw new Error(error.error || 'Failed to save'); } } async function loadDocument() { const token = getAuthToken(); if (!token) { alert('Please enter your auth token'); return; } const docId = getDocId(); try { const response = await fetch('/api/editor/load/' + encodeURIComponent(docId), { headers: { 'Authorization': 'Bearer ' + token } }); if (!response.ok) { const error = await response.json(); alert('Error: ' + (error.error || 'Failed to load')); return; } const data = await response.json(); editor.setContent(data.content || ''); console.log('Loaded document:', docId); } catch (error) { console.error('Load error:', error); alert('Failed to load document'); } } // Initialize editor document.addEventListener('DOMContentLoaded', function() { editor = RichEditor.init('editor-container', { uploadCallback: uploadFile, saveCallback: saveContent, debounceMs: 1500, placeholder: 'Start writing... (paste images, use /upload for files)' }); // Try to load saved token from localStorage const savedToken = localStorage.getItem('editor-auth-token'); if (savedToken) { document.getElementById('auth-token').value = savedToken; } // Save token to localStorage on change document.getElementById('auth-token').addEventListener('change', function() { localStorage.setItem('editor-auth-token', this.value); }); }); </script> </body> </html>