Gästebuch Block

Anwendungen für Webseiten. Künstliche Intelligenz verwenden.
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8526
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Gästebuch Block

Ungelesener Beitrag von Tommy Herrmann »

Ja - auf jeden Fall, ich verweise als Download auf Deine Seite:

https://www.mobirise-tutorials.com/AI-B ... tbuch.html
Volker
Moderator
Moderator
Beiträge: 2465
Registriert: Sa 12. Dez 2020, 22:35

Re: Gästebuch Block

Ungelesener Beitrag von Volker »

Tommy halt dich fest :D

jetzt mache ich dieses Gästebuch auch noch im Bento Style und in einer Schlichten Version, so hat der User ebi Import der Erweiterung 3 Blöcke zur Auswahl ;)

Super Idee :cool:
Volker
Moderator
Moderator
Beiträge: 2465
Registriert: Sa 12. Dez 2020, 22:35

Re: Gästebuch Block

Ungelesener Beitrag von Volker »

Tommy !!!!

Die KI hat geschlampt :D

Im Java Script die Smileys vergessen klickbar zu mache :crying:

Hier das Java Script für Dich

Code: Alles auswählen

 <script>
    (function() {
        var inBuilder = (typeof MbrsiteApp !== 'undefined') || (window.self !== window.top && /mobirise/i.test(document.referrer));
        if (inBuilder) return;

        var apiPath = 'guestbook-api.php';
        var feedContainer = document.getElementById('js-guestbook-feed');
        var paginationContainer = document.getElementById('js-gb-pagination');
        var form = document.getElementById('js-guestbook-form');
        var statusDiv = document.getElementById('gb-status');
        var msgField = document.getElementById('gb-message');
        
        var currentSection = document.getElementById('js-guestbook-feed') ? document.getElementById('js-guestbook-feed').closest('section') : null;
        
        var allEntries = [];
        var currentPage = 1;
        var itemsPerPage = parseInt('{{perPage}}') || 5;
        
        var isAdmin = false;
        var enteredPassword = ''; 

        if (currentSection) {
            var titleEl = currentSection.querySelector('.js-gb-main-title');
            if (titleEl) {
                titleEl.addEventListener('dblclick', function(e) {
                    e.preventDefault();
                    var pwCheck = prompt('Bitte Admin-Passwort eingeben:');
                    if (pwCheck !== null && pwCheck.trim() !== '') {
                        fetch(apiPath, {
                            method: 'POST',
                            headers: { 'Content-Type': 'application/json' },
                            body: JSON.stringify({ action: 'checkLogin', password: pwCheck.trim() })
                        })
                        .then(response => response.json())
                        .then(data => {
                            if (data.success) {
                                isAdmin = true;
                                enteredPassword = pwCheck.trim();
                                alert('Login erfolgreich! Ungeprüfte Beiträge zeigen jetzt das Freischaltfeld. 🔓');
                                loadEntries(); 
                            } else {
                                alert(data.error);
                            }
                        });
                    }
                });
            }

            // 🔥 FIX: Hier ist das Bindungs-Skript für deine Emoji-Bar!
            var emojiButtons = currentSection.querySelectorAll('.emoji-bar .emoji-btn');
            emojiButtons.forEach(function(btn) {
                btn.addEventListener('click', function(e) {
                    e.preventDefault();
                    var chosenEmoji = btn.textContent.replace('Anzeigen', '').trim(); // Bereinigt eventuelle Rückstände
                    if (msgField) {
                        var start = msgField.selectionStart;
                        var end = msgField.selectionEnd;
                        var text = msgField.value;
                        msgField.value = text.substring(0, start) + chosenEmoji + text.substring(end);
                        msgField.focus();
                        msgField.selectionStart = msgField.selectionEnd = start + chosenEmoji.length;
                    }
                });
            });
        }

        function renderFeed() {
            if (!feedContainer) return;
            if (!allEntries || allEntries.length === 0) {
                feedContainer.innerHTML = '<div class="text-center py-4 text-fallback">Noch keine freigeschalteten Einträge vorhanden.</div>';
                if (paginationContainer) paginationContainer.innerHTML = '';
                return;
            }

            var startIndex = (currentPage - 1) * itemsPerPage;
            var endIndex = startIndex + itemsPerPage;
            var pageEntries = allEntries.slice(startIndex, endIndex);

            var html = '';
            pageEntries.forEach(function(entry) {
                var date = new Date(entry.created_at.replace(/-/g, "/"));
                var formattedDate = date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' - ' + date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr';
                
                var styleOverride = (entry.status == 0) ? 'style="border: 1px solid #eab308 !important; background: rgba(234, 179, 8, 0.08) !important;"' : '';
                var titleAddon = (entry.status == 0) ? ' <span style="color:#eab308;font-size:0.75rem;">(Wartet auf Freischaltung)</span>' : '';

                html += '<div class="guestbook-entry-card mb-3 glass-card" data-id="' + entry.id + '" ' + styleOverride + '>';
                html += '  <div class="entry-header">';
                html += '    <strong class="entry-author">' + entry.name + titleAddon + '</strong>';
                html += '    <div class="d-flex align-items-center gap-3">';
                html += '      <span class="entry-date">' + formattedDate + '</span>';
                
                if (isAdmin) {
                    html += '   <button class="btn-edit-entry" title="Eintrag bearbeiten" style="background:none; border:none; cursor:pointer; font-size:1.1rem; padding:0; line-height:1;">✏️</button>';
                    html += '   <button class="btn-delete-entry" title="Eintrag löschen" style="background:none; border:none; cursor:pointer; font-size:1.1rem; padding:0; line-height:1;">🗑️</button>';
                }
                
                html += '    </div>';
                html += '  </div>';
                html += '  <p class="entry-text js-entry-text-target">' + entry.message.replace(/\n/g, '<br>') + '</p>';
                
                if (isAdmin && entry.status == 0) {
                    html += '  <div class="mt-3 text-end js-approve-wrapper">';
                    html += '    <button class="btn btn-sm btn-success btn-approve-action" style="padding: 6px 14px; font-size: 0.85rem; font-weight: bold; border-radius: 6px; border: none; background-color: #22c55e !important; color: #fff !important;">';
                    html += '       ✅ Eintrag freischalten';
                    html += '    </button>';
                    html += '  </div>';
                }
                
                html += '</div>';
            });
            feedContainer.innerHTML = html;

            if (isAdmin) {
                feedContainer.querySelectorAll('.btn-approve-action').forEach(function(btn) {
                    btn.addEventListener('click', function(e) {
                        e.stopPropagation();
                        var card = btn.closest('.guestbook-entry-card');
                        var id = card.getAttribute('data-id');
                        approveEntry(id, card);
                    });
                });

                feedContainer.querySelectorAll('.btn-delete-entry').forEach(function(btn) {
                    btn.addEventListener('click', function(e) {
                        e.stopPropagation();
                        var card = btn.closest('.guestbook-entry-card');
                        var id = card.getAttribute('data-id');
                        if (confirm('Möchtest du diesen Eintrag wirklich unwiderruflich löschen?')) {
                            deleteEntry(id, card);
                        }
                    });
                });

                feedContainer.querySelectorAll('.btn-edit-entry').forEach(function(btn) {
                    btn.addEventListener('click', function(e) {
                        e.stopPropagation();
                        var card = btn.closest('.guestbook-entry-card');
                        var id = card.getAttribute('data-id');
                        var textP = card.querySelector('.js-entry-text-target');
                        
                        if (card.classList.contains('is-editing')) return;
                        card.classList.add('is-editing');
                        
                        var origEntry = allEntries.find(item => item.id == id);
                        var currentRawText = origEntry ? origEntry.message : textP.innerText;
                        
                        textP.innerHTML = '<textarea class="form-control mb-2 js-edit-textarea" rows="4" style="color:#000 !important; background:#fff !important;">' + currentRawText + '</textarea>' +
                                          '<button class="btn btn-sm btn-success js-save-edit-btn" style="padding:4px 10px; font-size:0.8rem;">💾 Speichern</button> ' +
                                          '<button class="btn btn-sm btn-danger js-cancel-edit-btn" style="padding:4px 10px; font-size:0.8rem;">Abbrechen</button>';
                        
                        card.querySelector('.js-save-edit-btn').addEventListener('click', function() {
                            var newText = card.querySelector('.js-edit-textarea').value;
                            updateEntryText(id, newText, card);
                        });

                        card.querySelector('.js-cancel-edit-btn').addEventListener('click', function() {
                            renderFeed();
                        });
                    });
                });
            }

            renderPaginationControls();
        }

        function approveEntry(id, card) {
            fetch(apiPath, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ action: 'approve', id: id, password: enteredPassword })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    var entry = allEntries.find(item => item.id == id);
                    if (entry) entry.status = 1;
                    renderFeed(); 
                } else {
                    alert(data.error);
                }
            })
            .catch(err => alert('Fehler bei der Freischaltung.'));
        }

        function updateEntryText(id, newText, card) {
            fetch(apiPath, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ action: 'update', id: id, message: newText, password: enteredPassword })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    var entry = allEntries.find(item => item.id == id);
                    if (entry) entry.message = newText;
                    renderFeed();
                } else {
                    alert(data.error);
                }
            })
            .catch(err => alert('Fehler beim Speichern.'));
        }

        function renderPaginationControls() {
            if (!paginationContainer) return;
            var totalPages = Math.ceil(allEntries.length / itemsPerPage);
            if (totalPages <= 1) {
                paginationContainer.innerHTML = '';
                return;
            }

            var html = '';
            html += '<button class="pag-btn" data-page="' + (currentPage - 1) + '"' + (currentPage === 1 ? ' disabled' : '') + '>«</button>';
            for (var i = 1; i <= totalPages; i++) {
                html += '<button class="pag-btn' + (i === currentPage ? ' active' : '') + '" data-page="' + i + '">' + i + '</button>';
            }
            html += '<button class="pag-btn" data-page="' + (currentPage + 1) + '"' + (currentPage === totalPages ? ' disabled' : '') + '>»</button>';

            paginationContainer.innerHTML = html;

            paginationContainer.querySelectorAll('.pag-btn').forEach(function(btn) {
                btn.addEventListener('click', function() {
                    var targetPage = parseInt(btn.getAttribute('data-page'));
                    if (targetPage >= 1 && targetPage <= totalPages) {
                        currentPage = targetPage;
                        renderFeed();
                        feedContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
                    }
                });
            });
        }

        function loadEntries() {
            var url = apiPath + (isAdmin ? '?adminCheck=' + encodeURIComponent(enteredPassword) : '');
            fetch(url)
                .then(response => response.json())
                .then(data => {
                    if (!data.success) {
                        feedContainer.innerHTML = '<div class="alert alert-danger">' + data.error + '</div>';
                        return;
                    }
                    allEntries = data.entries || [];
                    renderFeed();
                })
                .catch(err => {
                    if(feedContainer) {
                        feedContainer.innerHTML = '<div class="text-center py-4 text-fallback">Warte auf ersten Eintrag...</div>';
                    }
                });
        }

        function deleteEntry(id, card) {
            fetch(apiPath, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ action: 'delete', id: id, password: enteredPassword })
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    card.style.transition = 'all 0.3s ease';
                    card.style.opacity = '0';
                    card.style.transform = 'scale(0.9)';
                    setTimeout(function() {
                        allEntries = allEntries.filter(entry => entry.id != id);
                        var totalPages = Math.ceil(allEntries.length / itemsPerPage);
                        if (currentPage > totalPages && currentPage > 1) {
                            currentPage = totalPages;
                        }
                        renderFeed();
                    }, 300);
                } else {
                    alert(data.error);
                }
            });
        }

        if (form) {
            form.addEventListener('submit', function(e) {
                e.preventDefault();
                var nameVal = document.getElementById('gb-name').value;
                var msgVal = msgField.value;

                statusDiv.style.display = 'block';
                statusDiv.className = 'mt-3 small text-fallback';
                statusDiv.textContent = 'Eintrag wird zur Prüfung gesendet... ⏳';

                fetch(apiPath, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ name: nameVal, message: msgVal })
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        statusDiv.textContent = 'Vielen Dank! Dein Eintrag wird geprüft und bald freigeschaltet. 🎉';
                        form.reset();
                        currentPage = 1;
                        loadEntries();
                        setTimeout(function() { statusDiv.style.display = 'none'; }, 5000);
                    } else {
                        statusDiv.textContent = data.error;
                    }
                })
                .catch(err => {
                    statusDiv.textContent = 'Fehler beim Senden.';
                });
            });
        }

        loadEntries();
    })();
    </script>
Im Zip gleich auch drin
Benutzeravatar
Tommy Herrmann
Site Admin
Site Admin
Beiträge: 8526
Registriert: So 6. Dez 2020, 07:37
Wohnort: Berlin
Kontaktdaten:

Re: Gästebuch Block

Ungelesener Beitrag von Tommy Herrmann »

Alles klar, mache ich morgen früh ...
Antworten

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot] und 1 Gast