1
0

newWebsite2.0

This commit is contained in:
Br0tcraft
2026-08-20 20:36:47 +02:00
parent 7020f970d8
commit 7d975feae4
100 changed files with 6774 additions and 3327 deletions

102
mini/js/main.js Normal file
View File

@@ -0,0 +1,102 @@
import { initTodayPage } from './modules/today.js';
import { initSequencePage } from './modules/sequence.js';
import { initKnowledgePage } from './modules/knowledge.js';
document.addEventListener("DOMContentLoaded", () => {
const container = document.getElementById("content-container");
const triggers = document.querySelectorAll("[data-file]");
const settingsBtn = document.getElementById('settingsBtn');
const settingsModal = document.getElementById('settingsModal');
const closeSettingsBtn = document.getElementById('closeSettingsBtn');
const darkModeToggle = document.getElementById('darkModeToggle');
settingsBtn.addEventListener('click', () => {
settingsModal.classList.add('active');
});
closeSettingsBtn.addEventListener('click', () => {
settingsModal.classList.remove('active');
});
settingsModal.addEventListener('click', (e) => {
if (e.target === settingsModal) {
settingsModal.classList.remove('active');
}
});
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && settingsModal.classList.contains('active')) {
settingsModal.classList.remove('active');
}
});
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const systemPrefersDark = mediaQuery.matches;
const storedDarkMode = localStorage.getItem('darkMode');
let isDark;
if (storedDarkMode !== null) {
isDark = storedDarkMode === 'true';
} else {
isDark = systemPrefersDark;
}
function applyDarkMode(enable) {
document.body.classList.toggle('dark-mode', enable);
if (darkModeToggle) {
darkModeToggle.checked = enable;
}
}
applyDarkMode(isDark);
darkModeToggle.addEventListener('change', () => {
const isDarkNow = darkModeToggle.checked;
applyDarkMode(isDarkNow);
localStorage.setItem('darkMode', isDarkNow);
});
function handleSystemChange(e) {
if (localStorage.getItem('darkMode') === null) {
applyDarkMode(e.matches);
}
}
if (mediaQuery.addEventListener) {
mediaQuery.addEventListener('change', handleSystemChange);
} else {
mediaQuery.addListener(handleSystemChange);
}
async function loadPage(file) {
try {
const response = await fetch(file);
if (!response.ok) throw new Error("Error loading page: " + response.statusText);
container.innerHTML = await response.text();
triggers.forEach(item => {
item.classList.toggle("active", item.getAttribute("data-file") === file);
});
if (file.includes("today")) initTodayPage();
if (file.includes("sequence")) initSequencePage();
if (file.includes("knowledge")) initKnowledgePage();
} catch (error) {
container.innerHTML = "<p>Error loading content.</p>";
console.error(error);
}
}
loadPage("pages/today.html");
triggers.forEach(trigger => {
trigger.addEventListener("click", (e) => {
e.preventDefault();
loadPage(trigger.getAttribute("data-file"));
});
});
});

View File

@@ -0,0 +1,95 @@
export async function initKnowledgePage() {
const wissenList = document.getElementById('wissen-list');
const gebeteList = document.getElementById('gebete-list');
if (wissenList) {
try {
const knowledgeResponse = await fetch('data/knowledge/knowledge.json');
const knowledgeItems = await knowledgeResponse.json();
renderKnowledgeList(wissenList, knowledgeItems);
} catch (error) {
console.error('Fehler beim Laden der Wissens-Übersicht:', error);
}
}
if (gebeteList) {
try {
const gebeteResponse = await fetch('data/prayers/prayers.json');
const gebeteItems = await gebeteResponse.json();
renderGebeteList(gebeteList, gebeteItems);
} catch (error) {
console.error('Fehler beim Laden der Gebete:', error);
}
}
const tabs = document.querySelectorAll('.wissen-tab');
const panelGebete = document.getElementById('panel-gebete');
const panelWissen = document.getElementById('panel-wissen');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('active'));
tab.classList.add('active');
const target = tab.dataset.tab;
if (panelGebete) panelGebete.classList.toggle('active', target === 'gebete');
if (panelWissen) panelWissen.classList.toggle('active', target === 'wissen');
});
});
}
function createAccordionItem(title, filename, basePath) {
const element = document.createElement('div');
element.className = 'wissen-item';
element.innerHTML = `
<button class="wissen-header">
<span class="wissen-title">${title}</span>
<img src="assets/icons/arrow_down.svg" alt="Pfeil nach unten" class="wissen-arrow">
</button>
<div class="wissen-content">
<p class="loading">Loading...</p>
</div>
`;
const header = element.querySelector('.wissen-header');
const contentDiv = element.querySelector('.wissen-content');
let isLoaded = false;
header.addEventListener('click', async () => {
element.classList.toggle('active');
if (element.classList.contains('active') && !isLoaded) {
try {
const contentResponse = await fetch(`${basePath}/${filename}`);
if (!contentResponse.ok) throw new Error('Failed to load file');
const htmlContent = await contentResponse.text();
contentDiv.innerHTML = htmlContent;
isLoaded = true;
} catch (err) {
contentDiv.innerHTML = '<p>Failed to load content.</p>';
}
}
});
return element;
}
function renderKnowledgeList(container, items) {
container.innerHTML = '';
items.forEach(item => {
const title = item.titel || item.title;
const element = createAccordionItem(title, item.file, 'data/knowledge');
container.appendChild(element);
});
}
function renderGebeteList(container, items) {
container.innerHTML = '';
items.forEach(item => {
const title = item.title || item.titel;
const element = createAccordionItem(title, item.file, 'data/prayers');
container.appendChild(element);
});
}

120
mini/js/modules/sequence.js Normal file
View File

@@ -0,0 +1,120 @@
export async function initSequencePage() {
const listContainer = document.getElementById('sequence-list') || document.getElementById('ablauf-list');
const filterChips = document.querySelectorAll('.filter-chip');
if (!listContainer) {
console.warn('Sequence container not found.');
return;
}
try {
const response = await fetch('data/sequence/sequence.json');
if (!response.ok) throw new Error('Sequence data could not be loaded.');
const sequenceSteps = await response.json();
renderSequenceList(listContainer, sequenceSteps);
setupFilterLogic(filterChips);
} catch (error) {
console.error('Error loading sequence:', error);
listContainer.innerHTML = '<p>Sequence could not be loaded.</p>';
}
}
function renderSequenceList(container, steps) {
container.innerHTML = '';
steps.forEach(step => {
const item = document.createElement('div');
item.className = 'ablauf-item';
item.dataset.categories = step.categories.join(',');
item.innerHTML = `
<button class="sequence-header">
<span class="sequence-title">${step.title}</span>
<i data-lucide="chevron-down" class="ablauf-arrow"></i>
</button>
<div class="sequence-content">
<p class="loading">Loading...</p>
</div>
`;
const header = item.querySelector('.sequence-header');
const contentDiv = item.querySelector('.sequence-content');
let isLoaded = false;
header.addEventListener('click', async () => {
item.classList.toggle('active');
if (item.classList.contains('active') && !isLoaded) {
try {
const contentResponse = await fetch(`data/sequence/${step.file}`);
if (!contentResponse.ok) throw new Error('Content not found.');
const htmlContent = await contentResponse.text();
contentDiv.innerHTML = htmlContent;
isLoaded = true;
} catch (err) {
console.error(err);
contentDiv.innerHTML = '<p>Content could not be loaded.</p>';
}
}
});
container.appendChild(item);
});
}
function setupFilterLogic(filterChips) {
if (!filterChips || filterChips.length === 0) return;
let activeFilters = new Set(['alle']);
function applyFilters() {
document.querySelectorAll('.ablauf-item').forEach(item => {
const categories = item.dataset.categories ? item.dataset.categories.split(',') : [];
const isVisible = activeFilters.has('alle') ||
categories.some(cat => activeFilters.has(cat));
item.style.display = isVisible ? '' : 'none';
});
}
filterChips.forEach(chip => {
chip.addEventListener('click', () => {
const filter = chip.dataset.filter;
if (filter === 'alle') {
activeFilters = new Set(['alle']);
filterChips.forEach(c => c.classList.remove('active'));
chip.classList.add('active');
} else {
if (activeFilters.has('alle')) {
activeFilters.delete('alle');
document.querySelector('.filter-chip[data-filter="alle"]')?.classList.remove('active');
}
if (activeFilters.has(filter)) {
activeFilters.delete(filter);
chip.classList.remove('active');
} else {
activeFilters.add(filter);
chip.classList.add('active');
}
if (activeFilters.size === 0) {
activeFilters.add('alle');
document.querySelector('.filter-chip[data-filter="alle"]')?.classList.add('active');
}
}
applyFilters();
});
});
applyFilters();
}

227
mini/js/modules/today.js Normal file
View File

@@ -0,0 +1,227 @@
export async function initTodayPage() {
const today = new Date();
document.getElementById('weekday').textContent = today.toLocaleDateString('de-DE', { weekday: 'long' });
document.getElementById('date').textContent = today.toLocaleDateString('de-DE', { day: '2-digit', month: 'long', year: 'numeric' });
const miniColor = getMiniColor(today);
const miniAmount = getMiniAmount(today);
document.getElementById('summary-color').textContent = miniColor;
document.getElementById('summary-count').textContent = miniAmount;
const modal = document.getElementById('task-modal');
if (!modal) return;
try {
const [tasksResponse, placementsResponse] = await Promise.all([
fetch('data/tasks.json'),
fetch('data/placements.json')
]);
const taskData = await tasksResponse.json();
const placementData = await placementsResponse.json();
setupTaskModal(modal, taskData);
setupPlacementViewer(placementData);
} catch (error) {
console.error('Error while loading data:', error);
}
}
function setupTaskModal(modal, taskData) {
const modalIcon = document.getElementById('modal-icon');
const modalTitle = document.getElementById('modal-title');
const modalDescription = document.getElementById('modal-description');
const modalSteps = document.getElementById('modal-steps');
const closeBtn = modal.querySelector('.modal-close');
const segContainer = document.getElementById('task-segmented-control');
document.querySelectorAll('.task-card').forEach(card => {
card.addEventListener('click', () => {
const data = taskData[card.dataset.task];
if (!data) return;
modalIcon.src = data.icon;
modalTitle.textContent = data.title;
if (data.description) {
modalDescription.textContent = data.description;
modalDescription.style.display = '';
} else {
modalDescription.style.display = 'none';
}
const steps = data.steps;
let sections = [];
let isFlat = false;
if (Array.isArray(steps) && steps.length > 0) {
if (typeof steps[0] === 'object' && steps[0].steps && Array.isArray(steps[0].steps)) {
sections = steps;
} else {
sections = [{ title: null, steps: steps }];
isFlat = true;
}
} else {
sections = [{ title: null, steps: [] }];
isFlat = true;
}
const renderSteps = (stepsArray) => {
modalSteps.innerHTML = stepsArray.map(step => `<li>${step}</li>`).join('');
};
if (sections.length > 1 && !isFlat) {
segContainer.style.display = 'flex';
segContainer.innerHTML = '';
sections.forEach((section, index) => {
const btn = document.createElement('button');
btn.className = 'segmented-btn' + (index === 0 ? ' active' : '');
btn.textContent = section.title;
btn.dataset.index = index;
btn.addEventListener('click', () => {
segContainer.querySelectorAll('.segmented-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
renderSteps(sections[index].steps);
});
segContainer.appendChild(btn);
});
renderSteps(sections[0].steps);
} else {
segContainer.style.display = 'none';
if (sections.length === 1) {
renderSteps(sections[0].steps);
} else {
renderSteps(steps); // Fallback
}
}
modal.classList.add('active');
});
});
// Schließen
closeBtn?.addEventListener('click', () => modal.classList.remove('active'));
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.classList.remove('active');
});
}
function setupPlacementViewer(placementData) {
let currentIndex = 0;
let showIncense = false;
const placementImage = document.getElementById('placement-image');
const placementLabel = document.getElementById('placement-label');
const prevBtn = document.getElementById('placement-prev');
const nextBtn = document.getElementById('placement-next');
const weihrauchToggle = document.getElementById('incense-toggle');
const koerbchenLegend = document.getElementById('basket-toggle');
const weihrauchLegend = document.getElementById('incense-legend');
const kerzeLabel = document.getElementById('kerze-label');
function updatePlacement() {
const dataset = showIncense ? placementData.withWeihrauch : placementData.standard;
const currentItem = dataset[currentIndex];
if (!currentItem) return;
placementImage.src = currentItem.image;
placementLabel.textContent = currentItem.label;
kerzeLabel.textContent = showIncense ? 'Kerze & Kollekte' : 'Kerze';
const isEntranceWithIncense = showIncense && currentIndex === 0;
koerbchenLegend.style.display = isEntranceWithIncense ? 'none' : '';
weihrauchLegend.style.display = isEntranceWithIncense ? '' : 'none';
}
prevBtn?.addEventListener('click', () => {
currentIndex = (currentIndex - 1 + 3) % 3;
updatePlacement();
});
nextBtn?.addEventListener('click', () => {
currentIndex = (currentIndex + 1) % 3;
updatePlacement();
});
weihrauchToggle?.addEventListener('click', () => {
showIncense = !showIncense;
weihrauchToggle.classList.toggle('active', showIncense);
updatePlacement();
});
updatePlacement();
}
function getOstern(jahr) {
const a = jahr % 19;
const b = jahr % 4;
const c = jahr % 7;
const k = Math.floor(jahr / 100);
const p = Math.floor((13 + 8 * k) / 25);
const q = Math.floor(k / 4);
const M = (15 - p + k - q) % 30;
const N = (4 + k - q) % 7;
const d = (19 * a + M) % 30;
const e = (2 * b + 4 * c + 6 * d + N) % 7;
const days = 22 + d + e;
if (days <= 31) {
return new Date(jahr, 2, days);
} else {
return new Date(jahr, 3, days - 31);
}
}
function tageDifferenz(datum1, datum2) {
const day = 24 * 60 * 60 * 1000;
return Math.round((datum1 - datum2) / day);
}
function getMiniColor(targetDate) {
const year = targetDate.getFullYear();
const easter = getOstern(year);
const diffToEaster = tageDifferenz(targetDate, easter);
const month = targetDate.getMonth();
const day = targetDate.getDate();
const wochentag = targetDate.getDay();
if ((month === 11 && day >= 24) || (month === 0 && day <= 10)) {
return "GRÜN";
}
if (diffToEaster >= -46 && diffToEaster <= -1) {
if (diffToEaster === -7 || diffToEaster === -2) {
return "ROT";
}
return "LILA";
}
if (diffToEaster >= 0 && diffToEaster <= 50) {
if (diffToEaster === 50) {
return "ROT";
}
return "GRÜN";
}
let holyEvening = new Date(year, 11, 24);
let fourthAdvent = new Date(year, 11, 24 - holyEvening.getDay());
let firstAdvent = new Date(fourthAdvent);
firstAdvent.setDate(fourthAdvent.getDate() - 21);
if (targetDate >= firstAdvent && targetDate < holyEvening) {
return "LILA";
}
return "GRÜN";
}
function getMiniAmount(targetDate) {
const amount = (targetDate.getDay() === 0 || targetDate.getDay() === 6) ? 6 : 4;
return amount;
}