186 lines
8.4 KiB
HTML
186 lines
8.4 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Project Notes</title>
|
|
<link rel="stylesheet" href="/static/theme.css" />
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.9.0/styles/atom-one-dark.min.css" />
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.65.16/lib/codemirror.min.css" />
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.65.16/theme/material-darker.min.css" />
|
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/dompurify/dist/purify.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
|
|
<script type="module" src="/static/dist/project-notes-frontend.es.js"></script>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<button id="toggle-sidebar-btn" title="Afficher/Masquer la barre latérale" style="background: none; border: none; padding: 0; margin-right: 1rem; cursor: pointer; color: var(--text-primary); display: flex; align-items: center;">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
|
</button>
|
|
<h1>📝 Project Notes</h1>
|
|
<input
|
|
type="search"
|
|
name="query"
|
|
placeholder="Rechercher une note (mot-clé, tag:projet, title:... )"
|
|
hx-get="/api/search"
|
|
hx-trigger="keyup changed delay:500ms, search"
|
|
hx-target="#search-results"
|
|
hx-indicator="#search-spinner"
|
|
style="flex-grow: 1; max-width: 350px;"
|
|
/>
|
|
<button
|
|
hx-get="/api/home"
|
|
hx-target="#editor-container"
|
|
hx-swap="innerHTML"
|
|
style="white-space: nowrap;"
|
|
title="Retour à la page d'accueil">
|
|
🏠 Accueil
|
|
</button>
|
|
<button onclick="showNewNoteModal()" style="white-space: nowrap;">
|
|
✨ Nouvelle note
|
|
</button>
|
|
<div id="search-spinner" class="htmx-indicator">
|
|
<progress></progress>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Modal pour nouvelle note -->
|
|
<div id="new-note-modal" style="display: none;">
|
|
<div class="modal-overlay" onclick="hideNewNoteModal()"></div>
|
|
<div class="modal-content">
|
|
<h2>📝 Nouvelle note</h2>
|
|
<form onsubmit="handleNewNote(event)">
|
|
<label for="note-name">Nom de la note</label>
|
|
<input
|
|
type="text"
|
|
id="note-name"
|
|
placeholder="ma-note.md"
|
|
autocomplete="off"
|
|
autofocus
|
|
required
|
|
/>
|
|
<p style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.5rem;">
|
|
💡 Si la note existe déjà, elle sera ouverte.
|
|
</p>
|
|
<div style="display: flex; gap: 0.5rem; margin-top: 1.5rem;">
|
|
<button type="submit">Créer / Ouvrir</button>
|
|
<button type="button" class="secondary" onclick="hideNewNoteModal()">Annuler</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal pour nouveau dossier -->
|
|
<div id="new-folder-modal" style="display: none;">
|
|
<div class="modal-overlay" onclick="hideNewFolderModal()"></div>
|
|
<div class="modal-content">
|
|
<h2>📁 Nouveau dossier</h2>
|
|
<form onsubmit="handleNewFolder(event)">
|
|
<label for="folder-name">Nom du dossier</label>
|
|
<input
|
|
type="text"
|
|
id="folder-name"
|
|
placeholder="mon-dossier"
|
|
autocomplete="off"
|
|
autofocus
|
|
required
|
|
/>
|
|
<p style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.5rem;">
|
|
💡 Vous pouvez créer des sous-dossiers avec "/", ex: projets/backend
|
|
</p>
|
|
<div style="display: flex; gap: 0.5rem; margin-top: 1.5rem;">
|
|
<button type="submit">Créer</button>
|
|
<button type="button" class="secondary" onclick="hideNewFolderModal()">Annuler</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Overlay pour fermer la sidebar sur mobile -->
|
|
<div class="sidebar-overlay" onclick="toggleSidebar()"></div>
|
|
|
|
<div class="main-layout">
|
|
<aside>
|
|
<button class="sidebar-close-btn" onclick="toggleSidebar()" title="Fermer le menu">
|
|
✕
|
|
</button>
|
|
<section>
|
|
<h2>🔍 Recherche</h2>
|
|
<div id="search-results">
|
|
<!-- Les résultats de la recherche apparaîtront ici -->
|
|
</div>
|
|
</section>
|
|
|
|
<hr>
|
|
|
|
<section>
|
|
<h2>📚 Notes</h2>
|
|
<button onclick="showNewFolderModal()" class="folder-create-btn">
|
|
📁 Nouveau dossier
|
|
</button>
|
|
<div id="file-tree" hx-get="/api/tree" hx-trigger="load" hx-swap="innerHTML">
|
|
<!-- L'arborescence des fichiers apparaîtra ici -->
|
|
<p style="color: var(--text-muted); font-size: 0.85rem;">Chargement...</p>
|
|
</div>
|
|
</section>
|
|
</aside>
|
|
<main id="main-content">
|
|
<div id="editor-container"
|
|
hx-get="/api/home"
|
|
hx-trigger="load"
|
|
hx-swap="innerHTML">
|
|
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center; height: 50vh; text-align: center; color: var(--text-secondary);">
|
|
<svg style="width: 64px; height: 64px; margin-bottom: 1rem; opacity: 0.5;" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
|
|
</svg>
|
|
<p style="font-size: 1.1rem; margin: 0;">Chargement...</p>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</div>
|
|
|
|
<script>
|
|
// Fonction pour gérer l'accordéon des dossiers dans la page d'accueil
|
|
window.toggleFolder = function(folderId) {
|
|
const content = document.getElementById('folder-' + folderId);
|
|
const icon = document.getElementById('icon-' + folderId);
|
|
|
|
if (content && icon) {
|
|
if (content.style.display === 'none') {
|
|
content.style.display = 'block';
|
|
icon.textContent = '📁';
|
|
localStorage.setItem('folder-' + folderId, 'open');
|
|
} else {
|
|
content.style.display = 'none';
|
|
icon.textContent = '📂';
|
|
localStorage.setItem('folder-' + folderId, 'closed');
|
|
}
|
|
}
|
|
};
|
|
|
|
// Restaurer l'état des dossiers depuis localStorage
|
|
window.restoreFolderStates = function() {
|
|
document.querySelectorAll('.folder-content').forEach(function(content) {
|
|
const folderId = content.id.replace('folder-', '');
|
|
const state = localStorage.getItem('folder-' + folderId);
|
|
const icon = document.getElementById('icon-' + folderId);
|
|
|
|
if (state === 'closed' && icon) {
|
|
content.style.display = 'none';
|
|
icon.textContent = '📂';
|
|
}
|
|
});
|
|
};
|
|
|
|
// Restaurer les états des dossiers après chargement de la page d'accueil
|
|
document.body.addEventListener('htmx:afterSwap', function(event) {
|
|
if (event.detail.target.id === 'editor-container') {
|
|
// Attendre un peu que le DOM soit prêt
|
|
setTimeout(restoreFolderStates, 100);
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |