├── README.md ├── test.js ├── foto └── icon.png ├── firebaseConfig.js ├── index.html ├── style.css └── main.js /README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | test -------------------------------------------------------------------------------- /foto/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/berthutapea/firebase/HEAD/foto/icon.png -------------------------------------------------------------------------------- /firebaseConfig.js: -------------------------------------------------------------------------------- 1 | const firebaseConfig = { 2 | apiKey: "AIzaSyDfPKy3dOy_7jdoympDUyIDY3NlXpcjgTE", 3 | authDomain: "comment-wedding.firebaseapp.com", 4 | projectId: "comment-wedding", 5 | storageBucket: "comment-wedding.appspot.com", 6 | messagingSenderId: "49578215033", 7 | appId: "1:49578215033:web:2be1955756e491505376a8", 8 | }; 9 | 10 | // Initialize Firebase 11 | const app = firebase.initializeApp(firebaseConfig); 12 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Test Comment 9 | 10 | 11 | 12 | 13 | 14 | 15 |

Ucapan

16 |

Merupakan suatu kehormatan dan kebahagiaan bagi kami sekeluarga apabila Bapak/Ibu/Saudara/i berkenan hadir untuk 17 | memberikan doa restu kepada kedua mempelai.

18 |
19 | 20 |

21 | 22 |
23 |
25 |
28 | 34 |

35 | 36 |
37 | 38 | 41 | 42 | 45 |
46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: Arial; 3 | margin: 0; 4 | padding: 0; 5 | background-color: transparent; 6 | background-image: linear-gradient(180deg, #A5A5A5 0%, #353535 100%); 7 | } 8 | 9 | h1 { 10 | text-align: center; 11 | color: #333; 12 | margin: 20px 0; 13 | } 14 | 15 | p { 16 | margin: 20px auto; 17 | color: rgb(0, 0, 0); 18 | font-size: 18px; 19 | line-height: 1.5; 20 | max-width: 800px; 21 | } 22 | 23 | #item { 24 | max-width: 600px; 25 | margin: auto; 26 | background-color: rgb(255, 255, 255); 27 | border-radius: 15px; 28 | padding: 20px; 29 | box-shadow: 0px 2px 10px 0px rgb(0 0 0 / 50%) 30 | } 31 | 32 | #comment-count { 33 | text-align: center; 34 | padding-bottom: 15px; 35 | border-bottom: 1px solid #ccc 36 | } 37 | 38 | 39 | form { 40 | max-width: 600px; 41 | margin: 0 auto; 42 | display: flex; 43 | flex-direction: column; 44 | align-items: stretch; 45 | padding: 10px; 46 | } 47 | 48 | input[type="text"], 49 | textarea { 50 | border: 1px solid #ccc; 51 | border-radius: 4px; 52 | padding: 10px; 53 | font-size: 16px; 54 | overflow: hidden; 55 | overflow-wrap: break-word; 56 | box-sizing: border-box; 57 | resize: vertical !important; 58 | } 59 | 60 | select { 61 | border: 1px solid #ccc; 62 | border-radius: 4px; 63 | padding: 10px; 64 | font-size: 16px; 65 | appearance: auto; 66 | } 67 | 68 | button[type="submit"] { 69 | background-color: #1e1c1c; 70 | color: white; 71 | font-size: 16px; 72 | padding: 10px 20px; 73 | border: none; 74 | border-radius: 4px; 75 | cursor: pointer; 76 | } 77 | 78 | form button[type="submit"]:hover { 79 | background-color: #020a7e; 80 | } 81 | 82 | 83 | #ucapan-container { 84 | max-width: 600px; 85 | margin: 10px auto; 86 | overflow-y: scroll; 87 | overflow-x: scroll; 88 | max-height: 100vh; 89 | -ms-overflow-style: none; 90 | scrollbar-width: none; 91 | } 92 | 93 | #ucapan-container h3 { 94 | font-size: 20px; 95 | margin: 0; 96 | word-wrap: break-word; 97 | font-weight: bold; 98 | color: #7B6945; 99 | padding: 10px 15px 6px !important; 100 | border-top: 1px solid #ccc; 101 | 102 | } 103 | 104 | #ucapan-container span { 105 | color: rgb(51, 0, 255); 106 | font-size: 15px; 107 | text-transform: capitalize; 108 | padding: 10px 15px 6px !important; 109 | } 110 | 111 | #ucapan-container p { 112 | font-size: 18px; 113 | margin: 0; 114 | word-wrap: break-word; 115 | padding: 10px 15px 6px !important; 116 | } 117 | 118 | #ucapan-container small { 119 | color: #333; 120 | margin: 0; 121 | padding: 10px 12px 6px !important; 122 | } 123 | 124 | img { 125 | height: 15px; 126 | width: 15px; 127 | position: relative; 128 | top: 1px; 129 | } 130 | 131 | .success { 132 | color: green; 133 | } 134 | 135 | .error { 136 | color: red; 137 | } -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const rdb = firebase.database(); 2 | 3 | const form = document.getElementById('form'); 4 | 5 | 6 | form.addEventListener('submit', (event) => { 7 | // Mencegah pengiriman data default ke Firebase 8 | event.preventDefault(); 9 | // Tangkap data yang dimasukkan ke form 10 | var nama = document.getElementById("nama").value; 11 | var ucapan = document.getElementById("ucapan").value; 12 | var kehadiran = document.querySelector("select").value; 13 | var tanggalWaktu = new Date(); 14 | 15 | // Kirim data ke Firebase 16 | firebase.database().ref("ucapan").push({ 17 | nama: nama, 18 | ucapan: ucapan, 19 | kehadiran: kehadiran, 20 | tanggalWaktu: tanggalWaktu.toString(), 21 | 22 | }).then(function () { 23 | // Tampilkan pesan sukses 24 | var successMessage = document.createElement("p"); 25 | successMessage.innerHTML = "Terima Kasih, Ucapan Anda Sudah Terkirim!"; 26 | successMessage.classList.add("success"); 27 | form.appendChild(successMessage); 28 | 29 | // Hapus pesan sukses setelah 3 detik 30 | setTimeout(function () { 31 | successMessage.remove(); 32 | }, 3000); 33 | }).catch(function (error) { 34 | // Tampilkan pesan error 35 | var errorMessage = document.createElement("p"); 36 | errorMessage.innerHTML = "Maaf, terjadi kesalahan saat mengirim ucapan Anda. Silakan coba lagi nanti."; 37 | errorMessage.classList.add("error"); 38 | form.appendChild(errorMessage); 39 | 40 | // Hapus pesan error setelah 3 detik 41 | setTimeout(function () { 42 | errorMessage.remove(); 43 | }, 3000); 44 | }); 45 | // Kosongkan form setelah data terkirim 46 | form.reset(); 47 | }); 48 | 49 | // Dapatkan referensi ke database Firebase 50 | var sayingRef = firebase.database().ref("ucapan"); 51 | 52 | // Dapatkan ucapan terbaru saat halaman dimuat 53 | sayingRef.on("value", function (snapshot) { 54 | // Hapus konten yang ada sebelumnya 55 | var sayingContainer = document.getElementById("ucapan-container"); 56 | sayingContainer.innerHTML = ""; 57 | 58 | // Dapatkan elemen HTML untuk menampilkan jumlah komentar ucapan 59 | var commentCountEl = document.getElementById("comment-count"); 60 | 61 | // Dapatkan ucapan terbaru saat halaman dimuat 62 | sayingRef.on("value", function (snapshot) { 63 | // Tampilkan jumlah komentar ucapan yang ada di database 64 | commentCountEl.innerHTML = snapshot.numChildren() + " Ucapan" + " "; 65 | }); 66 | 67 | // Tambahkan event listener untuk mendeteksi adanya data komentar baru 68 | sayingRef.on("child_added", function (childSnapshot) { 69 | // Tampilkan jumlah komentar ucapan yang ada di database setiap ada data komentar baru 70 | commentCountEl.innerHTML = snapshot.numChildren() + " Ucapan" + " "; 71 | }); 72 | 73 | // Tampilkan setiap ucapan 74 | snapshot.forEach(function (childSnapshot) { 75 | var say = childSnapshot.val(); 76 | displaySay( 77 | say.nama, 78 | say.ucapan, 79 | say.kehadiran, 80 | say.tanggalWaktu 81 | ); 82 | }); 83 | }); 84 | 85 | // Fungsi untuk menampilkan ucapan 86 | function displaySay(nama, ucapan, kehadiran, tanggalWaktu) { 87 | // Buat elemen div untuk menampilkan ucapan 88 | var sayEl = document.createElement("div"); 89 | 90 | // Hitung waktu yang lalu 91 | const input = tanggalWaktu; 92 | const date = Date.parse(input); 93 | const now = Date.now(); 94 | const diff = now - date; 95 | 96 | const years = Math.floor(diff / (1000 * 60 * 60 * 24 * 365)); 97 | const months = Math.floor(diff / (1000 * 60 * 60 * 24 * 30)); 98 | const weeks = Math.floor(diff / (1000 * 60 * 60 * 24 * 7)); 99 | const days = Math.floor(diff / (1000 * 60 * 60 * 24)); 100 | const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 101 | const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60)); 102 | 103 | let timeAgo; 104 | if (years > 0) { 105 | timeAgo = years + ' tahun'; 106 | if (months > 0) { 107 | timeAgo += ' ' + months + ' bulan'; 108 | } 109 | timeAgo += ' yang lalu'; 110 | } else if (months > 0) { 111 | timeAgo = months + ' bulan'; 112 | if (weeks > 0) { 113 | timeAgo += ' ' + weeks + ' minggu'; 114 | } 115 | timeAgo += ' yang lalu'; 116 | } else if (weeks > 0) { 117 | timeAgo = weeks + ' minggu'; 118 | if (days > 0) { 119 | timeAgo += ' ' + days + ' hari'; 120 | } 121 | timeAgo += ' yang lalu'; 122 | } else if (days > 0) { 123 | timeAgo = days + ' hari'; 124 | if (hours > 0) { 125 | timeAgo += ' ' + hours + ' jam'; 126 | } 127 | timeAgo += ' yang lalu'; 128 | } else if (hours > 0) { 129 | timeAgo = hours + ' jam'; 130 | if (minutes > 0) { 131 | timeAgo += ' ' + minutes + ' menit'; 132 | } 133 | timeAgo += ' yang lalu'; 134 | } else if (minutes > 0) { 135 | timeAgo = minutes + ' menit yang lalu'; 136 | } else { 137 | timeAgo = 'baru saja'; 138 | } 139 | 140 | // Tambahkan waktu yang lalu ke elemen div 141 | sayEl.innerHTML = 142 | "

" + 143 | nama + 144 | "Verified icon

" + 145 | kehadiran + 146 | "

" + 147 | ucapan + 148 | "

🕓 " + 149 | timeAgo + 150 | ""; 151 | 152 | // Tambahkan elemen div ke container ucapan sebagai elemen pertama 153 | var sayingContainer = document.getElementById("ucapan-container"); 154 | sayingContainer.insertBefore(sayEl, sayingContainer.firstChild); 155 | } 156 | --------------------------------------------------------------------------------