feat(ui): add landing page with random public postcards for unauthenticated visitors
This commit is contained in:
74
app/templates/index.html
Normal file
74
app/templates/index.html
Normal file
@@ -0,0 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}{{ 'brand'|t(lang) }}{% endblock %}
|
||||
{% block nav %}
|
||||
<nav class="navbar">
|
||||
<a href="/" class="nav-brand">{{ 'brand'|t(lang) }}</a>
|
||||
<div class="nav-links">
|
||||
<div class="lang-switcher" id="langSwitcher">
|
||||
<button type="button" class="lang-globe" onclick="document.getElementById('langDropdown').classList.toggle('show')">🌐</button>
|
||||
<div class="lang-dropdown" id="langDropdown">
|
||||
{% for code, name in available_languages.items() %}
|
||||
<a href="/?lang={{ code }}" class="lang-option {% if lang == code %}active{% endif %}">{{ name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<a href="/login" class="btn btn-primary" style="margin-left:.5rem">{{ 'index.go_login'|t(lang) }}</a>
|
||||
</div>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="section-header">
|
||||
<h1>📮 {{ 'index.title'|t(lang) }}</h1>
|
||||
<p style="color:var(--text-muted);margin-top:.25rem">{{ 'index.subtitle'|t(lang) }}</p>
|
||||
</div>
|
||||
|
||||
{% if postcards %}
|
||||
<div class="showcase-grid">
|
||||
{% for pc in postcards %}
|
||||
<div class="showcase-card" data-front="{{ pc.image_front or '' }}" data-number="{{ pc.card_number }}" onclick="openLightbox(this)">
|
||||
{% if pc.image_front %}
|
||||
<img src="{{ pc.image_front }}" alt="" class="showcase-card-img" loading="lazy">
|
||||
{% else %}
|
||||
<div class="showcase-card-img placeholder-img">📷</div>
|
||||
{% endif %}
|
||||
<div class="showcase-card-body">
|
||||
<strong>{{ pc.card_number }}</strong>
|
||||
<div class="showcase-card-meta">
|
||||
<span>{{ pc.country|flag }} {{ pc.country or '' }}</span>
|
||||
{% if pc.send_time %}<span>{{ pc.send_time.strftime('%Y-%m-%d') }}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<p>{{ 'index.empty'|t(lang) }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Lightbox -->
|
||||
<div id="lightbox" class="lightbox" onclick="closeLightbox()" style="display:none">
|
||||
<div class="lightbox-inner" onclick="event.stopPropagation()">
|
||||
<button class="lightbox-close" onclick="closeLightbox()">×</button>
|
||||
<img id="lightbox-img" src="" alt="">
|
||||
<div id="lightbox-number" class="lightbox-number"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function openLightbox(el) {
|
||||
var src = el.getAttribute('data-front');
|
||||
if (!src) return;
|
||||
document.getElementById('lightbox-img').src = src;
|
||||
document.getElementById('lightbox-number').textContent = el.getAttribute('data-number');
|
||||
document.getElementById('lightbox').style.display = 'flex';
|
||||
}
|
||||
function closeLightbox() {
|
||||
document.getElementById('lightbox').style.display = 'none';
|
||||
}
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') closeLightbox();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user