195 lines
5.3 KiB
JavaScript
195 lines
5.3 KiB
JavaScript
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";
|
||
|
||
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);
|
||
|
||
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 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;
|
||
}
|
||
|
||
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));
|
||
});
|
||
|
||
actions.appendChild(removeBtn);
|
||
wrapper.append(title, meta, summary, actions);
|
||
postsList.appendChild(wrapper);
|
||
});
|
||
};
|
||
|
||
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);
|
||
renderTags();
|
||
});
|
||
|
||
chip.appendChild(removeBtn);
|
||
tagsList.appendChild(chip);
|
||
});
|
||
};
|
||
|
||
const addTag = (rawValue) => {
|
||
const value = rawValue.trim();
|
||
if (!value) return;
|
||
if (currentTags.includes(value)) return;
|
||
currentTags = [...currentTags, value];
|
||
renderTags();
|
||
};
|
||
|
||
tagsInput.addEventListener("keydown", (event) => {
|
||
if (event.key === "Enter") {
|
||
event.preventDefault();
|
||
addTag(tagsInput.value);
|
||
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);
|
||
});
|