initial functionality and styling pass

This commit is contained in:
Bryan Van Deusen
2025-07-29 00:34:03 -04:00
parent 1590ca72c1
commit c67f1afc1f
1763 changed files with 876 additions and 76 deletions
+56
View File
@@ -0,0 +1,56 @@
{% extends "layout.html" %}
{% block title %}{{ artist }}'s Gallery{% endblock %}
{% block content %}
<h1 style="text-align:center; margin-top: 1rem;">{{ artist }}</h2>
<!-- Pagination Controls -->
<div class="pagination-container">
{% if images.has_prev %}
<a class="pagination-link" href="{{ url_for('main.artist_gallery', artist_name=artist, page=images.prev_num) }}">← Previous</a>
{% endif %}
{% for p in range(1, images.pages + 1) %}
<a class="pagination-link {% if p == images.page %}active{% endif %}" href="{{ url_for('main.artist_gallery', artist_name=artist, page=p) }}">{{ p }}</a>
{% endfor %}
{% if images.has_next %}
<a class="pagination-link" href="{{ url_for('main.artist_gallery', artist_name=artist, page=images.next_num) }}">Next →</a>
{% endif %}
</div>
<!-- Gallery Grid -->
<div class="gallery-grid">
{% for image in images %}
<div class="gallery-item">
<div class="gallery-thumb img-clickable"
data-full="{{ url_for('static', filename=image.filepath) }}"
style="background-image: url('{{ url_for('static', filename=image.filepath) }}');"
data-full="{{ url_for('static', filename=image.filepath) }}"
data-filename="{{ image.filename }}">
</div>
<a href="{{ url_for('main.artist_gallery', artist_name=image.artist) }}">{{ image.artist }}</a>
<span class="image-date">
{{ image.taken_at or image.imported_at | datetimeformat }}
</span>
</div>
{% endfor %}
</div>
<!-- Pagination Controls -->
<div class="pagination-container">
{% if images.has_prev %}
<a class="pagination-link" href="{{ url_for('main.artist_gallery', artist_name=artist, page=images.prev_num) }}">← Previous</a>
{% endif %}
{% for p in range(1, images.pages + 1) %}
<a class="pagination-link {% if p == images.page %}active{% endif %}" href="{{ url_for('main.artist_gallery', artist_name=artist, page=p) }}">{{ p }}</a>
{% endfor %}
{% if images.has_next %}
<a class="pagination-link" href="{{ url_for('main.artist_gallery', artist_name=artist, page=images.next_num) }}">Next →</a>
{% endif %}
</div>
{% endblock %}
+25
View File
@@ -0,0 +1,25 @@
{% extends "layout.html" %}
{% block title %}Gallery{% endblock %}
{% block content %}
<!-- Gallery Thumbnail Grid -->
<div class="gallery-grid">
{% for image in images %}
<div class="gallery-item">
<div class="gallery-thumb img-clickable"
data-full="{{ url_for('static', filename=image.filepath) }}"
style="background-image: url('{{ url_for('static', filename=image.filepath) }}');"
data-full="{{ url_for('static', filename=image.filepath) }}"
data-filename="{{ image.filename }}">
</div>
<a href="{{ url_for('main.artist_gallery', artist_name=image.artist) }}">{{ image.artist }}</a>
<span class="image-date">
{{ image.taken_at or image.imported_at | datetimeformat }}
</span>
</div>
{% endfor %}
</div>
{% endblock %}
+117 -21
View File
@@ -1,37 +1,133 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Flask Template App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<meta charset="utf-8">
<title>Flask Template App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="mainview">
<header>
{% if current_user.is_authenticated %}
Hello {{ current_user.username }} |
<a href="{{ url_for('auth.logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('auth.login') }}">Login</a> |
<a href="{{ url_for('auth.register') }}">Register</a>
<header>
<nav class="navbar">
<a class="nav-button" href="{{ url_for('main.gallery') if current_user.is_authenticated else url_for('main.index') }}">Home</a>
{% if current_user.is_authenticated and current_user.is_admin %}
<a class="nav-button" href="{{ url_for('main.settings') }}">Settings</a>
{% endif %}
{% if current_user.is_authenticated %}
<a class="nav-button" href="{{ url_for('auth.logout') }}">Logout</a>
{% else %}
<a class="nav-button" href="{{ url_for('auth.login') }}">Login</a>
<a class="nav-button" href="{{ url_for('auth.register') }}">Register</a>
{% endif %}
</nav>
</header>
<!-- FLASH MESSAGES -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash {{ category }}">
{{ message }}
</header>
<!-- FLASH MESSAGES -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="flash {{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
<hr>
<!-- MAIN CONTENT -->
<div class="content">
{% block content %}{% endblock %}
</div>
</div>
<!-- Modal -->
<div id="imageModal" class="modal">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content bg-transparent border-0">
<button id="modalClose" class="modal-button modal-close"></button>
<button id="modalPrev" class="modal-button modal-prev"></button>
<button id="modalNext" class="modal-button modal-next"></button>
<div class="modal-body">
<h5 id="modalFilename" class="modal-filename"></h5>
<img id="modalImage" src="" class="img-fluid">
</div>
{% endfor %}
{% endif %}
{% endwith %}
</div>
</div>
</div>
<hr>
<!-- MAIN CONTENT -->
{% block content %}{% endblock %}
<script>
document.addEventListener('DOMContentLoaded', () => {
const modal = document.getElementById('imageModal');
const modalImage = document.getElementById('modalImage');
const modalClose = document.getElementById('modalClose');
const modalPrev = document.getElementById('modalPrev');
const modalNext = document.getElementById('modalNext');
const modalFilename = document.getElementById('modalFilename');
const images = Array.from(document.querySelectorAll('.img-clickable'));
let currentIndex = -1;
function openModal(index) {
currentIndex = index;
const img = images[currentIndex];
modalImage.src = img.dataset.full;
modalFilename.textContent = img.dataset.filename || '';
modal.classList.add('active');
}
function closeModal() {
modal.classList.remove('active');
modalImage.src = '';
modalFilename.textContent = '';
currentIndex = -1;
}
function showNext() {
if (images.length === 0) return;
currentIndex = (currentIndex + 1) % images.length;
const img = images[currentIndex];
modalImage.src = img.dataset.full;
modalFilename.textContent = img.dataset.filename || '';
}
function showPrev() {
if (images.length === 0) return;
currentIndex = (currentIndex - 1 + images.length) % images.length;
const img = images[currentIndex];
modalImage.src = img.dataset.full;
modalFilename.textContent = img.dataset.filename || '';
}
images.forEach((img, index) => {
img.addEventListener('click', () => openModal(index));
});
modalClose.addEventListener('click', closeModal);
modalNext.addEventListener('click', showNext);
modalPrev.addEventListener('click', showPrev);
modal.addEventListener('click', (e) => {
if (e.target === modal) closeModal();
});
document.addEventListener('keydown', (e) => {
if (!modal.classList.contains('active')) return;
if (e.key === 'ArrowRight') showNext();
else if (e.key === 'ArrowLeft') showPrev();
else if (e.key === 'Escape') closeModal();
});
});
</script>
</body>
</html>
+25
View File
@@ -0,0 +1,25 @@
{% extends "layout.html" %}
{% block title %}Settings{% endblock %}
{% block content %}
<div class="container mt-4">
<h2>Image Management</h2>
<p>Use the options below to manage image data.</p>
<div class="mb-3">
<a href="{{ url_for('main.trigger_image_import') }}" class="btn btn-primary">
📥 Import Images
</a>
</div>
<div class="mb-3">
<form method="POST" action="{{ url_for('main.reset_db') }}"
onsubmit="return confirm('Are you sure you want to delete all image records?');">
<button type="submit" class="btn btn-danger">
🗑️ Reset Database
</button>
</form>
</div>
</div>
{% endblock %}