Chapter-Daten auf separaten data-Branch ausgelagert
chapters/ lag bisher im main-Branch, aus dem sich jede lokale Installation bedient (z.B. per ZIP-Download) — dadurch bekam jedes Chapter beim Einrichten die Mitgliederdaten aller anderen Chapter mit, obwohl die App diese Daten ohnehin nie lokal liest, sondern immer live über die Gitea-API holt. Alle Lese-/Schreibzugriffe auf chapters/* laufen jetzt gegen den neuen data-Branch (giteaDataUrl / giteaAuthUrl(..., 'data') inkl. branch: 'data' in den Schreib-Bodies). App-Code (index.html, admin.html, version.json) bleibt weiterhin auf main. chapters/ ist aus main entfernt (lokal weiterhin vorhanden, per .gitignore ausgeschlossen) und liegt vollständig auf dem neuen data-Branch.
1
.gitignore
vendored
@@ -4,3 +4,4 @@ screenshots/
|
|||||||
anleitung.html
|
anleitung.html
|
||||||
BNI-Vorstellungsrunde-Anleitung.pdf
|
BNI-Vorstellungsrunde-Anleitung.pdf
|
||||||
start-*.html
|
start-*.html
|
||||||
|
chapters/
|
||||||
|
|||||||
57
admin.html
@@ -380,7 +380,8 @@ const GITEA_RAW = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellun
|
|||||||
const GITEA_API = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde';
|
const GITEA_API = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde';
|
||||||
const CHAPTER_CONFIG_KEY = 'bni-active-chapter';
|
const CHAPTER_CONFIG_KEY = 'bni-active-chapter';
|
||||||
function giteaUrl(path) { return `${GITEA_RAW}/${path}?ref=main`; }
|
function giteaUrl(path) { return `${GITEA_RAW}/${path}?ref=main`; }
|
||||||
function giteaAuthUrl(path, token) { return `${GITEA_API}/contents/${path}?token=${encodeURIComponent(token)}`; }
|
function giteaDataUrl(path) { return `${GITEA_RAW}/${path}?ref=data`; }
|
||||||
|
function giteaAuthUrl(path, token, ref) { return `${GITEA_API}/contents/${path}?token=${encodeURIComponent(token)}${ref ? '&ref=' + ref : ''}`; }
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// CHAPTER CONFIG
|
// CHAPTER CONFIG
|
||||||
@@ -577,7 +578,7 @@ async function openImportFromChapter() {
|
|||||||
const listEl = document.getElementById('import-chapter-select-list');
|
const listEl = document.getElementById('import-chapter-select-list');
|
||||||
listEl.innerHTML = '<div style="color:var(--muted);font-size:0.85rem;">Lade Chapter…</div>';
|
listEl.innerHTML = '<div style="color:var(--muted);font-size:0.85rem;">Lade Chapter…</div>';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${GITEA_API}/contents/chapters?ref=main`);
|
const res = await fetch(`${GITEA_API}/contents/chapters?ref=data`);
|
||||||
const items = await res.json();
|
const items = await res.json();
|
||||||
const chapters = Array.isArray(items) ? items.filter(i => i.type === 'dir') : [];
|
const chapters = Array.isArray(items) ? items.filter(i => i.type === 'dir') : [];
|
||||||
if (!chapters.length) { listEl.innerHTML = '<div style="color:var(--muted);">Keine anderen Chapter gefunden.</div>'; return; }
|
if (!chapters.length) { listEl.innerHTML = '<div style="color:var(--muted);">Keine anderen Chapter gefunden.</div>'; return; }
|
||||||
@@ -585,7 +586,7 @@ async function openImportFromChapter() {
|
|||||||
for (const ch of chapters) {
|
for (const ch of chapters) {
|
||||||
if (activeChapter && ch.name === activeChapter.code) continue;
|
if (activeChapter && ch.name === activeChapter.code) continue;
|
||||||
try {
|
try {
|
||||||
const cfgRes = await fetch(giteaUrl(`chapters/${ch.name}/config.json`), { cache: 'no-store' });
|
const cfgRes = await fetch(giteaDataUrl(`chapters/${ch.name}/config.json`), { cache: 'no-store' });
|
||||||
const cfg = cfgRes.ok ? await cfgRes.json() : {};
|
const cfg = cfgRes.ok ? await cfgRes.json() : {};
|
||||||
const btn = document.createElement('div');
|
const btn = document.createElement('div');
|
||||||
btn.className = 'chapter-item';
|
btn.className = 'chapter-item';
|
||||||
@@ -611,7 +612,7 @@ async function loadChapterMembersForImport(code, chapterName) {
|
|||||||
const listEl = document.getElementById('import-member-list');
|
const listEl = document.getElementById('import-member-list');
|
||||||
listEl.innerHTML = '<div style="padding:12px;color:var(--muted);">Lade Mitglieder…</div>';
|
listEl.innerHTML = '<div style="padding:12px;color:var(--muted);">Lade Mitglieder…</div>';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${code}/members.json`));
|
const res = await fetch(giteaDataUrl(`chapters/${code}/members.json`));
|
||||||
if (!res.ok) { listEl.innerHTML = '<div style="padding:12px;color:#dc2626;">Keine Mitglieder gefunden.</div>'; return; }
|
if (!res.ok) { listEl.innerHTML = '<div style="padding:12px;color:#dc2626;">Keine Mitglieder gefunden.</div>'; return; }
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const members = data.members || [];
|
const members = data.members || [];
|
||||||
@@ -669,11 +670,11 @@ async function uploadSvToGitea() {
|
|||||||
const path = `chapters/${activeChapter.code}/stammvertreter.json`;
|
const path = `chapters/${activeChapter.code}/stammvertreter.json`;
|
||||||
try {
|
try {
|
||||||
let sha = null;
|
let sha = null;
|
||||||
const shaRes = await fetch(giteaAuthUrl(path, token));
|
const shaRes = await fetch(giteaAuthUrl(path, token, 'data'));
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
const body = { message: 'Stammvertreter aktualisiert', content };
|
const body = { message: 'Stammvertreter aktualisiert', content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
const res = await fetch(giteaAuthUrl(path, token), { method: sha?'PUT':'POST', headers: { 'Content-Type':'application/json' }, body: JSON.stringify(body) });
|
const res = await fetch(giteaAuthUrl(path, token, 'data'), { method: sha?'PUT':'POST', headers: { 'Content-Type':'application/json' }, body: JSON.stringify(body) });
|
||||||
if (res.ok) { statusEl.textContent = `✓ ${list.length} Stammvertreter gesichert`; statusEl.style.color = 'var(--success)'; }
|
if (res.ok) { statusEl.textContent = `✓ ${list.length} Stammvertreter gesichert`; statusEl.style.color = 'var(--success)'; }
|
||||||
else { statusEl.textContent = 'Fehler beim Upload.'; statusEl.style.color = '#dc2626'; }
|
else { statusEl.textContent = 'Fehler beim Upload.'; statusEl.style.color = '#dc2626'; }
|
||||||
} catch(e) { statusEl.textContent = 'Verbindungsfehler.'; statusEl.style.color = '#dc2626'; }
|
} catch(e) { statusEl.textContent = 'Verbindungsfehler.'; statusEl.style.color = '#dc2626'; }
|
||||||
@@ -683,7 +684,7 @@ async function downloadSvFromGitea() {
|
|||||||
const statusEl = document.getElementById('sv-sync-status');
|
const statusEl = document.getElementById('sv-sync-status');
|
||||||
statusEl.textContent = 'Lade…'; statusEl.style.color = 'var(--muted)';
|
statusEl.textContent = 'Lade…'; statusEl.style.color = 'var(--muted)';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/stammvertreter.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/stammvertreter.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) { statusEl.textContent = 'Keine Daten auf Server.'; statusEl.style.color = 'var(--muted)'; return; }
|
if (!res.ok) { statusEl.textContent = 'Keine Daten auf Server.'; statusEl.style.color = 'var(--muted)'; return; }
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (data.substitutes) { saveStammvertreter(data.substitutes); renderSvList(); statusEl.textContent = `✓ ${data.substitutes.length} Stammvertreter geladen`; statusEl.style.color = 'var(--success)'; }
|
if (data.substitutes) { saveStammvertreter(data.substitutes); renderSvList(); statusEl.textContent = `✓ ${data.substitutes.length} Stammvertreter geladen`; statusEl.style.color = 'var(--success)'; }
|
||||||
@@ -780,7 +781,7 @@ async function fetchMembersAdmin() {
|
|||||||
const statusEl = document.getElementById('members-status');
|
const statusEl = document.getElementById('members-status');
|
||||||
statusEl.textContent = 'Lade vom Server…'; statusEl.style.color = 'var(--muted)';
|
statusEl.textContent = 'Lade vom Server…'; statusEl.style.color = 'var(--muted)';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/members.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/members.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) { statusEl.textContent = 'Keine Mitglieder auf Server.'; return; }
|
if (!res.ok) { statusEl.textContent = 'Keine Mitglieder auf Server.'; return; }
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (!data.members || !data.members.length) { statusEl.textContent = 'Liste ist leer.'; return; }
|
if (!data.members || !data.members.length) { statusEl.textContent = 'Liste ist leer.'; return; }
|
||||||
@@ -817,14 +818,14 @@ async function uploadMembersAdmin() {
|
|||||||
const data = { lastUpdated: new Date().toISOString().slice(0,10), members };
|
const data = { lastUpdated: new Date().toISOString().slice(0,10), members };
|
||||||
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
||||||
const path = `chapters/${activeChapter.code}/members.json`;
|
const path = `chapters/${activeChapter.code}/members.json`;
|
||||||
const url = giteaAuthUrl(path, token);
|
const url = giteaAuthUrl(path, token, 'data');
|
||||||
console.log('[Upload] URL:', url);
|
console.log('[Upload] URL:', url);
|
||||||
statusEl.textContent = 'Prüfe SHA…';
|
statusEl.textContent = 'Prüfe SHA…';
|
||||||
let sha = null;
|
let sha = null;
|
||||||
const shaRes = await fetch(url);
|
const shaRes = await fetch(url);
|
||||||
console.log('[Upload] SHA-Status:', shaRes.status);
|
console.log('[Upload] SHA-Status:', shaRes.status);
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
const body = { message:`Mitglieder aktualisiert ${new Date().toLocaleDateString('de')}`, content };
|
const body = { message:`Mitglieder aktualisiert ${new Date().toLocaleDateString('de')}`, content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
statusEl.textContent = sha ? 'Aktualisiere…' : 'Erstelle…';
|
statusEl.textContent = sha ? 'Aktualisiere…' : 'Erstelle…';
|
||||||
const res = await fetch(url, { method:sha?'PUT':'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(body) });
|
const res = await fetch(url, { method:sha?'PUT':'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify(body) });
|
||||||
@@ -919,7 +920,7 @@ function editAgendaItem(id) {
|
|||||||
};
|
};
|
||||||
thumb.onload = () => { if (thumbHint) thumbHint.style.display = 'none'; };
|
thumb.onload = () => { if (thumbHint) thumbHint.style.display = 'none'; };
|
||||||
if (thumbHint) thumbHint.style.display = 'none';
|
if (thumbHint) thumbHint.style.display = 'none';
|
||||||
thumb.src = it.imagePath.startsWith('http') ? it.imagePath : giteaUrl(`chapters/${activeChapter.code}/${it.imagePath}`);
|
thumb.src = it.imagePath.startsWith('http') ? it.imagePath : giteaDataUrl(`chapters/${activeChapter.code}/${it.imagePath}`);
|
||||||
thumb.style.display = 'block';
|
thumb.style.display = 'block';
|
||||||
} else {
|
} else {
|
||||||
thumb.style.display = 'none';
|
thumb.style.display = 'none';
|
||||||
@@ -963,11 +964,11 @@ function handleAgendaImageFile(input) {
|
|||||||
|
|
||||||
async function uploadAgendaImage(path, dataUrl, token) {
|
async function uploadAgendaImage(path, dataUrl, token) {
|
||||||
const content = dataUrl.split(',')[1];
|
const content = dataUrl.split(',')[1];
|
||||||
const url = giteaAuthUrl(path, token);
|
const url = giteaAuthUrl(path, token, 'data');
|
||||||
let sha = null;
|
let sha = null;
|
||||||
const shaRes = await fetch(url);
|
const shaRes = await fetch(url);
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
const body = { message: `Agenda-Bild aktualisiert ${new Date().toLocaleDateString('de')}`, content };
|
const body = { message: `Agenda-Bild aktualisiert ${new Date().toLocaleDateString('de')}`, content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
const res = await fetch(url, { method: sha ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
const res = await fetch(url, { method: sha ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
||||||
if (!res.ok) { const t = await res.text(); throw new Error(`${res.status}: ${t.slice(0, 80)}`); }
|
if (!res.ok) { const t = await res.text(); throw new Error(`${res.status}: ${t.slice(0, 80)}`); }
|
||||||
@@ -1047,7 +1048,7 @@ async function fetchAgendaAdmin() {
|
|||||||
const statusEl = document.getElementById('agenda-status');
|
const statusEl = document.getElementById('agenda-status');
|
||||||
statusEl.textContent = 'Lade vom Server…'; statusEl.style.color = 'var(--muted)';
|
statusEl.textContent = 'Lade vom Server…'; statusEl.style.color = 'var(--muted)';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/agenda.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/agenda.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) { statusEl.textContent = 'Noch keine Agenda auf dem Server.'; return; }
|
if (!res.ok) { statusEl.textContent = 'Noch keine Agenda auf dem Server.'; return; }
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
const state = loadState();
|
const state = loadState();
|
||||||
@@ -1068,11 +1069,11 @@ async function uploadAgendaAdmin() {
|
|||||||
const data = { items: state.agendaCatalog || [] };
|
const data = { items: state.agendaCatalog || [] };
|
||||||
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
||||||
const path = `chapters/${activeChapter.code}/agenda.json`;
|
const path = `chapters/${activeChapter.code}/agenda.json`;
|
||||||
const url = giteaAuthUrl(path, token);
|
const url = giteaAuthUrl(path, token, 'data');
|
||||||
let sha = null;
|
let sha = null;
|
||||||
const shaRes = await fetch(url);
|
const shaRes = await fetch(url);
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
const body = { message: `Agenda aktualisiert ${new Date().toLocaleDateString('de')}`, content };
|
const body = { message: `Agenda aktualisiert ${new Date().toLocaleDateString('de')}`, content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
const res = await fetch(url, { method: sha ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
const res = await fetch(url, { method: sha ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
|
||||||
if (res.ok) { statusEl.textContent = `✓ ${data.items.length} Agenda-Punkte hochgeladen`; statusEl.style.color = 'var(--success)'; }
|
if (res.ok) { statusEl.textContent = `✓ ${data.items.length} Agenda-Punkte hochgeladen`; statusEl.style.color = 'var(--success)'; }
|
||||||
@@ -1089,16 +1090,16 @@ async function loadAllChapters() {
|
|||||||
const container = document.getElementById('all-chapters-list');
|
const container = document.getElementById('all-chapters-list');
|
||||||
container.innerHTML = '<div style="color:var(--muted);font-size:0.85rem;">Lade…</div>';
|
container.innerHTML = '<div style="color:var(--muted);font-size:0.85rem;">Lade…</div>';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${GITEA_API}/contents/chapters?ref=main`);
|
const res = await fetch(`${GITEA_API}/contents/chapters?ref=data`);
|
||||||
const items = await res.json();
|
const items = await res.json();
|
||||||
const chapters = Array.isArray(items) ? items.filter(i => i.type === 'dir') : [];
|
const chapters = Array.isArray(items) ? items.filter(i => i.type === 'dir') : [];
|
||||||
_allChaptersData = [];
|
_allChaptersData = [];
|
||||||
container.innerHTML = '';
|
container.innerHTML = '';
|
||||||
for (const ch of chapters) {
|
for (const ch of chapters) {
|
||||||
try {
|
try {
|
||||||
const cfgRes = await fetch(giteaUrl(`chapters/${ch.name}/config.json`), { cache: 'no-store' });
|
const cfgRes = await fetch(giteaDataUrl(`chapters/${ch.name}/config.json`), { cache: 'no-store' });
|
||||||
const cfg = cfgRes.ok ? await cfgRes.json() : {};
|
const cfg = cfgRes.ok ? await cfgRes.json() : {};
|
||||||
const membersRes = await fetch(giteaUrl(`chapters/${ch.name}/members.json`));
|
const membersRes = await fetch(giteaDataUrl(`chapters/${ch.name}/members.json`));
|
||||||
const membersData = membersRes.ok ? await membersRes.json() : {};
|
const membersData = membersRes.ok ? await membersRes.json() : {};
|
||||||
_allChaptersData.push({ code: ch.name, cfg });
|
_allChaptersData.push({ code: ch.name, cfg });
|
||||||
const isEnabled = !!cfg.memberCoordinatorReport;
|
const isEnabled = !!cfg.memberCoordinatorReport;
|
||||||
@@ -1227,18 +1228,18 @@ async function toggleCoordinatorReport(code, currentEnabled) {
|
|||||||
const token = getAdminToken();
|
const token = getAdminToken();
|
||||||
if (!token) { alert('Bitte Admin-Token in den Einstellungen eintragen.'); return; }
|
if (!token) { alert('Bitte Admin-Token in den Einstellungen eintragen.'); return; }
|
||||||
try {
|
try {
|
||||||
const cfgRes = await fetch(giteaUrl(`chapters/${code}/config.json`), { cache: 'no-store' });
|
const cfgRes = await fetch(giteaDataUrl(`chapters/${code}/config.json`), { cache: 'no-store' });
|
||||||
if (!cfgRes.ok) { alert('Config nicht gefunden.'); return; }
|
if (!cfgRes.ok) { alert('Config nicht gefunden.'); return; }
|
||||||
const cfg = await cfgRes.json();
|
const cfg = await cfgRes.json();
|
||||||
const shaRes = await fetch(giteaAuthUrl(`chapters/${code}/config.json`, token));
|
const shaRes = await fetch(giteaAuthUrl(`chapters/${code}/config.json`, token, 'data'));
|
||||||
if (!shaRes.ok) { alert('SHA-Fetch fehlgeschlagen.'); return; }
|
if (!shaRes.ok) { alert('SHA-Fetch fehlgeschlagen.'); return; }
|
||||||
const sha = (await shaRes.json()).sha;
|
const sha = (await shaRes.json()).sha;
|
||||||
cfg.memberCoordinatorReport = !currentEnabled;
|
cfg.memberCoordinatorReport = !currentEnabled;
|
||||||
const content = btoa(unescape(encodeURIComponent(JSON.stringify(cfg, null, 2))));
|
const content = btoa(unescape(encodeURIComponent(JSON.stringify(cfg, null, 2))));
|
||||||
const res = await fetch(giteaAuthUrl(`chapters/${code}/config.json`, token), {
|
const res = await fetch(giteaAuthUrl(`chapters/${code}/config.json`, token, 'data'), {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ message: `Koordinatoren-Bericht ${cfg.memberCoordinatorReport ? 'aktiviert' : 'deaktiviert'} für ${code}`, content, sha })
|
body: JSON.stringify({ message: `Koordinatoren-Bericht ${cfg.memberCoordinatorReport ? 'aktiviert' : 'deaktiviert'} für ${code}`, content, sha, branch: 'data' })
|
||||||
});
|
});
|
||||||
if (res.ok) { loadAllChapters(); }
|
if (res.ok) { loadAllChapters(); }
|
||||||
else { alert('Fehler beim Speichern der Konfiguration.'); }
|
else { alert('Fehler beim Speichern der Konfiguration.'); }
|
||||||
@@ -1253,7 +1254,7 @@ async function loadCoordinatorReportData() {
|
|||||||
form.style.display = 'block';
|
form.style.display = 'block';
|
||||||
_coordReportData = null;
|
_coordReportData = null;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${code}/coordinator-report-${year}.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${code}/coordinator-report-${year}.json`), { cache: 'no-store' });
|
||||||
if (res.ok) _coordReportData = await res.json();
|
if (res.ok) _coordReportData = await res.json();
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
if (!_coordReportData) {
|
if (!_coordReportData) {
|
||||||
@@ -1429,14 +1430,14 @@ async function _saveCoordinatorReportToGitea(code, data) {
|
|||||||
_coordStatus('Speichere…');
|
_coordStatus('Speichere…');
|
||||||
let sha = null;
|
let sha = null;
|
||||||
try {
|
try {
|
||||||
const shaRes = await fetch(giteaAuthUrl(path, token));
|
const shaRes = await fetch(giteaAuthUrl(path, token, 'data'));
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
const content = btoa(unescape(encodeURIComponent(JSON.stringify(data, null, 2))));
|
||||||
const body = { message: `Update Koordinatoren-Bericht ${year} für ${code}`, content };
|
const body = { message: `Update Koordinatoren-Bericht ${year} für ${code}`, content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaAuthUrl(path, token), {
|
const res = await fetch(giteaAuthUrl(path, token, 'data'), {
|
||||||
method: sha ? 'PUT' : 'POST',
|
method: sha ? 'PUT' : 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Epsilon",
|
|
||||||
"syncUrl": "https://bni-ulm.com/epsilon/de/memberlist?chapterName=®ionIds=43671&isChapterwebsite=true",
|
|
||||||
"websiteUrl": "https://bni-ulm.de/epsilon",
|
|
||||||
"defaultTimer": 60
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Galaxis",
|
|
||||||
"logoUrl": "logo.png",
|
|
||||||
"syncUrl": "https://bni-ulm.com/galaxis/de/memberlist?chapterName=6041®ionIds=43671&isChapterwebsite=true",
|
|
||||||
"websiteUrl": "https://bni-ulm.de/galaxis",
|
|
||||||
"defaultTimer": 60
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Helios",
|
|
||||||
"syncUrl": "https://bni-konstanz.de/helios/de/memberlist?chapterName=40832®ionIds=6023&isChapterwebsite=true",
|
|
||||||
"websiteUrl": "https://bni-konstanz.de/helios",
|
|
||||||
"defaultTimer": 60
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Kallisto",
|
|
||||||
"syncUrl": "https://bni-ulm.com/kallisto/de/memberlist?chapterName=35844®ionIds=43671$isChapterwebsite",
|
|
||||||
"websiteUrl": "https://bni-ulm.de/kallisto",
|
|
||||||
"defaultTimer": 60
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 33 KiB |
@@ -1,82 +0,0 @@
|
|||||||
{
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"id": "willkommen",
|
|
||||||
"label": "Willkommen",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g063c60ec44c3347ad841c139671232dff"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "trainingsbeitrag",
|
|
||||||
"label": "Trainingsbeitrag",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g066608ae9da024f8e87c0e705dbe6852f"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "visitenkarten",
|
|
||||||
"label": "Visitenkarten",
|
|
||||||
"type": "image",
|
|
||||||
"imagePath": "agenda/visitenkarten.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "verleihung-der-lumora",
|
|
||||||
"label": "Verleihung der Lumora",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0385ba8f3e8a8422ab051f1591bcf598d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bericht-des-mitgliederkoordinators",
|
|
||||||
"label": "Bericht des Mitgliederkoordinators",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0d27561ab34c141a39f981ab6b36fbd03"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "break-out",
|
|
||||||
"label": "Break Out",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0fbb79876ba15437abf469c098a72b789"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "naechste-hauptpraesentation",
|
|
||||||
"label": "Nächste Hauptpräsentation",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0ba90bb948a91426d9bb4bbb59bb5bf9d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "marketing-ergebnisrunde-erklaerung",
|
|
||||||
"label": "Marketing- Ergebnisrunde Erklärung",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0848053a6eea54f18bbaaee7d33861386"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "feedback-gaeste",
|
|
||||||
"label": "Feedback Gäste",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0da62ecf51cdf4d9285097db2c9b80b26"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "ziehung-des-tagespreises",
|
|
||||||
"label": "Ziehung des Tagespreises",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0b231f4b1bdf34850a8a8baca4b2d6972"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bericht-des-schatzmeisters",
|
|
||||||
"label": "Bericht des Schatzmeisters",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0249a5f37a97e419db184bef50bcbdb8e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "bericht-des-eventkoordinators",
|
|
||||||
"label": "Bericht des Eventkoordinators",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g0ad05a18b97214634818823cd3bd3ebca"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "zitat",
|
|
||||||
"label": "Zitat",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://show.zohopublic.eu/publish/cb5g03d4fc1ad7a8141c098addbee9dfcbffb"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 197 KiB |
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Lumora Hybrid",
|
|
||||||
"logoUrl": "BNI Logo.png",
|
|
||||||
"syncUrl": "https://bni-ulm.com/lumora/de/memberlist?chapterName=44269®ionIds=43671&isChapterwebsite=true",
|
|
||||||
"websiteUrl": "https://bni-ulm.de/lumora",
|
|
||||||
"defaultTimer": 60
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"id": "bericht-der-schatzmeisterin",
|
|
||||||
"label": "Bericht der Schatzmeisterin",
|
|
||||||
"type": "image",
|
|
||||||
"notes": "Hier sollte was stehen",
|
|
||||||
"imagePath": "agenda/bericht-der-schatzmeisterin.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "beispieldatei",
|
|
||||||
"label": "Beispieldatei",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://workdrive.digiseed.de/writer/open/a5u6x594bfa69700846d88739fa2756082ada"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "willkommen",
|
|
||||||
"label": "Willkommen",
|
|
||||||
"type": "image",
|
|
||||||
"imagePath": "agenda/willkommen.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "ende-logo",
|
|
||||||
"label": "Ende - Logo",
|
|
||||||
"type": "image",
|
|
||||||
"imagePath": "agenda/ende-logo.jpg"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "witz-des-tages",
|
|
||||||
"label": "Witz des Tages",
|
|
||||||
"type": "embed",
|
|
||||||
"embedUrl": "https://digiseed.de"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "schatzmeister-offline",
|
|
||||||
"label": "Schatzmeister Offline",
|
|
||||||
"type": "image",
|
|
||||||
"imagePath": "agenda/schatzmeister-offline.jpg"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 196 KiB |
|
Before Width: | Height: | Size: 72 KiB |
|
Before Width: | Height: | Size: 277 KiB |
|
Before Width: | Height: | Size: 72 KiB |
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"chapterName": "BNI Chapter Sonne",
|
|
||||||
"syncUrl": "https://bni-ulm.com/sonne/de/memberlist?chapterName=6035®ionIds=43671&isChapterwebsite=true",
|
|
||||||
"websiteUrl": "https://bni-ulm.de/sonne",
|
|
||||||
"defaultTimer": 60,
|
|
||||||
"memberCoordinatorReport": false
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"year": "2025-2026",
|
|
||||||
"metrics": [
|
|
||||||
{
|
|
||||||
"key": "attendance",
|
|
||||||
"label": "Anwesenheit",
|
|
||||||
"unit": "%",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 98
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 98
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "members",
|
|
||||||
"label": "Mitgliederzahl",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 41
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 42
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "newMembers",
|
|
||||||
"label": "Neue Mitglieder",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "guests",
|
|
||||||
"label": "Gäste / Besucher",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 6
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "oneOnOne",
|
|
||||||
"label": "4-Augen-Gespräche",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 118
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 72
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "cte",
|
|
||||||
"label": "CTE",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 254
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 59
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "referrals",
|
|
||||||
"label": "Empfehlungen",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 70
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 32
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "revenueThank",
|
|
||||||
"label": "Umsatzdanke",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 0,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2025-04",
|
|
||||||
"value": 106513
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2025-05",
|
|
||||||
"value": 231210
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"updatedAt": "2026-05-21"
|
|
||||||
}
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
{
|
|
||||||
"year": "2026-2027",
|
|
||||||
"metrics": [
|
|
||||||
{
|
|
||||||
"key": "attendance",
|
|
||||||
"label": "Anwesenheit",
|
|
||||||
"unit": "%",
|
|
||||||
"annualTarget": 95,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 96
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 97
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "members",
|
|
||||||
"label": "Mitgliederzahl",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 49,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 42
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "newMembers",
|
|
||||||
"label": "Neue Mitglieder",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 7,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "guests",
|
|
||||||
"label": "Gäste / Besucher",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 10.5,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 6
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "oneOnOne",
|
|
||||||
"label": "4-Augen-Gespräche",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 168,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 56
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 72
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "cte",
|
|
||||||
"label": "CTE",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 705.6,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 208
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 59
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "referrals",
|
|
||||||
"label": "Empfehlungen",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 100.8,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 34
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 32
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "revenueThank",
|
|
||||||
"label": "Umsatzdanke",
|
|
||||||
"unit": "",
|
|
||||||
"annualTarget": 146034,
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"month": "2026-04",
|
|
||||||
"value": 26259
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"month": "2026-05",
|
|
||||||
"value": 231210
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"updatedAt": "2026-05-24"
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
{
|
|
||||||
"updatedAt": "2026-04-27",
|
|
||||||
"metrics": [
|
|
||||||
{
|
|
||||||
"key": "attendance",
|
|
||||||
"label": "Anwesenheit",
|
|
||||||
"unit": "%",
|
|
||||||
"target": 95,
|
|
||||||
"current": 96
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "members",
|
|
||||||
"label": "Mitgliederzahl",
|
|
||||||
"unit": "",
|
|
||||||
"target": 42,
|
|
||||||
"current": 42
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "newMembers",
|
|
||||||
"label": "Neue Mitglieder",
|
|
||||||
"unit": "",
|
|
||||||
"target": 1.3,
|
|
||||||
"current": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "guests",
|
|
||||||
"label": "Gäste / Besucher",
|
|
||||||
"unit": "",
|
|
||||||
"target": 10.5,
|
|
||||||
"current": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "oneOnOne",
|
|
||||||
"label": "4-Augen-Gespräche",
|
|
||||||
"unit": "",
|
|
||||||
"target": 168,
|
|
||||||
"current": 56
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "cte",
|
|
||||||
"label": "CTE",
|
|
||||||
"unit": "",
|
|
||||||
"target": 705.6,
|
|
||||||
"current": 208
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "referrals",
|
|
||||||
"label": "Empfehlungen",
|
|
||||||
"unit": "",
|
|
||||||
"target": 100.8,
|
|
||||||
"current": 34
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "revenueThank",
|
|
||||||
"label": "Umsatzdanke",
|
|
||||||
"unit": "",
|
|
||||||
"target": 146034,
|
|
||||||
"current": 26259
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
25
index.html
@@ -1947,7 +1947,8 @@ const APP_VERSION = '2.1';
|
|||||||
const GITEA_RAW = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde/raw';
|
const GITEA_RAW = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde/raw';
|
||||||
const GITEA_API = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde';
|
const GITEA_API = 'http://72.60.134.73:3000/api/v1/repos/cheubaum/BNI-Vorstellungsrunde';
|
||||||
function giteaUrl(path) { return `${GITEA_RAW}/${path}?ref=main`; }
|
function giteaUrl(path) { return `${GITEA_RAW}/${path}?ref=main`; }
|
||||||
function giteaAuthUrl(path, token) { return `${GITEA_API}/contents/${path}?token=${encodeURIComponent(token)}`; }
|
function giteaDataUrl(path) { return `${GITEA_RAW}/${path}?ref=data`; }
|
||||||
|
function giteaAuthUrl(path, token, ref) { return `${GITEA_API}/contents/${path}?token=${encodeURIComponent(token)}${ref ? '&ref=' + ref : ''}`; }
|
||||||
const CHAPTER_CONFIG_KEY = 'bni-active-chapter';
|
const CHAPTER_CONFIG_KEY = 'bni-active-chapter';
|
||||||
|
|
||||||
function loadChapterConfig() {
|
function loadChapterConfig() {
|
||||||
@@ -2509,7 +2510,7 @@ function renderDisplay() {
|
|||||||
imgEl.src = '';
|
imgEl.src = '';
|
||||||
} else if (it.imagePath) {
|
} else if (it.imagePath) {
|
||||||
const src = it.imagePath.startsWith('http') ? it.imagePath
|
const src = it.imagePath.startsWith('http') ? it.imagePath
|
||||||
: giteaUrl(`chapters/${activeChapter.code}/${it.imagePath}`);
|
: giteaDataUrl(`chapters/${activeChapter.code}/${it.imagePath}`);
|
||||||
imgEl.onerror = () => {
|
imgEl.onerror = () => {
|
||||||
imgEl.style.display = 'none';
|
imgEl.style.display = 'none';
|
||||||
if (errEl) errEl.style.display = 'block';
|
if (errEl) errEl.style.display = 'block';
|
||||||
@@ -3234,7 +3235,7 @@ async function fetchChapterAgendaFromGitea() {
|
|||||||
if (!state.agendaCatalog) state.agendaCatalog = [];
|
if (!state.agendaCatalog) state.agendaCatalog = [];
|
||||||
ensureAgendaOrderDefaults();
|
ensureAgendaOrderDefaults();
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/agenda.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/agenda.json`), { cache: 'no-store' });
|
||||||
const items = res.ok ? (await res.json()).items : null;
|
const items = res.ok ? (await res.json()).items : null;
|
||||||
if (Array.isArray(items)) {
|
if (Array.isArray(items)) {
|
||||||
// Mergen statt Überschreiben: lokale, noch nicht hochgeladene Punkte
|
// Mergen statt Überschreiben: lokale, noch nicht hochgeladene Punkte
|
||||||
@@ -5337,7 +5338,7 @@ async function activateChapter() {
|
|||||||
status.textContent = 'Überprüfe Lizenzcode…';
|
status.textContent = 'Überprüfe Lizenzcode…';
|
||||||
status.style.color = 'rgba(255,255,255,0.6)';
|
status.style.color = 'rgba(255,255,255,0.6)';
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${code}/config.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${code}/config.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
status.textContent = 'Ungültiger oder abgelaufener Lizenzcode.';
|
status.textContent = 'Ungültiger oder abgelaufener Lizenzcode.';
|
||||||
status.style.color = '#f87171';
|
status.style.color = '#f87171';
|
||||||
@@ -5379,7 +5380,7 @@ function applyChapterUI(config) {
|
|||||||
if (ctrlName) ctrlName.textContent = `${name} – Steuerung`;
|
if (ctrlName) ctrlName.textContent = `${name} – Steuerung`;
|
||||||
if (config.logoUrl && activeChapter) {
|
if (config.logoUrl && activeChapter) {
|
||||||
const src = config.logoUrl.startsWith('http') ? config.logoUrl
|
const src = config.logoUrl.startsWith('http') ? config.logoUrl
|
||||||
: giteaUrl(`chapters/${activeChapter.code}/${config.logoUrl}`);
|
: giteaDataUrl(`chapters/${activeChapter.code}/${config.logoUrl}`);
|
||||||
['display-logo','display-logo-empty','ctrl-logo'].forEach(id => {
|
['display-logo','display-logo-empty','ctrl-logo'].forEach(id => {
|
||||||
const img = document.getElementById(id);
|
const img = document.getElementById(id);
|
||||||
if (img) img.src = src;
|
if (img) img.src = src;
|
||||||
@@ -5397,7 +5398,7 @@ function applyChapterUI(config) {
|
|||||||
async function checkLicenseAndUpdates() {
|
async function checkLicenseAndUpdates() {
|
||||||
if (!activeChapter) return;
|
if (!activeChapter) return;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/config.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/config.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
clearChapterData();
|
clearChapterData();
|
||||||
state = defaultState();
|
state = defaultState();
|
||||||
@@ -5441,7 +5442,7 @@ function showUpdateBanner(version, notes) {
|
|||||||
|
|
||||||
async function downloadUpdate(version) {
|
async function downloadUpdate(version) {
|
||||||
try {
|
try {
|
||||||
const licRes = await fetch(giteaUrl(`chapters/${activeChapter.code}/config.json`), { cache: 'no-store' });
|
const licRes = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/config.json`), { cache: 'no-store' });
|
||||||
if (!licRes.ok) {
|
if (!licRes.ok) {
|
||||||
clearChapterData();
|
clearChapterData();
|
||||||
state = defaultState();
|
state = defaultState();
|
||||||
@@ -5502,7 +5503,7 @@ async function downloadUpdate(version) {
|
|||||||
async function fetchChapterMembersFromGitea() {
|
async function fetchChapterMembersFromGitea() {
|
||||||
if (!activeChapter) return;
|
if (!activeChapter) return;
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/members.json`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/members.json`), { cache: 'no-store' });
|
||||||
if (!res.ok) return;
|
if (!res.ok) return;
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
if (!data.members || !data.members.length) return;
|
if (!data.members || !data.members.length) return;
|
||||||
@@ -5563,13 +5564,13 @@ async function uploadMembersToGitea() {
|
|||||||
try {
|
try {
|
||||||
// Get current SHA
|
// Get current SHA
|
||||||
let sha = null;
|
let sha = null;
|
||||||
const shaRes = await fetch(giteaAuthUrl(path, token));
|
const shaRes = await fetch(giteaAuthUrl(path, token, 'data'));
|
||||||
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
if (shaRes.ok) sha = (await shaRes.json()).sha;
|
||||||
|
|
||||||
const body = { message: `Mitglieder aktualisiert ${new Date().toLocaleDateString('de')}`, content };
|
const body = { message: `Mitglieder aktualisiert ${new Date().toLocaleDateString('de')}`, content, branch: 'data' };
|
||||||
if (sha) body.sha = sha;
|
if (sha) body.sha = sha;
|
||||||
|
|
||||||
const res = await fetch(giteaAuthUrl(path, token), {
|
const res = await fetch(giteaAuthUrl(path, token, 'data'), {
|
||||||
method: sha ? 'PUT' : 'POST',
|
method: sha ? 'PUT' : 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
@@ -5821,7 +5822,7 @@ async function showCoordinatorReport() {
|
|||||||
];
|
];
|
||||||
const datas = await Promise.all(candidates.map(async f => {
|
const datas = await Promise.all(candidates.map(async f => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(giteaUrl(`chapters/${activeChapter.code}/${f}`), { cache: 'no-store' });
|
const res = await fetch(giteaDataUrl(`chapters/${activeChapter.code}/${f}`), { cache: 'no-store' });
|
||||||
if (!res.ok) return null;
|
if (!res.ok) return null;
|
||||||
return await res.json();
|
return await res.json();
|
||||||
} catch(e) { return null; }
|
} catch(e) { return null; }
|
||||||
|
|||||||