Masaüstünden temiz PocketBase kurulumu

This commit is contained in:
M. Batuhan Erkek
2026-01-30 02:17:27 +03:00
parent d00a5fac34
commit 5a513b41aa

259
admin.js
View File

@@ -1,194 +1,135 @@
import { initializeApp } from "https://www.gstatic.com/firebasejs/12.8.0/firebase-app.js";
import { getAnalytics } from "https://www.gstatic.com/firebasejs/12.8.0/firebase-analytics.js";
import {
getAuth,
onAuthStateChanged,
signInWithEmailAndPassword,
signOut,
} from "https://www.gstatic.com/firebasejs/12.8.0/firebase-auth.js";
import {
addDoc,
collection,
deleteDoc,
doc,
getFirestore,
onSnapshot,
orderBy,
query,
serverTimestamp,
} from "https://www.gstatic.com/firebasejs/12.8.0/firebase-firestore.js";
import PocketBase from 'https://cdnjs.cloudflare.com/ajax/libs/pocketbase/0.21.1/pocketbase.es.mjs';
const firebaseConfig = {
apiKey: "AIzaSyAdLH7HMwCMZ4lThoWGEiI5TEjfvBMXem8",
authDomain: "batuhanerkeksite.firebaseapp.com",
projectId: "batuhanerkeksite",
storageBucket: "batuhanerkeksite.firebasestorage.app",
messagingSenderId: "439489523058",
appId: "1:439489523058:web:ce15dc3127f1ce03a8c1eb",
measurementId: "G-FC46PNZJHX",
};
const app = initializeApp(firebaseConfig);
try {
getAnalytics(app);
} catch {
// Analytics optional in local/dev environments.
}
const auth = getAuth(app);
const db = getFirestore(app);
// 1. PocketBase Bağlantısı
// 'https://pocketbase.batuhanerkek.com' kısmını kendi domaininle değiştir
const pb = new PocketBase('https://pocketbase.batuhanerkek.com');
const loginCard = document.getElementById("login-card");
const adminPanel = document.getElementById("admin-panel");
const loginForm = document.getElementById("login-form");
const blogForm = document.getElementById("blog-form");
const postsList = document.getElementById("posts-list");
const logoutBtn = document.getElementById("logout-btn");
const postsList = document.getElementById("posts-list");
const tagsInput = document.getElementById("tags-input");
const tagsList = document.getElementById("tags-list");
let currentTags = [];
const postsRef = collection(db, "posts");
const renderPosts = (posts) => {
postsList.innerHTML = "";
if (!posts.length) {
const empty = document.createElement("div");
empty.className = "post-item";
empty.textContent = "Henüz blog yazısı yok.";
postsList.appendChild(empty);
return;
// Panel Görünümünü Ayarla
function setAuthState(isLoggedIn) {
if (isLoggedIn) {
loginCard.classList.add("hidden");
adminPanel.classList.remove("hidden");
loadPosts();
} else {
loginCard.classList.remove("hidden");
adminPanel.classList.add("hidden");
}
}
posts.forEach((post) => {
const wrapper = document.createElement("div");
wrapper.className = "post-item";
const title = document.createElement("h3");
title.textContent = post.title;
const meta = document.createElement("div");
meta.className = "post-meta";
const tagsLabel = post.tags?.length ? post.tags.join(", ") : "Etiket yok";
meta.textContent = `${post.date || "-"} · ${tagsLabel}`;
const summary = document.createElement("p");
summary.textContent = post.summary;
const actions = document.createElement("div");
actions.className = "post-actions";
const removeBtn = document.createElement("button");
removeBtn.className = "ghost";
removeBtn.type = "button";
removeBtn.textContent = "Sil";
removeBtn.addEventListener("click", () => {
deleteDoc(doc(db, "posts", post.id));
// 2. Giriş Yapma (PocketBase Auth)
loginForm.addEventListener("submit", async (event) => {
event.preventDefault();
const formData = new FormData(loginForm);
try {
await pb.collection('users').authWithPassword(
formData.get("email"),
formData.get("password")
);
loginForm.reset();
setAuthState(true);
} catch (error) {
alert("Giriş başarısız: " + error.message);
}
});
actions.appendChild(removeBtn);
wrapper.append(title, meta, summary, actions);
postsList.appendChild(wrapper);
// 3. Çıkış Yapma
logoutBtn.addEventListener("click", () => {
pb.authStore.clear();
setAuthState(false);
});
// 4. Yeni Yazı Kaydetme
blogForm.addEventListener("submit", async (event) => {
event.preventDefault();
const formData = new FormData(blogForm);
const newPost = {
title: formData.get("title").trim(),
tags: JSON.stringify(currentTags), // PocketBase için dizi formatı
summary: formData.get("summary").trim(),
content: formData.get("content").trim(),
date: formData.get("date"),
image: formData.get("image").trim(),
};
const setAuthState = (isLoggedIn) => {
loginCard.classList.toggle("hidden", isLoggedIn);
adminPanel.classList.toggle("hidden", !isLoggedIn);
};
const renderTags = () => {
tagsList.innerHTML = "";
if (!currentTags.length) return;
currentTags.forEach((tag, index) => {
const chip = document.createElement("span");
chip.className = "tag";
chip.textContent = tag;
const removeBtn = document.createElement("button");
removeBtn.type = "button";
removeBtn.setAttribute("aria-label", `${tag} etiketini kaldır`);
removeBtn.textContent = "×";
removeBtn.addEventListener("click", () => {
currentTags = currentTags.filter((_, i) => i !== index);
try {
await pb.collection('posts').create(newPost);
blogForm.reset();
currentTags = [];
renderTags();
loadPosts();
alert("Yazı başarıyla kaydedildi!");
} catch (error) {
alert("Kaydedilemedi: " + error.message);
}
});
chip.appendChild(removeBtn);
tagsList.appendChild(chip);
// 5. Yazıları Listeleme
async function loadPosts() {
try {
const records = await pb.collection('posts').getFullList({
sort: '-created',
});
postsList.innerHTML = records.map(post => `
<div class="post-item">
<span>${post.title}</span>
<button onclick="deletePost('${post.id}')">Sil</button>
</div>
`).join('');
} catch (error) {
console.error("Yazılar yüklenemedi:", error);
}
}
// Yazı Silme Fonksiyonu (Global yapıyoruz)
window.deletePost = async (id) => {
if (confirm("Bu yazıyı silmek istediğinize emin misiniz?")) {
try {
await pb.collection('posts').delete(id);
loadPosts();
} catch (error) {
alert("Silinemedi: " + error.message);
}
}
};
const addTag = (rawValue) => {
const value = rawValue.trim();
if (!value) return;
if (currentTags.includes(value)) return;
currentTags = [...currentTags, value];
// Etiket Yönetimi
function renderTags() {
tagsList.innerHTML = currentTags.map((tag, index) => `
<span class="tag">${tag} <i onclick="removeTag(${index})">&times;</i></span>
`).join('');
}
window.removeTag = (index) => {
currentTags.splice(index, 1);
renderTags();
};
tagsInput.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
event.preventDefault();
addTag(tagsInput.value);
const tag = tagsInput.value.trim();
if (tag && !currentTags.includes(tag)) {
currentTags.push(tag);
renderTags();
}
tagsInput.value = "";
}
});
loginForm.addEventListener("submit", (event) => {
event.preventDefault();
const formData = new FormData(loginForm);
const email = formData.get("email");
const password = formData.get("password");
signInWithEmailAndPassword(auth, email, password)
.then(() => {
loginForm.reset();
})
.catch(() => {
alert("Giriş başarısız. E-posta veya şifre hatalı.");
});
});
logoutBtn.addEventListener("click", () => {
signOut(auth);
});
blogForm.addEventListener("submit", (event) => {
event.preventDefault();
const formData = new FormData(blogForm);
const newPost = {
title: formData.get("title").trim(),
tags: currentTags,
summary: formData.get("summary").trim(),
content: formData.get("content").trim(),
date: formData.get("date"),
image: formData.get("image").trim(),
createdAt: serverTimestamp(),
};
addDoc(postsRef, newPost)
.then(() => {
blogForm.reset();
currentTags = [];
renderTags();
})
.catch(() => {
alert("Yazı kaydedilemedi. Tekrar deneyin.");
});
});
onAuthStateChanged(auth, (user) => {
setAuthState(!!user);
});
const postsQuery = query(postsRef, orderBy("createdAt", "desc"));
onSnapshot(postsQuery, (snapshot) => {
const posts = snapshot.docs.map((docSnap) => ({
id: docSnap.id,
...docSnap.data(),
}));
renderPosts(posts);
});
// Sayfa yüklendiğinde oturum kontrolü
if (pb.authStore.isValid) {
setAuthState(true);
}