import { $, api, esc, showError, renderHeader, renderFooter, isAdmin, prepareImage } from './common.js';
renderHeader('kooperationen');
renderFooter();
let coops = [];
let admin = false; // nur der Admin-Zugang darf anlegen, ändern, löschen
let editingId = null;
let imageData = null; // data:-URL des neu gewählten Titelbildes
const imgUrl = (c) => `/koop-img/${encodeURIComponent(c.image)}`;
// ---------- Soziale Medien ----------
const SOCIALS = [
{ key: 'website', label: 'Website', icon: '' },
{ key: 'instagram', label: 'Instagram', icon: '' },
{ key: 'youtube', label: 'YouTube', icon: '' },
{ key: 'tiktok', label: 'TikTok', icon: '' },
{ key: 'facebook', label: 'Facebook', icon: '' },
{ key: 'discord', label: 'Discord', icon: '' },
];
const icon = (s) => ``;
function socialsHtml(c) {
const links = SOCIALS.filter((s) => c.socials?.[s.key]);
return links.length
? links.map((s) => `${icon(s)}${s.label}`).join('')
: '
Keine Links eingetragen.
';
}
// Ohne Titelbild: Anfangsbuchstaben auf Flaggenblau
const initials = (name) => name.split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0]).join('').toUpperCase();
// ---------- Übersicht ----------
function renderOverview() {
$('#coop-empty').hidden = coops.length > 0;
$('#coop-empty-hint').textContent = admin
? 'Trag über „Kooperation hinzufügen“ die erste Gruppe ein.'
: 'Sobald der Admin eine Kooperation einträgt, erscheint sie hier.';
$('#coop-grid').innerHTML = coops.map((c) => `
${c.image ? `
})
` : `
${esc(initials(c.name))}`}
${esc(c.name)}
${c.leader ? `
Anführer: ${esc(c.leader)}
` : ''}
Ansehen
`).join('');
}
// ---------- Einzelansicht (#id) ----------
function renderDetail(c) {
document.title = `${c.name} – Kooperationen – HCRB`;
$('#detail-name').textContent = c.name;
const img = $('#detail-img');
img.hidden = !c.image;
if (c.image) img.src = imgUrl(c);
$('#detail-hero').classList.toggle('no-image', !c.image);
$('#detail-hero').dataset.initials = initials(c.name);
$('#detail-description').textContent = c.description || 'Noch keine Beschreibung.';
$('#detail-leader').textContent = c.leader || 'Nicht angegeben';
$('#detail-socials').innerHTML = socialsHtml(c);
$('#detail-admin').hidden = !admin;
}
function route() {
const id = location.hash.slice(1);
const coop = coops.find((c) => c.id === id);
$('#overview').hidden = !!coop;
$('#detail').hidden = !coop;
if (coop) {
renderDetail(coop);
scrollTo(0, 0);
} else {
document.title = 'Kooperationen – HCRB';
renderOverview();
}
}
addEventListener('hashchange', () => {
closeForm();
route();
});
$('#back-link').addEventListener('click', (e) => {
e.preventDefault();
history.pushState(null, '', location.pathname);
route();
});
// ---------- Formular ----------
function showPreview(src) {
$('#coop-preview').hidden = !src;
if (src) $('#coop-preview').src = src;
$('#drop-text').innerHTML = src
? 'Anderes Titelbild wählen'
: 'Titelbild auswählen
oder hierher ziehen · am besten ein breites Foto (Querformat)';
}
function openForm(coop) {
editingId = coop?.id ?? null;
imageData = null;
$('#coop-form').reset();
$('#coop-error').hidden = true;
$('#coop-form-title').textContent = coop ? 'Kooperation bearbeiten' : 'Kooperation hinzufügen';
$('#coop-name').value = coop?.name ?? '';
$('#coop-leader').value = coop?.leader ?? '';
$('#coop-description').value = coop?.description ?? '';
for (const s of SOCIALS) $(`#social-${s.key}`).value = coop?.socials?.[s.key] ?? '';
$('#remove-image-wrap').hidden = !coop?.image;
showPreview(coop?.image ? imgUrl(coop) : null);
$('#coop-form-card').hidden = false;
$('#coop-form-card').scrollIntoView({ behavior: 'smooth', block: 'start' });
$('#coop-name').focus({ preventScroll: true });
}
function closeForm() {
$('#coop-form-card').hidden = true;
editingId = null;
imageData = null;
}
async function pickFile(file) {
if (!file) return;
$('#coop-error').hidden = true;
try {
imageData = await prepareImage(file, 2000);
showPreview(imageData);
$('#coop-remove-image').checked = false;
} catch (err) {
imageData = null;
$('#coop-error').textContent = err.message || 'Das Bild konnte nicht gelesen werden.';
$('#coop-error').hidden = false;
}
}
$('#coop-file').addEventListener('change', (e) => pickFile(e.target.files[0]));
const drop = $('#dropzone');
drop.addEventListener('dragover', (e) => { e.preventDefault(); drop.classList.add('over'); });
drop.addEventListener('dragleave', () => drop.classList.remove('over'));
drop.addEventListener('drop', (e) => {
e.preventDefault();
drop.classList.remove('over');
pickFile(e.dataTransfer.files[0]);
});
$('#add-btn').addEventListener('click', () => openForm(null));
$('#coop-cancel').addEventListener('click', closeForm);
$('#detail-edit').addEventListener('click', () => openForm(coops.find((c) => c.id === location.hash.slice(1))));
$('#detail-delete').addEventListener('click', async () => {
const c = coops.find((x) => x.id === location.hash.slice(1));
if (!c || !confirm(`Kooperation „${c.name}“ wirklich löschen?`)) return;
try {
await api('DELETE', `/kooperationen/${c.id}`);
history.pushState(null, '', location.pathname);
await load();
} catch (err) {
showError(err);
}
});
$('#coop-form').addEventListener('submit', async (e) => {
e.preventDefault();
const error = $('#coop-error');
error.hidden = true;
const button = $('#coop-submit');
button.disabled = true;
try {
const body = {
name: $('#coop-name').value,
leader: $('#coop-leader').value,
description: $('#coop-description').value,
socials: Object.fromEntries(SOCIALS.map((s) => [s.key, $(`#social-${s.key}`).value])),
};
if (imageData) body.image = imageData;
else if ($('#coop-remove-image').checked) body.removeImage = true;
const saved = editingId
? await api('PUT', `/kooperationen/${editingId}`, body)
: await api('POST', '/kooperationen', body);
closeForm();
coops = await api('GET', '/kooperationen');
// Nach dem Speichern die Seite der Kooperation zeigen
if (location.hash.slice(1) === saved.id) route();
else location.hash = saved.id;
} catch (err) {
error.textContent = err.message;
error.hidden = false;
} finally {
button.disabled = false;
}
});
// ---------- Laden ----------
async function load() {
coops = await api('GET', '/kooperationen');
route();
}
admin = await isAdmin();
$('#add-btn').hidden = !admin;
showPreview(null);
await load().catch(showError);