2026-04-06 15:21:18 -04:00
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="en" data-theme="light">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="utf-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
|
<title>{% block title %}PI Weekly{% endblock %} — Plymouth Independent</title>
|
2026-04-06 18:40:04 -04:00
|
|
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>📰</text></svg>">
|
2026-04-06 15:21:18 -04:00
|
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
|
|
|
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
|
|
|
</head>
|
|
|
|
|
<body>
|
|
|
|
|
<nav class="container">
|
|
|
|
|
<ul>
|
|
|
|
|
<li><a href="/" class="brand">PI Weekly</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
<ul>
|
2026-04-06 17:41:21 -04:00
|
|
|
<li><a href="/">Dashboard</a></li>
|
2026-04-06 15:21:18 -04:00
|
|
|
<li><a href="/articles">Articles</a></li>
|
|
|
|
|
<li><a href="/publish">Publish</a></li>
|
|
|
|
|
<li><a href="/issues">Issues</a></li>
|
|
|
|
|
<li><a href="/settings">Settings</a></li>
|
|
|
|
|
</ul>
|
|
|
|
|
</nav>
|
|
|
|
|
<main class="container">
|
|
|
|
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
|
|
|
|
{% if messages %}
|
|
|
|
|
{% for category, message in messages %}
|
|
|
|
|
<div role="alert" {% if category == 'error' %}class="pico-background-red-500"{% endif %}>
|
|
|
|
|
{{ message }}
|
|
|
|
|
</div>
|
|
|
|
|
{% endfor %}
|
|
|
|
|
{% endif %}
|
|
|
|
|
{% endwith %}
|
|
|
|
|
|
|
|
|
|
{% block content %}{% endblock %}
|
|
|
|
|
</main>
|
|
|
|
|
<footer class="container">
|
|
|
|
|
<small>PI Weekly Newspaper Generator</small>
|
|
|
|
|
</footer>
|
2026-04-06 18:40:04 -04:00
|
|
|
<dialog id="confirm-dialog">
|
|
|
|
|
<article>
|
|
|
|
|
<header>
|
|
|
|
|
<button aria-label="Close" rel="prev" onclick="closeConfirm()"></button>
|
|
|
|
|
<p><strong id="confirm-title">Confirm</strong></p>
|
|
|
|
|
</header>
|
|
|
|
|
<p id="confirm-message"></p>
|
|
|
|
|
<footer>
|
|
|
|
|
<button class="secondary" onclick="closeConfirm()">Cancel</button>
|
|
|
|
|
<button id="confirm-ok" onclick="submitConfirm()">Confirm</button>
|
|
|
|
|
</footer>
|
|
|
|
|
</article>
|
|
|
|
|
</dialog>
|
|
|
|
|
<script>
|
|
|
|
|
let _confirmTarget = null;
|
|
|
|
|
function confirmAction(message, formOrEl, title) {
|
|
|
|
|
_confirmTarget = formOrEl;
|
|
|
|
|
document.getElementById('confirm-title').textContent = title || 'Confirm';
|
|
|
|
|
document.getElementById('confirm-message').textContent = message;
|
|
|
|
|
const btn = document.getElementById('confirm-ok');
|
|
|
|
|
btn.className = '';
|
|
|
|
|
if (formOrEl.dataset.confirmDanger) {
|
|
|
|
|
btn.className = 'btn-danger-fill';
|
|
|
|
|
}
|
|
|
|
|
const dialog = document.getElementById('confirm-dialog');
|
|
|
|
|
document.documentElement.classList.add('modal-is-open', 'modal-is-opening');
|
|
|
|
|
dialog.showModal();
|
|
|
|
|
setTimeout(() => document.documentElement.classList.remove('modal-is-opening'), 200);
|
|
|
|
|
}
|
|
|
|
|
function closeConfirm() {
|
|
|
|
|
const dialog = document.getElementById('confirm-dialog');
|
|
|
|
|
document.documentElement.classList.add('modal-is-closing');
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
dialog.close();
|
|
|
|
|
document.documentElement.classList.remove('modal-is-open', 'modal-is-closing');
|
|
|
|
|
_confirmTarget = null;
|
|
|
|
|
}, 200);
|
|
|
|
|
}
|
|
|
|
|
function submitConfirm() {
|
|
|
|
|
if (_confirmTarget) _confirmTarget.submit();
|
|
|
|
|
}
|
|
|
|
|
</script>
|
2026-04-06 15:21:18 -04:00
|
|
|
{% block scripts %}{% endblock %}
|
|
|
|
|
</body>
|
|
|
|
|
</html>
|