2026-06-03 10:43:17 +01:00
|
|
|
{% extends "base.html" %}
|
|
|
|
|
|
|
|
|
|
{% block content %}
|
|
|
|
|
<h2>Project Management - Development Notes</h2>
|
|
|
|
|
|
|
|
|
|
<div class="project-management-container">
|
|
|
|
|
<div class="editor-section">
|
|
|
|
|
<div class="editor-controls">
|
|
|
|
|
<button onclick="saveNotes()" class="btn">Save Notes</button>
|
|
|
|
|
<button onclick="loadNotes()" class="btn">Reload</button>
|
|
|
|
|
<span id="status" style="margin-left: 15px; font-style: italic;"></span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="editor-row">
|
|
|
|
|
<div class="editor-col">
|
|
|
|
|
<h3>Editor</h3>
|
|
|
|
|
<textarea id="markdown-editor" class="markdown-editor"
|
|
|
|
|
placeholder="Write your markdown notes here..."></textarea>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="editor-col">
|
|
|
|
|
<h3>Preview</h3>
|
|
|
|
|
<div id="markdown-preview" class="markdown-preview"></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
|
|
|
<script>
|
|
|
|
|
const NOTES_FILE = 'notes_development/project_notes.md';
|
|
|
|
|
|
|
|
|
|
// Initialize: load and render notes
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
|
loadNotes();
|
|
|
|
|
|
|
|
|
|
// Set up live preview
|
|
|
|
|
const editor = document.getElementById('markdown-editor');
|
|
|
|
|
const preview = document.getElementById('markdown-preview');
|
|
|
|
|
|
|
|
|
|
editor.addEventListener('input', function() {
|
|
|
|
|
preview.innerHTML = marked.parse(editor.value);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function loadNotes() {
|
|
|
|
|
fetch('/get_notes/' + NOTES_FILE)
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (!response.ok) {
|
|
|
|
|
throw new Error('File not found, using default');
|
|
|
|
|
}
|
|
|
|
|
return response.text();
|
|
|
|
|
})
|
|
|
|
|
.then(content => {
|
|
|
|
|
document.getElementById('markdown-editor').value = content;
|
|
|
|
|
document.getElementById('markdown-preview').innerHTML = marked.parse(content);
|
|
|
|
|
document.getElementById('status').textContent = 'Loaded successfully';
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
document.getElementById('status').textContent = '';
|
|
|
|
|
}, 2000);
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
document.getElementById('status').textContent = 'Using default content';
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
document.getElementById('status').textContent = '';
|
|
|
|
|
}, 2000);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function saveNotes() {
|
|
|
|
|
const content = document.getElementById('markdown-editor').value;
|
|
|
|
|
const statusEl = document.getElementById('status');
|
|
|
|
|
|
|
|
|
|
fetch('/save_notes', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ content: content, filename: NOTES_FILE })
|
|
|
|
|
})
|
|
|
|
|
.then(response => {
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
statusEl.textContent = 'Saved successfully!';
|
|
|
|
|
statusEl.style.color = '#4CAF50';
|
|
|
|
|
} else {
|
|
|
|
|
statusEl.textContent = 'Error saving';
|
|
|
|
|
statusEl.style.color = '#f44336';
|
|
|
|
|
}
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
statusEl.textContent = '';
|
|
|
|
|
statusEl.style.color = '';
|
|
|
|
|
}, 2000);
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
statusEl.textContent = 'Error: ' + error.message;
|
|
|
|
|
statusEl.style.color = '#f44336';
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
statusEl.textContent = '';
|
|
|
|
|
statusEl.style.color = '';
|
|
|
|
|
}, 2000);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Auto-save every 30 seconds
|
|
|
|
|
setInterval(() => {
|
|
|
|
|
saveNotes();
|
|
|
|
|
}, 30000);
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
.project-management-container {
|
|
|
|
|
max-width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.editor-controls {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
margin-bottom: 15px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
background-color: #f9f9f9;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.editor-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 20px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.editor-col {
|
|
|
|
|
flex: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-editor {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 500px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview {
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 500px;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
background-color: white;
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview h1,
|
|
|
|
|
.markdown-preview h2,
|
|
|
|
|
.markdown-preview h3,
|
|
|
|
|
.markdown-preview h4,
|
|
|
|
|
.markdown-preview h5,
|
|
|
|
|
.markdown-preview h6 {
|
|
|
|
|
margin-top: 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview pre {
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
padding: 10px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
overflow-x: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview code {
|
|
|
|
|
font-family: monospace;
|
|
|
|
|
background-color: #f5f5f5;
|
|
|
|
|
padding: 2px 4px;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview table {
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.markdown-preview th,
|
|
|
|
|
.markdown-preview td {
|
|
|
|
|
border: 1px solid #ddd;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
}
|
2026-06-20 01:20:39 +01:00
|
|
|
|
|
|
|
|
/* ============================================
|
|
|
|
|
RESPONSIVE DESIGN FOR PROJECT MANAGEMENT
|
|
|
|
|
============================================ */
|
2026-06-03 10:43:17 +01:00
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.editor-row {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
}
|
2026-06-20 01:20:39 +01:00
|
|
|
.markdown-editor,
|
|
|
|
|
.markdown-preview {
|
|
|
|
|
height: 350px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (max-width: 480px) {
|
|
|
|
|
.editor-controls {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 0.5rem;
|
|
|
|
|
}
|
|
|
|
|
.editor-controls button {
|
|
|
|
|
width: 100%;
|
|
|
|
|
}
|
2026-06-03 10:43:17 +01:00
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
{% endblock %}
|