166 lines
10 KiB
HTML
166 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>EchoLog</title>
|
|
<link rel="icon" type="image/png" href="{{ url_for('static', filename='echolog.png') }}">
|
|
<link href="{{ url_for('static', filename='output.css') }}" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
|
|
<!-- PWA Manifest and Meta -->
|
|
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
|
<meta name="theme-color" content="#0f172a">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
<link rel="apple-touch-icon" href="{{ url_for('static', filename='echolog.png') }}">
|
|
<script>
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', function() {
|
|
navigator.serviceWorker.register("{{ url_for('static', filename='service-worker.js') }}");
|
|
});
|
|
}
|
|
</script>
|
|
</head>
|
|
<body class="bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 min-h-screen text-white">
|
|
<div class="container mx-auto max-w-2xl p-6">
|
|
<header class="mb-8 flex items-center justify-between">
|
|
<div>
|
|
<a href="/"><h1 class="text-4xl font-extrabold tracking-tight bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">EchoLog</h1></a>
|
|
<p class="text-gray-400 mt-1">Your personal homelab journal</p>
|
|
</div>
|
|
{% if session.logged_in %}
|
|
<a href="/logout" class="text-gray-300 hover:text-pink-400 transition text-xl" title="Logout">
|
|
<i class="fas fa-sign-out-alt"></i>
|
|
</a>
|
|
{% endif %}
|
|
</header>
|
|
|
|
<form action="/add" method="POST" class="mb-8 bg-gray-800/80 rounded-xl shadow-lg p-6 border border-gray-700">
|
|
<div class="mb-4">
|
|
<label for="date" class="block text-xs font-semibold text-gray-400 mb-1">Date</label>
|
|
<input type="date" id="date" name="date" class="w-full p-2 bg-gray-900 border border-gray-700 rounded focus:ring-2 focus:ring-blue-500" required value="{{ today }}">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label for="content" class="block text-xs font-semibold text-gray-400 mb-1">Journal Entry</label>
|
|
<textarea id="content" name="content" rows="4" class="w-full p-3 bg-gray-900 border border-gray-700 rounded focus:ring-2 focus:ring-blue-500 resize-vertical" placeholder="What did you do today?" required></textarea>
|
|
</div>
|
|
<button type="submit" class="w-full py-2 bg-gradient-to-r from-blue-500 to-pink-500 text-white font-bold rounded shadow hover:scale-105 transition">Add Entry</button>
|
|
</form>
|
|
|
|
<form action="/search" method="GET" class="mb-8 flex flex-col gap-4 items-stretch md:flex-row md:items-end">
|
|
<div class="flex-1">
|
|
<label for="query" class="block text-xs font-semibold text-gray-400 mb-1">Search</label>
|
|
<input type="text" id="query" name="query" class="w-full p-2 bg-gray-900 border border-gray-700 rounded" placeholder="Search by keyword...">
|
|
</div>
|
|
<div class="flex-1">
|
|
<label for="date_search" class="block text-xs font-semibold text-gray-400 mb-1">Date</label>
|
|
<input type="date" id="date_search" name="date" class="w-full p-2 bg-gray-900 border border-gray-700 rounded">
|
|
</div>
|
|
<button type="submit" class="px-6 py-2 bg-gradient-to-r from-purple-500 to-pink-500 text-white font-bold rounded shadow hover:scale-105 transition w-full md:w-auto">Filter</button>
|
|
</form>
|
|
|
|
<section>
|
|
<h2 class="text-2xl font-bold mb-4 text-pink-400">Previous Entries</h2>
|
|
<ul class="space-y-6">
|
|
{% for entry in entries %}
|
|
<li class="p-5 bg-gray-800/80 rounded-xl border border-gray-700 shadow hover:shadow-lg transition">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<span class="text-xs text-gray-400 font-mono">{{ entry.date }}</span>
|
|
<div class="flex gap-2">
|
|
<button type="button" class="text-blue-400 hover:text-blue-200" title="Edit" onclick='openEditModal("{{ entry.id|escape }}", "{{ entry.date|escape }}", {{ entry.content|tojson|safe }})'><i class="fas fa-edit"></i></button>
|
|
<button type="button" class="text-pink-400 hover:text-pink-200" title="Delete" onclick='openDeleteModal("{{ entry.id|escape }}")'><i class="fas fa-trash-alt"></i></button>
|
|
</div>
|
|
</div>
|
|
<pre class="whitespace-pre-wrap break-words text-base text-gray-100 font-sans">{{ entry.content }}</pre>
|
|
</li>
|
|
{% else %}
|
|
<li class="text-gray-500 text-center">No entries found.</li>
|
|
{% endfor %}
|
|
</ul>
|
|
|
|
<!-- Edit Modal -->
|
|
<div id="edit-modal" class="fixed inset-0 bg-black/30 backdrop-blur-sm flex items-center justify-center z-50 hidden">
|
|
<div class="bg-gray-900 rounded-xl shadow-2xl p-8 w-full max-w-lg border border-gray-700 relative">
|
|
<button onclick="closeEditModal()" class="absolute top-4 right-4 text-gray-400 hover:text-pink-400 text-2xl"><i class="fas fa-times"></i></button>
|
|
<h2 class="text-2xl font-bold mb-6 text-pink-400">Edit Entry</h2>
|
|
<form id="edit-form" action="/edit_modal" method="POST" class="space-y-4">
|
|
<input type="hidden" id="edit-id" name="id">
|
|
<div>
|
|
<label for="edit-date" class="block text-xs font-semibold text-gray-400 mb-1">Date</label>
|
|
<input type="date" id="edit-date" name="date" class="w-full p-2 bg-gray-800 border border-gray-700 rounded focus:ring-2 focus:ring-blue-500" required>
|
|
</div>
|
|
<div>
|
|
<label for="edit-content" class="block text-xs font-semibold text-gray-400 mb-1">Journal Entry</label>
|
|
<textarea id="edit-content" name="content" rows="4" class="w-full p-3 bg-gray-800 border border-gray-700 rounded focus:ring-2 focus:ring-blue-500 resize-vertical" required></textarea>
|
|
</div>
|
|
<div class="flex gap-4">
|
|
<button type="submit" class="flex-1 py-2 bg-gradient-to-r from-blue-500 to-pink-500 text-white font-bold rounded shadow hover:scale-105 transition">Save Changes</button>
|
|
<button type="button" onclick="closeEditModal()" class="flex-1 py-2 bg-gray-700 text-white font-bold rounded shadow hover:bg-gray-600 transition">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Delete Modal -->
|
|
<div id="delete-modal" class="fixed inset-0 bg-black/30 backdrop-blur-sm flex items-center justify-center z-50 hidden">
|
|
<div class="bg-gray-900 rounded-xl shadow-2xl p-8 w-full max-w-md border border-gray-700 relative">
|
|
<button onclick="closeDeleteModal()" class="absolute top-4 right-4 text-gray-400 hover:text-pink-400 text-2xl"><i class="fas fa-times"></i></button>
|
|
<h2 class="text-2xl font-bold mb-6 text-pink-400">Delete Entry</h2>
|
|
<p class="mb-6 text-gray-300">Are you sure you want to delete this entry? This action cannot be undone.</p>
|
|
<form id="delete-form" method="POST">
|
|
<div class="flex gap-4">
|
|
<button type="submit" class="flex-1 py-2 bg-gradient-to-r from-blue-500 to-pink-500 text-white font-bold rounded shadow hover:scale-105 transition">Delete</button>
|
|
<button type="button" onclick="closeDeleteModal()" class="flex-1 py-2 bg-gray-700 text-white font-bold rounded shadow hover:bg-gray-600 transition">Cancel</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-8 flex justify-between">
|
|
{% if has_prev %}
|
|
<a href="?page={{ page - 1 }}" class="px-4 py-2 bg-gray-700 rounded hover:bg-gray-600">Previous</a>
|
|
{% else %}
|
|
<span></span>
|
|
{% endif %}
|
|
{% if has_next %}
|
|
<a href="?page={{ page + 1 }}" class="px-4 py-2 bg-gray-700 rounded hover:bg-gray-600">Next</a>
|
|
{% endif %}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<footer class="mt-16 py-6 border-t border-gray-800 text-center text-gray-500 text-sm">
|
|
<span>JDB-NET © {{ now.year }}</span>
|
|
·
|
|
<a href="https://echolog.jdbnet.co.uk" target="_blank" rel="noopener" class="text-gray-500 hover:text-pink-400 hover:underline ml-1">Docs</a>
|
|
</footer>
|
|
|
|
<script>
|
|
function openEditModal(id, date, content) {
|
|
document.getElementById('edit-modal').classList.remove('hidden');
|
|
document.getElementById('edit-id').value = id;
|
|
document.getElementById('edit-date').value = date;
|
|
document.getElementById('edit-content').value = content;
|
|
}
|
|
function closeEditModal() {
|
|
document.getElementById('edit-modal').classList.add('hidden');
|
|
}
|
|
function openDeleteModal(id) {
|
|
document.getElementById('delete-modal').classList.remove('hidden');
|
|
var form = document.getElementById('delete-form');
|
|
form.action = '/delete/' + id;
|
|
}
|
|
function closeDeleteModal() {
|
|
document.getElementById('delete-modal').classList.add('hidden');
|
|
document.getElementById('delete-form').action = '';
|
|
}
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.key === 'Escape') {
|
|
closeEditModal();
|
|
closeDeleteModal();
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|