| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- <aside class="w-64 border-r border-zinc-800 bg-zinc-900/50 flex flex-col">
- <div class="p-4 flex justify-between items-center border-b border-zinc-800">
- <span class="text-xs font-bold uppercase tracking-widest text-zinc-500">Main Vault</span>
- <span class="text-[10px] px-1.5 py-0.5 rounded bg-zinc-800 text-zinc-400 border border-zinc-700">v2.4</span>
- </div>
- <div class="flex-1 overflow-y-auto custom-scrollbar p-2 space-y-0.5">
- {{range .Subfoldere}}
- {{template "folder" .}}
- {{end}}
- {{range .Fisiere}}
- {{template "file" .}}
- {{end}}
- </div>
- {{/* BOTTOM: NEW ROOT FOLDER */}}
- <div class="p-2 border-t border-zinc-800">
- <form method="POST" action="/api/create_dir" class="flex gap-1 items-center">
- <input type="hidden" name="director" value="">
- <input
- type="text"
- name="subdirector"
- placeholder="New folder..."
- class="flex-1 bg-zinc-800 text-zinc-300 text-xs rounded px-2 py-1 outline-none border border-zinc-700 focus:border-zinc-500 placeholder-zinc-600"
- >
- <button type="submit"
- class="text-zinc-400 hover:text-zinc-100 hover:bg-zinc-700 rounded p-1 transition-colors border border-zinc-700"
- title="Create folder">
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/>
- </svg>
- </button>
- </form>
- </div>
- </aside>
- {{/* ================= FILE TEMPLATE ================= */}}
- {{define "file"}}
- <div class="group/file flex items-center justify-between px-2 py-1 text-xs rounded hover:bg-zinc-800 text-zinc-500 hover:text-zinc-300 transition-colors">
- <a href="/design_view/?note={{.Path}}" class="flex items-center gap-2 min-w-0 flex-1">
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
- class="shrink-0 text-zinc-600">
- <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
- <polyline points="14 2 14 8 20 8"/>
- </svg>
- <span class="truncate">{{.Nume}}</span>
- </a>
- {{/* DELETE FILE BUTTON */}}
- <form id="delete-file-{{.Path}}" method="POST" action="/api/delete_file">
- <input type="hidden" name="path" value="{{.Path}}">
- <button type="button"
- onclick="event.stopPropagation(); showDeleteModal('Delete {{.Nume}}? This cannot be undone.', 'delete-file-{{.Path}}')"
- class="opacity-0 group-hover/file:opacity-100 transition-opacity text-zinc-600 hover:text-red-400 rounded p-0.5"
- title="Delete note">
- <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <polyline points="3 6 5 6 21 6"/>
- <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
- <path d="M10 11v6M14 11v6"/>
- <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>
- </svg>
- </button>
- </form>
- </div>
- {{end}}
- {{/* ================= FOLDER TEMPLATE ================= */}}
- {{define "folder"}}
- <details class="group" id="folder-{{.Nume}}"
- ontoggle="saveFolderState('folder-{{.Nume}}', this.open)">
- <summary class="flex items-center justify-between px-2 py-1 text-xs rounded hover:bg-zinc-800 cursor-pointer list-none text-zinc-400 group-open:text-zinc-200 transition-colors">
- <div class="flex items-center gap-1.5 min-w-0">
- <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"
- class="shrink-0 transition-transform duration-150 group-open:rotate-90">
- <polyline points="9 18 15 12 9 6"/>
- </svg>
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
- class="shrink-0 text-zinc-500 group-open:hidden">
- <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
- </svg>
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"
- class="shrink-0 text-zinc-300 hidden group-open:block">
- <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
- <line x1="2" y1="10" x2="22" y2="10"/>
- </svg>
- <span class="truncate">{{.Display}}</span>
- </div>
- {{/* ACTION BUTTONS — visible on hover only */}}
- <div class="flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity shrink-0">
- {{/* New note button */}}
- <form method="POST" action="/api/save_note">
- <input type="hidden" name="director" value="{{.Nume}}">
- <input type="hidden" name="titlu" value="Untitled">
- <input type="hidden" name="notita" value="">
- <button type="submit"
- onclick="event.stopPropagation()"
- class="text-zinc-500 hover:text-zinc-100 hover:bg-zinc-700 rounded p-0.5 transition-colors"
- title="New note">
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/>
- <polyline points="14 2 14 8 20 8"/>
- <line x1="12" y1="18" x2="12" y2="12"/>
- <line x1="9" y1="15" x2="15" y2="15"/>
- </svg>
- </button>
- </form>
- {{/* New subfolder button */}}
- <button
- onclick="event.stopPropagation(); var f = this.closest('details').querySelector('.new-folder-form'); f.style.display = f.style.display === 'none' ? 'flex' : 'none'; f.querySelector('input[type=text]').focus();"
- class="text-zinc-500 hover:text-zinc-100 hover:bg-zinc-700 rounded p-0.5 transition-colors"
- title="New folder">
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"/>
- <line x1="12" y1="13" x2="12" y2="19"/>
- <line x1="9" y1="16" x2="15" y2="16"/>
- </svg>
- </button>
- {{/* DELETE FOLDER BUTTON */}}
- <form id="delete-dir-{{.Nume}}" method="POST" action="/api/delete_dir">
- <input type="hidden" name="path" value="{{.Nume}}">
- <button type="button"
- onclick="event.stopPropagation(); showDeleteModal('Delete {{.Display}} and everything inside it? This cannot be undone.', 'delete-dir-{{.Nume}}')"
- class="text-zinc-500 hover:text-red-400 rounded p-0.5 transition-colors"
- title="Delete folder">
- <svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
- <polyline points="3 6 5 6 21 6"/>
- <path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/>
- <path d="M10 11v6M14 11v6"/>
- <path d="M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2"/>
- </svg>
- </button>
- </form>
- </div>
- </summary>
- {{/* INLINE FOLDER NAME INPUT */}}
- <form method="POST" action="/api/create_dir"
- class="new-folder-form gap-1 px-2 py-1 items-center"
- style="display:none;">
- <input type="hidden" name="director" value="{{.Nume}}">
- <input
- type="text"
- name="subdirector"
- placeholder="Folder name..."
- class="flex-1 bg-zinc-800 text-zinc-300 text-xs rounded px-2 py-1 outline-none border border-zinc-700 focus:border-zinc-500 placeholder-zinc-600"
- >
- <button type="submit"
- class="text-zinc-400 hover:text-zinc-100 hover:bg-zinc-700 rounded p-1 transition-colors border border-zinc-700">
- <svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 24 24"
- fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
- <polyline points="20 6 9 17 4 12"/>
- </svg>
- </button>
- </form>
- {{/* CHILDREN */}}
- <div class="ml-3 pl-2 border-l border-zinc-800 space-y-0.5 mt-0.5">
- {{range .Fisiere}}
- {{template "file" .}}
- {{end}}
- {{range .Subfoldere}}
- {{template "folder" .}}
- {{end}}
- </div>
- </details>
- {{end}}
- <script>
- function saveFolderState(id, isOpen) {
- const states = JSON.parse(localStorage.getItem('folderStates') || '{}');
- states[id] = isOpen;
- localStorage.setItem('folderStates', JSON.stringify(states));
- }
- function restoreFolderStates() {
- const states = JSON.parse(localStorage.getItem('folderStates') || '{}');
- document.querySelectorAll('details[id^="folder-"]').forEach(details => {
- const id = details.id;
- if (id in states) {
- details.open = states[id];
- } else {
- details.open = true;
- }
- });
- }
- document.addEventListener('DOMContentLoaded', restoreFolderStates);
- function showDeleteModal(message, formId) {
- document.getElementById('delete-modal-message').textContent = message;
- document.getElementById('delete-modal-confirm').onclick = function() {
- document.getElementById(formId).submit();
- };
- document.getElementById('delete-modal').classList.remove('hidden');
- }
- function hideDeleteModal() {
- document.getElementById('delete-modal').classList.add('hidden');
- }
- // Close on Escape key
- document.addEventListener('keydown', function(e) {
- if (e.key === 'Escape') hideDeleteModal();
- });
- </script>
|