Kode ini membangun sebuah form yang mengizinkan pengguna untuk membuat postingan di Blogger melalui integrasi dengan Firebase dan API Google Blogger. Form ini juga mendukung unggahan gambar yang akan diresize dan disimpan di Firebase Storage. Semua data yang disimpan akan ditampilkan dalam tabel yang juga menyertakan fitur delete untuk menghapus postingan.
<style>
body {
font-family: Arial, sans-serif;
}
#user-table {
width: 100%;
overflow-x: auto;
display: block;
margin-top: 20px;
border-collapse: collapse;
}
#user-table th, #user-table td {
padding: 8px;
border: 1px solid #ddd;
}
#user-table thead {
background-color: #f2f2f2;
}
.custom-form {
background-color: #ffffff;
padding: 20px;
border-radius: 8px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
max-width: 600px;
width: 100%;
margin-top: 20px;
}
.custom-form label {
display: block;
margin-bottom: 8px;
color: #495057;
}
.custom-form input,
.custom-form select,
.custom-form textarea {
width: 100%;
padding: 10px;
margin-bottom: 16px;
box-sizing: border-box;
border: 1px solid #ced4da;
border-radius: 10px;
font-size: 14px;
}
.custom-form textarea {
resize: vertical;
}
.custom-form button {
background-color: #28a745;
color: #ffffff;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
.custom-form button:hover {
background-color: #218838;
}
</style>
<form id="blogPostForm" class="custom-form">
<label for="title">judul :</label>
<input type="text" id="title" name="title" required>
<label for="content">isi :</label>
<textarea id="content" name="content" required></textarea>
<label for="imageFile">gambar/logo :</label>
<input type="file" id="imageFile" name="imageFile" accept="image/*" required>
<label for="labels">label (misal Jakarta, Surabaya, Senior Staff, Manager):</label>
<input type="text" id="labels" name="labels">
<label for="expired">expired :</label>
<input type="date" id="expired" name="expired" required>
<button type="submit" id="submitBtn">Pasang lowongan anda</button>
</form>
<h2>Lowongan Anda</h2>
<table id="user-table">
<thead>
<tr>
<th>Gambar/Logo</th>
<th>Judul Lowongan</th>
<th>Tanggal Terbit</th>
<th>Tanggal Kedaluwarsa</th>
<th>Jumlah View</th>
<th>Email</th>
<th>Aksi</th>
</tr>
</thead>
<tbody id="imageDataList"></tbody>
</table>
<script>
// Fungsi untuk mendapatkan refresh token dari Firebase
async function getRefreshToken() {
var db = firebase.firestore();
const doc = await db.collection('tokens').doc('refreshToken').get();
if (doc.exists) {
return doc.data().token;
} else {
throw new Error('Token refresh tidak ditemukan di Firebase');
}
}
// Fungsi untuk mendapatkan access token baru menggunakan refresh token
async function getAccessToken(refreshToken) {
const response = await fetch('https://oauth2.googleapis.com/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: 'isi dengan client ID di google console',
client_secret: 'isi dengan client secreet di google console',
refresh_token: refreshToken,
grant_type: 'refresh_token'
})
});
const data = await response.json();
if (data.access_token) {
return data.access_token;
} else {
throw new Error('Gagal mendapatkan access token: ' + JSON.stringify(data));
}
}
// Fungsi untuk mengunggah gambar ke Firebase Storage
async function uploadImage(file) {
const storageRef = firebase.storage().ref();
const fileRef = storageRef.child(`images/${file.name}`);
await fileRef.put(file);
return await fileRef.getDownloadURL();
}
// Fungsi untuk menyimpan data gambar ke Firestore
async function saveImageData(imageUrl, userID, userEmail, postID, postTitle, postUrl, publishedDate, expiredDate) {
var db = firebase.firestore();
await db.collection('images').add({
imageUrl: imageUrl,
userID: userID,
userEmail: userEmail,
postID: postID,
postTitle: postTitle,
postUrl: postUrl,
publishedDate: publishedDate,
expiredDate: expiredDate
});
}
// Fungsi untuk membuat postingan di Blogger menggunakan access token
async function createBloggerPost(accessToken, title, content, imageUrl, labels, expired) {
const blogId = 'isi dengan ID blog anda'; // Ganti dengan ID Blog Anda
const postUrl = `https://www.googleapis.com/blogger/v3/blogs/${blogId}/posts/`;
if (imageUrl) {
content = `<img src="${imageUrl}" alt="Gambar"><br>` + content;
}
content += `<br>Expired date: ${expired}`;
const postData = {
title: title,
content: content.replace(/\n/g, '<br>'),
labels: labels ? labels.split(',').map(label => label.trim()) : []
};
const response = await fetch(postUrl, {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(postData)
});
if (response.ok) {
const post = await response.json();
console.log('Posting berhasil dibuat:', post);
const user = firebase.auth().currentUser;
const userID = user.uid;
const userEmail = user.email;
const postID = post.id;
const postTitle = post.title;
const postUrl = post.url;
const publishedDate = new Date(post.published).toLocaleString();
const expiredDate = expired;
await saveImageData(imageUrl, userID, userEmail, postID, postTitle, postUrl, publishedDate, expiredDate);
displayImageData(imageUrl, userID, userEmail, postID, postTitle, postUrl, publishedDate, expiredDate);
alert("Data sudah ditayangkan");
const form = document.getElementById('blogPostForm');
var btn = document.getElementById("submitBtn");
btn.innerHTML = "Pasang lowongan anda";
btn.disabled = false;
form.reset();
} else {
const error = await response.json();
console.error('Gagal membuat postingan:', error);
}
}
// Fungsi utama untuk menangani proses submit form
async function main(event) {
event.preventDefault(); // Mencegah form submit default
try {
const form = document.getElementById('blogPostForm');
var btn = document.getElementById("submitBtn");
btn.innerHTML = "tunggu data disimpan...";
btn.disabled = true;
const title = form.title.value;
const content = form.content.value;
const imageFile = form.imageFile.files[0];
const labels = form.labels.value;
const expired = form.expired.value;
const resizedImage = await resizeImage(imageFile, 600, 600);
const randomString = generateRandomString(3);
const fileExtension = imageFile.name.split('.').pop();
const newFileName = `${imageFile.name.split('.').slice(0, -1).join('.')}_${randomString}.${fileExtension}`;
const user = firebase.auth().currentUser;
const userID = user.uid;
const storageRef = firebase.storage().ref();
const imageRef = storageRef.child(`${userID}/${newFileName}`);
const uploadTaskSnapshot = await imageRef.put(resizedImage);
const imageUrl = await uploadTaskSnapshot.ref.getDownloadURL();
const refreshToken = await getRefreshToken();
const accessToken = await getAccessToken(refreshToken);
await createBloggerPost(accessToken, title, content, imageUrl, labels, expired);
} catch (error) {
console.error('Terjadi kesalahan dalam fungsi utama:', error);
}
}
// Event listener untuk form submit
document.getElementById('blogPostForm').addEventListener('submit', main);
// Fungsi untuk menampilkan data gambar yang disimpan
function displayImageData(imageUrl, userID, userEmail, postID, postTitle, postUrl, publishedDate, expiredDate) {
const imageDataList = document.getElementById('imageDataList');
const listItem = document.createElement('tr');
const user = firebase.auth().currentUser;
const userIDku = user.uid;
if (userID !== userIDku) {
return; // Jika userID tidak sesuai dengan user yang sedang login, keluar dari fungsi
}
listItem.innerHTML = `
<td><img src="${imageUrl}" style="max-width: 100px;"></td>
<td><a href="${postUrl}" target="_blank">${postTitle}</a></td>
<td>${publishedDate}</td>
<td>${expiredDate}</td>
<td>loading..</td>
<td>${userEmail}</td>
<td><button onclick="deleteImageData('${postID}')">Delete</button></td>
`;
imageDataList.appendChild(listItem);
// Ambil jumlah view dari Blogger API dan tampilkan
fetch(`https://www.googleapis.com/blogger/v3/blogs/3012084879947884101/posts/${postID}?key=AIzaSyC41jj8xa6neO0lXgBkUf_P5hwq0I2GLSw`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok ' + response.statusText);
}
return response.json();
})
.then(data => {
const postView = data.statistics && data.statistics.viewCount ? data.statistics.viewCount : 'N/A';
listItem.querySelector('td:nth-child(5)').textContent = postView;
})
.catch(error => {
console.error('Gagal mengambil jumlah view:', error);
listItem.querySelector('td:nth-child(5)').textContent = 'Error';
});
}
// Fungsi untuk menghapus data gambar dari Firestore
async function deleteImageData(postID) {
try {
console.log('Mencoba menghapus posting dengan ID:', postID);
var db = firebase.firestore();
const imagesRef = db.collection('images');
const snapshot = await imagesRef.where('postID', '==', postID).get();
if (!snapshot.empty) {
snapshot.forEach(async (doc) => {
await imagesRef.doc(doc.id).delete().then(() => {
console.log(`Dokumen dengan ID terhapus: ${doc.id}`);
}).catch((error) => {
console.error(`Error menghapus dokumen dengan ID: ${doc.id}`, error);
});
});
// Hapus baris dari tabel
const rows = document.querySelectorAll('#imageDataList tr');
rows.forEach(row => {
if (row.cells[3].textContent === postID) {
row.remove();
}
});
console.log('Data gambar berhasil dihapus');
const accessToken = await getAccessToken(await getRefreshToken());
deletePost(postID, accessToken);
} else {
console.log('Dokumen tidak ditemukan');
}
} catch (error) {
console.error('Terjadi kesalahan dalam menghapus data gambar:', error);
}
}
// Fungsi untuk menghapus postingan dari Blogger
async function deletePost(postID, accessToken) {
const blogId = '3012084879947884101'; // Ganti dengan ID Blog Anda
const apiKey = 'AIzaSyC41jj8xa6neO0lXgBkUf_P5hwq0I2GLSw'; // Ganti dengan API Key Anda
fetch(`https://www.googleapis.com/blogger/v3/blogs/${blogId}/posts/${postID}?key=${apiKey}`, {
method: 'DELETE',
headers: {
'Authorization': `Bearer ${accessToken}`
},
})
.then(response => {
if (response.ok) {
console.log('Postingan berhasil dihapus');
alert("Postingan berhasil dihapus");
var row = document.querySelector(`tr[data-post-id="${postID}"]`);
if (row) {
row.remove();
}
location.reload();
} else {
console.error('Gagal menghapus postingan. Status:', response.status);
alert("Postingan gagal dihapus");
}
})
.catch((error) => {
console.error('Error:', error);
});
}
// Memanggil fungsi untuk fetch dan menampilkan data gambar saat halaman dimuat
async function fetchAndDisplayImageData() {
try {
var db = firebase.firestore();
const imagesRef = db.collection('images');
const snapshot = await imagesRef.get();
snapshot.forEach(doc => {
const imageData = doc.data();
displayImageData(
imageData.imageUrl,
imageData.userID,
imageData.userEmail,
imageData.postID,
imageData.postTitle,
imageData.postUrl,
imageData.publishedDate,
imageData.expiredDate
);
});
} catch (error) {
console.error('Terjadi kesalahan dalam mengambil data gambar:', error);
}
}
// Memanggil fungsi untuk fetch dan menampilkan data gambar saat halaman dimuat
fetchAndDisplayImageData();
// Fungsi untuk mengubah ukuran gambar
function resizeImage(file, maxWidth, maxHeight) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(event) {
const img = new Image();
img.src = event.target.result;
img.onload = function() {
let width = img.width;
let height = img.height;
if (width > height) {
if (width > maxWidth) {
height *= maxWidth / width;
width = maxWidth;
}
} else {
if (height > maxHeight) {
width *= maxHeight / height;
height = maxHeight;
}
}
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob((blob) => {
resolve(blob);
}, file.type);
};
};
reader.onerror = function(error) {
reject(error);
};
});
}
// Fungsi untuk menghasilkan string acak
function generateRandomString(length) {
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let result = '';
for (let i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * characters.length));
}
return result;
}
</script>
Post a Comment