Update web/templates/entry_edit.html
This commit is contained in:
parent
55a99ff430
commit
b6579fe08b
@ -3,167 +3,194 @@
|
||||
{% load static %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page">
|
||||
<!-- Top bar -->
|
||||
<div class="result-wrap">
|
||||
|
||||
<!-- Top bar: back + counter + clear Prev/Next -->
|
||||
<div class="result-toolbar">
|
||||
<div class="rt-left">
|
||||
<a class="btn btn-secondary" href="{% url 'entry_view' entry.id %}">← Back to Entry</a>
|
||||
<span class="rt-count">Editing: #{{ entry.id }}</span>
|
||||
<a class="btn btn-secondary" href="{% url 'search' %}">← Back to Search</a>
|
||||
{% if count %}
|
||||
<span class="rt-count">{{ position }} of {{ count }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="rt-right">
|
||||
<a class="btn" href="{% url 'entry_view' entry.id %}">Cancel</a>
|
||||
<button form="entry-edit-form" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Card -->
|
||||
<div class="card entry-form modern-form" style="padding: 24px;">
|
||||
<form id="entry-edit-form" method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="f-grid">
|
||||
<div class="f-row">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Subject</div>
|
||||
<div class="f-control">
|
||||
{{ form.subject }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row tall">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Illustration</div>
|
||||
<div class="f-control">
|
||||
{{ form.illustration }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row tall">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Application</div>
|
||||
<div class="f-control">
|
||||
{{ form.application }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Scripture</div>
|
||||
<div class="f-control">
|
||||
{{ form.scripture_raw }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Source</div>
|
||||
<div class="f-control">
|
||||
{{ form.source }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Talk Title</div>
|
||||
<div class="f-control">
|
||||
{{ form.talk_title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="f-row">
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Talk Number</div>
|
||||
<div class="f-control">
|
||||
{{ form.talk_number }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Combined row for Entry Code + Date Added + Date Edited -->
|
||||
<div class="f-row" style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px;">
|
||||
<div>
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Entry Code</div>
|
||||
<div class="f-control">
|
||||
{{ form.entry_code }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Date Added</div>
|
||||
<div class="f-control">
|
||||
{{ form.date_added }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="f-label" style="font-weight: 600; font-size: 1.05em;">Date Edited</div>
|
||||
<div class="f-control">
|
||||
{{ form.date_edited }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- bottom actions -->
|
||||
<div class="form-actions bottom-actions" style="margin-top: 20px;">
|
||||
<a class="btn btn-secondary" href="{% url 'entry_view' entry.id %}">Cancel</a>
|
||||
<button class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
<form method="get" action="{% url 'nav_prev' %}" class="inline">
|
||||
<!-- send current zero-based index (position-1); view will subtract 1 -->
|
||||
<input type="hidden" name="i" value="{{ position|add:'-1' }}">
|
||||
<button class="btn btn-lg" {% if position <= 1 %}disabled{% endif %}>‹ Prev</button>
|
||||
</form>
|
||||
<form method="get" action="{% url 'nav_next' %}" class="inline">
|
||||
<!-- send current zero-based index (position-1); view will add 1 -->
|
||||
<input type="hidden" name="i" value="{{ position|add:'-1' }}">
|
||||
<button class="btn btn-lg btn-primary" {% if position >= count %}disabled{% endif %}>Next ›</button>
|
||||
</form>
|
||||
|
||||
<!-- Share button (copies Illustration + two spaces + Application) -->
|
||||
<button id="share-btn" class="btn btn-lg btn-primary" type="button" title="Copy to clipboard" style="margin-left:6px;">
|
||||
<span style="display:flex;align-items:center;gap:6px;">
|
||||
<!-- iOS-like share icon (SVG) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
||||
viewBox="0 0 16 16" aria-hidden="true" focusable="false" fill="currentColor">
|
||||
<path d="M8 1a.5.5 0 0 1 .5.5V9a.5.5 0 0 1-1 0V1.5A.5.5 0 0 1 8 1z"/>
|
||||
<path d="M5.646 3.646a.5.5 0 0 1 .708 0L8 5.293l1.646-1.647a.5.5 0 0 1 .708.708L8.354 6.354a.5.5 0 0 1-.708 0L5.646 4.354a.5.5 0 0 1 0-.708z"/>
|
||||
<path d="M4.5 6A1.5 1.5 0 0 0 3 7.5v5A1.5 1.5 0 0 0 4.5 14h7A1.5 1.5 0 0 0 13 12.5v-5A1.5 1.5 0 0 0 11.5 6H10a.5.5 0 0 0 0 1h1.5a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-7a.5.5 0 0 1-.5-.5v-5a.5.5 0 0 1 .5-.5H6a.5.5 0 0 0 0-1H4.5z"/>
|
||||
</svg>
|
||||
Share
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{% if user.is_authenticated and user.is_staff %}
|
||||
<a class="btn btn-outline" href="{% url 'entry_edit' entry.id %}">Edit</a>
|
||||
<a class="btn btn-danger" href="{% url 'entry_delete' entry.id %}">Delete</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Talk title auto-fill & auto-date -->
|
||||
<!-- Main card -->
|
||||
<div class="result-card">
|
||||
<!-- SUBJECT pills (WOL-linked) -->
|
||||
<div class="subject-pills">
|
||||
{% if subject_list %}
|
||||
{% for s in subject_list %}
|
||||
<a
|
||||
class="chip chip-subject"
|
||||
href="https://wol.jw.org/en/wol/s/r1/lp-e?q={{ s }}"
|
||||
target="_blank" rel="noopener noreferrer"
|
||||
title="Search WOL for {{ s }}"
|
||||
>{{ s }}</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<span class="chip chip-muted">(no subject)</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- ILLUSTRATION -->
|
||||
<div class="section">
|
||||
<div class="section-label">Illustration</div>
|
||||
<div class="section-body lead-text" id="illustration-text">
|
||||
{{ entry.illustration|linebreaksbr|default:"—" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- APPLICATION -->
|
||||
<div class="section">
|
||||
<div class="section-label">Application</div>
|
||||
<div class="section-body lead-text" id="application-text">
|
||||
{{ entry.application|linebreaksbr|default:"—" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Meta (smaller) -->
|
||||
<div class="meta-grid">
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Source</div>
|
||||
<div class="meta-value">
|
||||
{% if entry.source %}
|
||||
{% with s=entry.source %}
|
||||
{% with sl=s|lower %}
|
||||
{% if sl|slice:":2" == "wp" or sl|slice:":2" == "ws" or sl|slice:":2" == "yb" or sl|slice:":2" == "km" or sl|slice:":3" == "mwb" or sl|slice:":1" == "w" or sl|slice:":1" == "g" or sl|slice:":2" == "ap" or sl|slice:":3" == "apf" or sl|slice:":2" == "be" or sl|slice:":2" == "bh" or sl|slice:":2" == "br" or sl|slice:":2" == "bt" or sl|slice:":3" == "btg" or sl|slice:":2" == "cf" or sl|slice:":2" == "cl" or sl|slice:":2" == "ct" or sl|slice:":2" == "dp" or sl|slice:":2" == "fg" or sl|slice:":2" == "fy" or sl|slice:":2" == "gt" or sl|slice:":2" == "hb" or sl|slice:":2" == "im" or sl|slice:":2" == "ip" or sl|slice:":2" == "it" or sl|slice:":2" == "jv" or sl|slice:":2" == "ka" or sl|slice:":2" == "kj" or sl|slice:":2" == "kl" or sl|slice:":2" == "lf" or sl|slice:":3" == "lff" or sl|slice:":2" == "ll" or sl|slice:":2" == "ly" or sl|slice:":2" == "my" or sl|slice:":2" == "od" or sl|slice:":2" == "pe" or sl|slice:":2" == "po" or sl|slice:":2" == "pt" or sl|slice:":2" == "rr" or sl|slice:":2" == "rs" or sl|slice:":2" == "sg" or sl|slice:":2" == "sh" or sl|slice:":2" == "si" or sl|slice:":2" == "td" or sl|slice:":2" == "tp" or sl|slice:":2" == "tr" or sl|slice:":2" == "ts" or sl|slice:":2" == "un" %}
|
||||
<a class="chip chip-link"
|
||||
href="https://wol.jw.org/en/wol/l/r1/lp-e?q={{ s|urlencode }}"
|
||||
target="_blank" rel="noopener noreferrer">{{ s }}</a>
|
||||
{% else %}
|
||||
<a class="chip chip-link"
|
||||
href="https://www.google.com/search?q={{ s|urlencode }}"
|
||||
target="_blank" rel="noopener noreferrer">{{ s }}</a>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% else %}—{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Scripture</div>
|
||||
<div class="meta-value">
|
||||
{% if scripture_list %}
|
||||
{% for sc in scripture_list %}
|
||||
<a class="chip chip-link"
|
||||
href="https://wol.jw.org/en/wol/l/r1/lp-e?q={{ sc|urlencode }}"
|
||||
target="_blank" rel="noopener noreferrer">{{ sc }}</a>
|
||||
{% endfor %}
|
||||
{% else %}—{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Code</div>
|
||||
<div class="meta-value">{{ entry.entry_code|default:"—" }}</div>
|
||||
</div>
|
||||
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Talk</div>
|
||||
<div class="meta-value">
|
||||
{% if entry.talk_title %}{{ entry.talk_title }}{% else %}—{% endif %}
|
||||
{% if entry.talk_number %}<span class="chip chip-muted">#{{ entry.talk_number }}</span>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="meta-item">
|
||||
<div class="meta-label">Dates</div>
|
||||
<div class="meta-value small">
|
||||
{% if entry.date_added %}Added: {{ entry.date_added }}{% else %}Added: —{% endif %}
|
||||
{% if entry.date_edited %} • Edited: {{ entry.date_edited }}{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Toast for copy confirmation -->
|
||||
<div id="copy-toast"
|
||||
style="position:fixed;bottom:20px;left:50%;transform:translateX(-50%);
|
||||
background:#333;color:#fff;padding:10px 16px;border-radius:6px;
|
||||
font-size:14px;display:none;z-index:9999;">
|
||||
The Illustration was copied to the clipboard
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.subject-pills{
|
||||
display:flex;
|
||||
flex-wrap:wrap;
|
||||
gap:10px;
|
||||
margin:0 0 10px;
|
||||
}
|
||||
.chip-subject{
|
||||
font-weight:700;
|
||||
font-size:16px;
|
||||
padding:8px 14px;
|
||||
border-radius:999px;
|
||||
background:#eef5fc;
|
||||
border:1px solid #d7e6f7;
|
||||
color:#0f172a;
|
||||
text-decoration:none;
|
||||
text-transform: capitalize; /* Capitalize each word */
|
||||
}
|
||||
.chip-subject:hover{
|
||||
background:#e2effc;
|
||||
border-color:#c9def5;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Copy Illustration + two spaces + Application
|
||||
(function () {
|
||||
const talksUrl = "{% static 'talks.json' %}";
|
||||
|
||||
function wireAutofill(talkMap) {
|
||||
const numberEl = document.getElementById("id_talk_number");
|
||||
const titleEl = document.getElementById("id_talk_title");
|
||||
if (!numberEl || !titleEl) return;
|
||||
|
||||
const isEffectivelyEmpty = (s) => {
|
||||
const t = (s || "").trim();
|
||||
return t === "" || t === "-" || t === "—";
|
||||
};
|
||||
|
||||
let userTyped = false;
|
||||
|
||||
titleEl.addEventListener("input", () => {
|
||||
userTyped = !isEffectivelyEmpty(titleEl.value);
|
||||
if (!userTyped) titleEl.dataset.autofilled = "0";
|
||||
const btn = document.getElementById('share-btn');
|
||||
if (!btn) return;
|
||||
btn.addEventListener('click', function () {
|
||||
const ill = (document.getElementById('illustration-text')?.innerText || '').trim();
|
||||
const app = (document.getElementById('application-text')?.innerText || '').trim();
|
||||
const text = ill + ' ' + app; // two spaces between
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
const toast = document.getElementById('copy-toast');
|
||||
if (!toast) return;
|
||||
toast.style.display = 'block';
|
||||
setTimeout(() => { toast.style.display = 'none'; }, 5000);
|
||||
}).catch(err => {
|
||||
alert('Failed to copy: ' + err);
|
||||
});
|
||||
});
|
||||
|
||||
function maybeAutofill() {
|
||||
const n = numberEl.value;
|
||||
const mapped = talkMap && talkMap[n] ? talkMap[n] : "";
|
||||
|
||||
if (!userTyped) {
|
||||
if (mapped) {
|
||||
titleEl.value = mapped;
|
||||
titleEl.dataset.autofilled = "1";
|
||||
} else if (titleEl.dataset.autofilled === "1") {
|
||||
titleEl.value = "";
|
||||
titleEl.dataset.autofilled = "0";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numberEl.addEventListener("change", maybeAutofill);
|
||||
|
||||
if (isEffectivelyEmpty(titleEl.value)) {
|
||||
userTyped = false;
|
||||
maybeAutofill();
|
||||
} else {
|
||||
userTyped = true;
|
||||
}
|
||||
}
|
||||
|
||||
fetch(talksUrl, {cache: "no-store"})
|
||||
.then(r => r.ok ? r.json() : {})
|
||||
.then(map => wireAutofill(map))
|
||||
.catch(() => wireAutofill({}));
|
||||
|
||||
// Auto-fill today's date for Date Edited if empty
|
||||
const dateEditedEl = document.getElementById("id_date_edited");
|
||||
if (dateEditedEl && !dateEditedEl.value) {
|
||||
const today = new Date();
|
||||
const yyyy = today.getFullYear();
|
||||
const mm = String(today.getMonth() + 1).padStart(2, '0');
|
||||
const dd = String(today.getDate()).padStart(2, '0');
|
||||
dateEditedEl.value = `${yyyy}-${mm}-${dd}`;
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue
Block a user