Familienangebote im August: Unterschied zwischen den Versionen

Aus Bündnis für Familie Tübingen.
Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 3: Zeile 3:
<head>
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Familienangebote August 2026</title>
<title>Familienangebote August 2026</title>


<style>
<style>
body{
body{
     font-family:Arial,sans-serif;
     font-family: Arial, sans-serif;
     margin:20px;
     margin:20px;
     background:#f5f5f5;
     background:#f5f5f5;
Zeile 16: Zeile 15:
h1{
h1{
     text-align:center;
     text-align:center;
}
.toolbar{
    display:flex;
    gap:10px;
    margin-bottom:20px;
    justify-content:center;
}
button{
    cursor:pointer;
}
}


Zeile 22: Zeile 32:
     grid-template-columns:repeat(7,1fr);
     grid-template-columns:repeat(7,1fr);
     gap:10px;
     gap:10px;
}
.weekday{
    background:#003366;
    color:white;
    padding:10px;
    text-align:center;
    font-weight:bold;
}
}


.day{
.day{
     background:white;
     background:white;
     min-height:180px;
     min-height:150px;
     border-radius:10px;
     border-radius:8px;
     padding:10px;
     padding:8px;
     box-shadow:0 2px 5px rgba(0,0,0,0.15);
     box-shadow:0 2px 5px rgba(0,0,0,.15);
     cursor:pointer;
     cursor:pointer;
}
}
Zeile 35: Zeile 53:
.day-number{
.day-number{
     font-weight:bold;
     font-weight:bold;
     margin-bottom:5px;
     margin-bottom:8px;
}
}


.entry{
.entry{
     background:#e9f3ff;
     background:#e8f2ff;
    margin-top:5px;
     padding:4px;
     padding:4px;
    margin-bottom:4px;
     border-radius:4px;
     border-radius:4px;
     font-size:12px;
     font-size:12px;
}
.weekday{
    text-align:center;
    font-weight:bold;
    padding:10px;
}
}


Zeile 56: Zeile 68:
     position:fixed;
     position:fixed;
     inset:0;
     inset:0;
     background:rgba(0,0,0,0.6);
     background:rgba(0,0,0,.5);
    justify-content:center;
    align-items:center;
}
}


.modal-content{
.modal-content{
     background:white;
     background:white;
     width:700px;
     width:90%;
     max-width:95%;
     max-width:900px;
     margin:30px auto;
    max-height:90vh;
     overflow:auto;
     padding:20px;
     padding:20px;
     border-radius:10px;
     border-radius:10px;
    max-height:90vh;
    overflow:auto;
}
}


input,textarea{
label{
    display:block;
    margin-top:10px;
    font-weight:bold;
}
 
input, textarea{
     width:100%;
     width:100%;
    margin-bottom:10px;
     padding:8px;
     padding:8px;
    box-sizing:border-box;
}
}


button{
.entry-card{
    border:1px solid #ccc;
     padding:10px;
     padding:10px;
     margin-right:5px;
     margin:10px 0;
    border-radius:6px;
}
}


.entry-list{
.actions{
     margin-top:20px;
    display:flex;
    gap:10px;
     margin-top:10px;
}
}


.saved-entry{
.close-btn{
     border:1px solid #ddd;
     float:right;
    padding:10px;
    margin-bottom:10px;
}
}


.empty{
    background:transparent;
}
</style>
</style>
</head>
</head>
<body>
<body>


<h1>Familienangebote August 2026</h1>
<h1>Familienangebote August 2026</h1>
 
<div class="toolbar">
    <button onclick="exportData()">Export JSON</button>
    <input type="file" id="importFile" onchange="importData(event)">
</div>


<div class="calendar" id="calendar"></div>
<div class="calendar" id="calendar"></div>


<div class="modal" id="modal">
<div class="modal" id="modal">
<div class="modal-content">
    <div class="modal-content">
 
<h2 id="modalDate"></h2>
 
<label>Angebot</label>
<input id="angebot">


<label>Uhrzeit</label>
        <button class="close-btn" onclick="closeModal()">Schließen</button>
<input id="uhrzeit">


<label>Treffpunkt/Ort</label>
        <h2 id="modalDate"></h2>
<input id="ort">


<label>Zielgruppe</label>
        <button onclick="addEntry()">+ Neuer Eintrag</button>
<input id="zielgruppe">


<label>Anmeldung</label>
        <div id="entriesContainer"></div>
<input id="anmeldung">
 
<label>Link zum Angebot</label>
<input id="link">
 
<label>Beschreibung</label>
<textarea id="beschreibung"></textarea>
 
<label>Weitere Termine (durch Komma getrennt)</label>
<input id="weitereTermine" placeholder="05,12,19,26">
 
<button onclick="saveEntry()">Speichern</button>
<button onclick="closeModal()">Schließen</button>
 
<div class="entry-list" id="entryList"></div>


</div>
    </div>
</div>
</div>


<script>
<script>


const year=2026;
const STORAGE_KEY = "familienangebote_august_2026";
const month=7;


let selectedDay=null;
let data = JSON.parse(localStorage.getItem(STORAGE_KEY) || "{}");
let selectedDay = null;


const calendar=document.getElementById("calendar");
const weekdays = ["Mo","Di","Mi","Do","Fr","Sa","So"];


const weekdays=[
function saveData(){
"Mo","Di","Mi","Do","Fr","Sa","So"
    localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
];
    renderCalendar();
}


weekdays.forEach(w=>{
function renderCalendar(){
    const div=document.createElement("div");
    div.className="weekday";
    div.innerText=w;
    calendar.appendChild(div);
});


const daysInMonth=31;
    const cal = document.getElementById("calendar");
    cal.innerHTML = "";


for(let d=1;d<=daysInMonth;d++){
    weekdays.forEach(day=>{
        const div = document.createElement("div");
        div.className = "weekday";
        div.textContent = day;
        cal.appendChild(div);
    });


     const day=document.createElement("div");
     const firstDay = new Date(2026,7,1);
    day.className="day";


     day.innerHTML=
     let offset = firstDay.getDay();
     `<div class="day-number">${d}</div>
     offset = offset === 0 ? 6 : offset - 1;
    <div id="entries-${d}"></div>`;


     day.onclick=()=>openDay(d);
     for(let i=0;i<offset;i++){
        const empty = document.createElement("div");
        empty.className = "empty";
        cal.appendChild(empty);
    }


     calendar.appendChild(day);
     for(let day=1; day<=31; day++){
}


function loadData(){
         const div = document.createElement("div");
    return JSON.parse(
        div.className = "day";
         localStorage.getItem("august2026") || "{}"
    );
}


function saveData(data){
         div.onclick = () => openDay(day);
    localStorage.setItem(
         "august2026",
        JSON.stringify(data)
    );
}


function render(){
        const dayNumber = document.createElement("div");
        dayNumber.className = "day-number";
        dayNumber.textContent = day;


    const data=loadData();
        div.appendChild(dayNumber);


    for(let d=1;d<=31;d++){
        const entries = data[day] || [];


         const container=
         entries.forEach(entry=>{
        document.getElementById(`entries-${d}`);
            const e = document.createElement("div");
            e.className = "entry";
            e.textContent = entry.angebot || "(ohne Titel)";
            div.appendChild(e);
        });


         container.innerHTML="";
         cal.appendChild(div);
 
        (data[d]||[]).forEach(item=>{
 
            const div=document.createElement("div");
            div.className="entry";
 
            div.innerHTML=
            `<strong>${item.angebot}</strong><br>
            ${item.uhrzeit}`;
 
            container.appendChild(div);
 
        });
     }
     }
}
}
Zeile 213: Zeile 207:
function openDay(day){
function openDay(day){


     selectedDay=day;
     selectedDay = day;


     document.getElementById("modal").style.display="block";
     document.getElementById("modal").style.display="flex";
     document.getElementById("modalDate").innerText=
     document.getElementById("modalDate").textContent =
    `Tag ${day}. August 2026`;
        `Samstag, ${day}. August 2026`.replace("Samstag", new Date(2026,7,day)
        .toLocaleDateString("de-DE",{weekday:"long"}));


     showEntries(day);
     renderEntries();
}
}


Zeile 226: Zeile 221:
}
}


function saveEntry(){
function renderEntries(){


     const data=loadData();
     const container = document.getElementById("entriesContainer");
    container.innerHTML = "";


     const entry={
     if(!data[selectedDay]){
         angebot:angebot.value,
         data[selectedDay] = [];
         uhrzeit:uhrzeit.value,
    }
         ort:ort.value,
 
         zielgruppe:zielgruppe.value,
    data[selectedDay].forEach((entry,index)=>{
        anmeldung:anmeldung.value,
 
        link:link.value,
         const card = document.createElement("div");
        beschreibung:beschreibung.value
         card.className = "entry-card";
    };
 
         card.innerHTML = `
            <label>Angebot</label>
            <input value="${entry.angebot || ''}" onchange="updateField(${index},'angebot',this.value)">


    const tage=[selectedDay];
            <label>Uhrzeit</label>
            <input value="${entry.uhrzeit || ''}" onchange="updateField(${index},'uhrzeit',this.value)">


    if(weitereTermine.value.trim()){
            <label>Treffpunkt/Ort</label>
            <input value="${entry.ort || ''}" onchange="updateField(${index},'ort',this.value)">


        weitereTermine.value
            <label>Zielgruppe</label>
        .split(",")
            <input value="${entry.zielgruppe || ''}" onchange="updateField(${index},'zielgruppe',this.value)">
        .forEach(t=>{


             const n=parseInt(t.trim());
             <label>Anmeldung</label>
            <input value="${entry.anmeldung || ''}" onchange="updateField(${index},'anmeldung',this.value)">


             if(n>=1 && n<=31){
             <label>Link zum Angebot</label>
                tage.push(n);
            <input value="${entry.link || ''}" onchange="updateField(${index},'link',this.value)">
            }


        });
            <label>Beschreibung</label>
    }
            <textarea rows="4" onchange="updateField(${index},'beschreibung',this.value)">${entry.beschreibung || ''}</textarea>


    tage.forEach(tag=>{
            <div class="actions">
                <button onclick="copyEntry(${index})">Kopieren</button>
                <button onclick="deleteEntry(${index})">Löschen</button>
            </div>
        `;


         if(!data[tag]){
         container.appendChild(card);
            data[tag]=[];
    });
        }
}


        data[tag].push(entry);
function addEntry(){


    data[selectedDay].push({
        angebot:"",
        uhrzeit:"",
        ort:"",
        zielgruppe:"",
        anmeldung:"",
        link:"",
        beschreibung:""
     });
     });


     saveData(data);
     saveData();
    renderEntries();
}


    render();
function updateField(index, field, value){
    showEntries(selectedDay);


     document.querySelectorAll("input,textarea")
     data[selectedDay][index][field] = value;
    .forEach(f=>{
        if(f.id!=="weitereTermine"){
            f.value="";
        }
    });


     weitereTermine.value="";
     saveData();
}
}


function showEntries(day){
function deleteEntry(index){


     const data=loadData();
     if(confirm("Eintrag löschen?")){


    const list=document.getElementById("entryList");
        data[selectedDay].splice(index,1);
 
        saveData();
        renderEntries();
    }
}


    list.innerHTML="<h3>Vorhandene Einträge</h3>";
function copyEntry(index){


     (data[day]||[]).forEach((e,index)=>{
     const copy = JSON.parse(
        JSON.stringify(data[selectedDay][index])
    );


        const div=document.createElement("div");
    data[selectedDay].push(copy);


        div.className="saved-entry";
    saveData();
    renderEntries();
}


        div.innerHTML=`
function exportData(){
        <strong>${e.angebot}</strong><br>
        Uhrzeit: ${e.uhrzeit}<br>
        Ort: ${e.ort}<br>
        Zielgruppe: ${e.zielgruppe}<br>
        Anmeldung: ${e.anmeldung}<br>
        <a href="${e.link}" target="_blank">Link</a><br>
        ${e.beschreibung}<br><br>
        <button onclick="deleteEntry(${day},${index})">
        Löschen
        </button>
        `;


         list.appendChild(div);
    const blob = new Blob(
         [JSON.stringify(data,null,2)],
        {type:"application/json"}
    );


     });
     const a = document.createElement("a");
    a.href = URL.createObjectURL(blob);
    a.download = "familienangebote_august_2026.json";
    a.click();
}
}


function deleteEntry(day,index){
function importData(event){


     const data=loadData();
     const file = event.target.files[0];
    if(!file) return;


     data[day].splice(index,1);
     const reader = new FileReader();


     saveData(data);
     reader.onload = e => {
 
        data = JSON.parse(e.target.result);
 
        saveData();
 
        alert("Import erfolgreich.");
    };


     render();
     reader.readAsText(file);
    showEntries(day);
}
}


render();
renderCalendar();


</script>
</script>

Version vom 9. Juni 2026, 09:43 Uhr

<!DOCTYPE html> Familienangebote August 2026

Familienangebote – August 2026