Du kannst nicht mehr als 25 Themen auswählen
Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
229 Zeilen
8.6 KiB
HTML
229 Zeilen
8.6 KiB
HTML
vor 3 Wochen
|
<!DOCTYPE html>
|
||
|
<html lang="de">
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
|
<title>Schreiberling</title>
|
||
|
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🪶</text></svg>">
|
||
|
<link href="/static/css/tharanor.form.css" type="text/css" rel="stylesheet">
|
||
|
<link href="/static/css/tharanor.letter.css" type="text/css" rel="stylesheet">
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>Schreiberling des Rates der Gilden</h1>
|
||
|
|
||
|
<form action="/generate" method="post">
|
||
|
<div class="form-grid">
|
||
|
<label for="senderSelect">Verfasser:</label>
|
||
|
<span>
|
||
|
<select name="sender" id="senderSelect">
|
||
|
{% for s in senders %}
|
||
|
<option value="{{ s.id }}">{{ s.name }}</option>
|
||
|
{% endfor %}
|
||
|
</select>
|
||
|
<button type="button" class="mini add" onclick="openModalAdd('senderModal')">✚</button>
|
||
|
<button type="button" class="mini edit" onclick="openModalEdit('sender')">✎</button>
|
||
|
</span>
|
||
|
|
||
|
<label for="stateSelect">Reich:</label>
|
||
|
<span>
|
||
|
<select id="stateSelect">
|
||
|
<option value="all">-- Alle --</option>
|
||
|
{% for s in states %}
|
||
|
<option value="{{ s.id }}">{{ s.name }}</option>
|
||
|
{% endfor %}
|
||
|
</select>
|
||
|
<button type="button" class="mini add" onclick="openModalAdd('stateModal')">✚</button>
|
||
|
<button type="button" class="mini edit" onclick="openModalEdit('state')">✎</button>
|
||
|
</span>
|
||
|
|
||
|
<label for="recipientSelect">Empfänger:</label>
|
||
|
<span>
|
||
|
<select name="recipient" id="recipientSelect">
|
||
|
{% for r in recipients %}
|
||
|
<option value="{{ r.id }}">{{ r.name }}</option>
|
||
|
{% endfor %}
|
||
|
</select>
|
||
|
<button type="button" class="mini add" onclick="openModalAdd('recipientModal')">✚</button>
|
||
|
<button type="button" class="mini edit" onclick="openModalEdit('recipient')">✎</button>
|
||
|
</span>
|
||
|
</div>
|
||
|
|
||
|
<label for="textInput">Brieftext:</label><br>
|
||
|
<textarea name="text" id="textInput"></textarea><br><br>
|
||
|
|
||
|
<button type="submit">Brief in Auftrag geben</button>
|
||
|
</form>
|
||
|
|
||
|
<!-- Sender Modal -->
|
||
|
<div id="senderModal" class="modal">
|
||
|
<div class="modal-content">
|
||
|
<h3 class="modal-add">Neuen Verfasser anlegen</h3>
|
||
|
<h3 class="modal-edit">Verfasser editieren</h3>
|
||
|
<form id="senderForm">
|
||
|
<input type="hidden" name="id">
|
||
|
<label>
|
||
|
Name:<br>
|
||
|
<input name="name" placeholder="Name" required>
|
||
|
</label>
|
||
|
<label>
|
||
|
Kuralie:<br>
|
||
|
<textarea name="kuralie" placeholder="Kuralie" rows="4"></textarea>
|
||
|
</label>
|
||
|
<label>
|
||
|
Siegel:<br>
|
||
|
<img id="siegelPreview" src="" height="100" alt="siegel"/>
|
||
|
<input type="file" name="siegel" required>
|
||
|
</label>
|
||
|
<label>
|
||
|
Signatur:<br>
|
||
|
<img id="signaturPreview" src="" width="300" alt="signatur"/>
|
||
|
<input type="file" name="signatur" required>
|
||
|
</label>
|
||
|
<button type="submit">Speichern</button>
|
||
|
<button type="button" onclick="closeModal('senderModal')">Abbrechen</button>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<!-- State Modal -->
|
||
|
<div id="stateModal" class="modal">
|
||
|
<div class="modal-content">
|
||
|
<h3 class="modal-add">Neues Reich anlegen</h3>
|
||
|
<h3 class="modal-edit">Reich editieren</h3>
|
||
|
<form id="stateForm">
|
||
|
<input type="hidden" name="id">
|
||
|
<label>
|
||
|
Name:<br>
|
||
|
<input name="name" placeholder="Name" required>
|
||
|
</label>
|
||
|
<button type="submit">Speichern</button>
|
||
|
<button type="button" onclick="closeModal('stateModal')">Abbrechen</button>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<!-- Recipient Modal -->
|
||
|
<div id="recipientModal" class="modal">
|
||
|
<div class="modal-content">
|
||
|
<h3 class="modal-add">Neuen Korrespondent anlegen</h3>
|
||
|
<h3 class="modal-edit">Korrespondent editieren</h3>
|
||
|
<form id="recipientForm">
|
||
|
<input type="hidden" name="id">
|
||
|
<label>
|
||
|
Name:<br>
|
||
|
<input name="name" placeholder="Name" required>
|
||
|
</label>
|
||
|
<label>
|
||
|
Kuralie:<br>
|
||
|
<textarea name="kuralie" placeholder="Kuralie" rows="4"></textarea>
|
||
|
</label>
|
||
|
<label>
|
||
|
Reich:<br>
|
||
|
<select name="state_id">
|
||
|
<option value="">-- Kein Reich --</option>
|
||
|
{% for state in states %}
|
||
|
<option value="{{ state.id }}">{{ state.name }}</option>
|
||
|
{% endfor %}
|
||
|
</select>
|
||
|
</label>
|
||
|
<button type="submit">Speichern</button>
|
||
|
<button type="button" onclick="closeModal('recipientModal')">Abbrechen</button>
|
||
|
</form>
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<script>
|
||
|
document.querySelectorAll(".modal-content form").forEach(f => f.addEventListener('submit', modalEvent));
|
||
|
|
||
|
function openModalAdd(id) {
|
||
|
document.getElementById(id).classList.add('active');
|
||
|
}
|
||
|
|
||
|
function openModalEdit(type) {
|
||
|
const select = document.getElementById(`${type}Select`);
|
||
|
const selected_id = select.value;
|
||
|
|
||
|
fetch(`/api/${type}s/${selected_id}`)
|
||
|
.then(res => res.json())
|
||
|
.then(x => {
|
||
|
const form = document.getElementById(`${type}Form`);
|
||
|
Object.entries(x)
|
||
|
.filter(([k]) => !["siegel", "signatur"].includes(k))
|
||
|
.forEach(([k, v]) => form[k].value = v);
|
||
|
if (type === "sender") {
|
||
|
document.getElementById('siegelPreview').src = `/static/uploads/${x.siegel}`;
|
||
|
document.getElementById('signaturPreview').src = `/static/uploads/${x.signatur}`;
|
||
|
}
|
||
|
document.getElementById(`${type}Modal`).classList.add('active', "edit");
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function closeModal(id) {
|
||
|
document.getElementById(id).getElementsByTagName("form")[0].reset()
|
||
|
document.getElementById(id).classList.remove('active', "edit");
|
||
|
}
|
||
|
|
||
|
function modalEvent(e) {
|
||
|
e.preventDefault();
|
||
|
const data = new FormData(e.target);
|
||
|
const modal = e.target.parentNode.parentNode;
|
||
|
const type = modal.id.replace("Modal", "");
|
||
|
const is_edit = modal.classList.contains("edit");
|
||
|
const id = data.get("id");
|
||
|
data.delete("id");
|
||
|
|
||
|
fetch(is_edit ? `/api/${type}s/${id}` : `/api/${type}s`, {
|
||
|
method: is_edit ? 'PUT' : 'POST',
|
||
|
body: data
|
||
|
}).then(res => res.json()).then(() => {
|
||
|
closeModal(`${type}Modal`);
|
||
|
refreshDropdown(type);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
document.getElementById('stateSelect').addEventListener('change', function () {
|
||
|
const stateId = this.value;
|
||
|
|
||
|
fetch(`/api/recipients?state_id=${stateId}`)
|
||
|
.then(response => response.json())
|
||
|
.then(data => {
|
||
|
const recipientSelect = document.getElementById('recipientSelect');
|
||
|
recipientSelect.innerHTML = '';
|
||
|
data.forEach(r => {
|
||
|
const option = document.createElement('option');
|
||
|
option.value = r.id;
|
||
|
option.textContent = r.name;
|
||
|
recipientSelect.appendChild(option);
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
function refreshDropdown(type) {
|
||
|
fetch(`/api/${type}s`)
|
||
|
.then(res => res.json())
|
||
|
.then(data => {
|
||
|
const select = document.getElementById(`${type}Select`);
|
||
|
const current = select.value;
|
||
|
select.innerHTML = (type === "state") ? '<option value="all">-- Alle --</option>' : '';
|
||
|
let modalSelect;
|
||
|
if (type === 'state') {
|
||
|
modalSelect = document.querySelector('#recipientModal select[name="state_id"]');
|
||
|
modalSelect.innerHTML = '<option value="">-- Kein Reich --</option>';
|
||
|
}
|
||
|
data.forEach(s => {
|
||
|
const opt = document.createElement('option');
|
||
|
opt.value = s.id;
|
||
|
opt.textContent = s.name;
|
||
|
select.appendChild(opt);
|
||
|
if (type === 'state') {
|
||
|
modalSelect.appendChild(opt.cloneNode(true));
|
||
|
}
|
||
|
});
|
||
|
select.value = current;
|
||
|
});
|
||
|
}
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|