Files
frontend-app/src/main.js
T

208 lines
9.2 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import "./style.css";
import PocketBase from "pocketbase";
import { renderSettings } from "./pages/settings.js";
import { renderDesktop } from "./pages/desktop.js";
import { renderKaza } from "./pages/kaza.js";
import { getDefaultCity } from "./utils/locations.js";
const pb = new PocketBase("https://pocketbase.iontalp.com");
const app = document.getElementById("app");
let activeTab = "desktop";
let sidebarOpen = window.innerWidth >= 768;
let selectedCity = localStorage.getItem("selected_city");
async function render() {
const user = pb.authStore.model;
if (!user) {
renderLogin();
return;
}
// Güvenli Avatar URL
const avatarUrl = user?.avatar
? `https://pocketbase.iontalp.com/api/files/${user.collectionId || "_pb_users_auth_"}/${user.id}/${user.avatar}?thumb=100x100`
: null;
let currentBg =
user.selected_bg ||
"https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?q=80&w=1920";
if (user.selected_city) {
selectedCity = user.selected_city;
localStorage.setItem("selected_city", selectedCity);
} else {
const stored = localStorage.getItem("selected_city");
if (stored) {
selectedCity = stored;
} else {
selectedCity = getDefaultCity().name;
}
}
let currentPage;
if (activeTab === "settings") {
currentPage = await renderSettings(
pb,
currentBg,
(newBg) => {
pb.authStore.model.selected_bg = newBg;
render();
},
selectedCity,
(city) => {
selectedCity = city;
localStorage.setItem("selected_city", city);
render();
},
);
} else if (activeTab === "kaza") {
currentPage = await renderKaza(pb);
} else {
currentPage = await renderDesktop(selectedCity, pb);
}
app.innerHTML = `
<div class="relative w-full h-screen overflow-hidden bg-slate-950 text-slate-100 flex">
<!-- Kristal Netliğinde Arka Plan -->
<div class="absolute inset-0 z-0 bg-center bg-cover bg-no-repeat transition-all duration-700"
style="background-image: url('${currentBg}');">
</div>
<!-- İnce Netlik Katmanı -->
<div class="absolute inset-0 z-10 bg-black/25"></div>
<!-- Mobil Karartma Overlay -->
${sidebarOpen ? `<div id="sidebarOverlay" class="fixed inset-0 bg-black/50 z-30 md:hidden"></div>` : ""}
<!-- Sol Menü (Sidebar) -->
<aside id="sidebar" class="fixed md:relative z-40 md:z-30 inset-y-0 left-0 ${sidebarOpen ? "w-72 translate-x-0" : "w-72 -translate-x-full md:w-20 md:translate-x-0"} h-screen bg-slate-900/85 border-r border-white/10 flex flex-col justify-between transition-all duration-300 ease-in-out overflow-hidden shadow-2xl p-4">
<div class="w-full">
<!-- Sidebar Üst Başlık & Toggle Butonu (İç içe geçmeyi çözen kısım) -->
<div class="flex items-center justify-between mb-6 h-10 px-1">
<h1 class="font-bold text-white text-lg ${sidebarOpen ? "block" : "hidden"} transition-all truncate">İon Talp</h1>
<button id="globalSidebarToggle" class="bg-slate-800/80 hover:bg-slate-700 text-white w-9 h-9 rounded-xl transition-all border border-white/10 shadow-md flex items-center justify-center shrink-0 ${sidebarOpen ? "" : "mx-auto"}">
<span>${sidebarOpen ? "◀" : "▶"}</span>
</button>
</div>
<!-- Navigasyon Menüsü (Zıplamayı önleyen sabit genişlikli ikonlar) -->
<nav class="space-y-2 w-full">
<button id="navDesktop" class="w-full flex items-center h-12 px-3 rounded-xl font-medium transition-all ${activeTab === "desktop" ? "bg-indigo-600/40 text-indigo-300 border border-indigo-500/40" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span class="w-6 h-6 flex items-center justify-center text-xl shrink-0">🏠</span>
<span class="${sidebarOpen ? "opacity-100 ml-3" : "opacity-0 w-0 hidden"} transition-opacity duration-200 whitespace-nowrap overflow-hidden">Masaüstü</span>
</button>
<button id="navKaza" class="w-full flex items-center h-12 px-3 rounded-xl font-medium transition-all ${activeTab === "kaza" ? "bg-indigo-600/40 text-indigo-300 border border-indigo-500/40" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span class="w-6 h-6 flex items-center justify-center text-xl shrink-0">📿</span>
<span class="${sidebarOpen ? "opacity-100 ml-3" : "opacity-0 w-0 hidden"} transition-opacity duration-200 whitespace-nowrap overflow-hidden">Kaza Namazı</span>
</button>
<button id="navSettings" class="w-full flex items-center h-12 px-3 rounded-xl font-medium transition-all ${activeTab === "settings" ? "bg-indigo-600/40 text-indigo-300 border border-indigo-500/40" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span class="w-6 h-6 flex items-center justify-center text-xl shrink-0">⚙️</span>
<span class="${sidebarOpen ? "opacity-100 ml-3" : "opacity-0 w-0 hidden"} transition-opacity duration-200 whitespace-nowrap overflow-hidden">Ayarlar</span>
</button>
</nav>
</div>
<!-- Profil ve Çıkış Alanı -->
<div class="space-y-3 pt-4 border-t border-white/10 w-full">
<div id="profileBtn" class="flex items-center h-12 px-2 rounded-xl hover:bg-white/5 cursor-pointer transition-all">
${
avatarUrl
? `<img src="${avatarUrl}" alt="Avatar" class="w-9 h-9 rounded-full object-cover border border-white/20 shadow-md shrink-0" />`
: `<div class="w-9 h-9 rounded-full bg-indigo-600/30 border border-indigo-500/30 flex items-center justify-center font-bold text-indigo-400 shrink-0">${(user.username || user.email).charAt(0).toUpperCase()}</div>`
}
<div class="${sidebarOpen ? "opacity-100 ml-3" : "opacity-0 w-0 hidden"} transition-opacity duration-200 overflow-hidden whitespace-nowrap">
<p class="text-sm font-medium text-white truncate">${user.name || user.username || user.email}</p>
<p class="text-xs text-emerald-400">Çevrimiçi</p>
</div>
</div>
<button id="logoutBtn" class="w-full bg-rose-500/20 text-rose-300 hover:bg-rose-500/30 h-11 rounded-xl border border-rose-500/30 text-sm font-medium transition-all flex items-center justify-center">
<span class="w-6 h-6 flex items-center justify-center text-base shrink-0">🚪</span>
<span class="${sidebarOpen ? "opacity-100 ml-2" : "opacity-0 w-0 hidden"} transition-opacity duration-200 whitespace-nowrap overflow-hidden">Çıkış Yap</span>
</button>
</div>
</aside>
<!-- Ana İçerik -->
<main id="mainContent" class="relative z-20 flex-1 h-screen p-4 md:p-8 flex items-center justify-center overflow-y-auto">
${currentPage.html}
</main>
</div>
`;
const mainContent = document.getElementById("mainContent");
if (currentPage.initEvents) {
currentPage.initEvents(mainContent);
}
document.getElementById("navDesktop")?.addEventListener("click", () => {
activeTab = "desktop";
render();
});
document.getElementById("navKaza")?.addEventListener("click", () => {
activeTab = "kaza";
render();
});
document.getElementById("navSettings")?.addEventListener("click", () => {
activeTab = "settings";
render();
});
document.getElementById("logoutBtn")?.addEventListener("click", () => {
pb.authStore.clear();
render();
});
document
.getElementById("globalSidebarToggle")
?.addEventListener("click", () => {
sidebarOpen = !sidebarOpen;
render();
});
document.getElementById("sidebarOverlay")?.addEventListener("click", () => {
sidebarOpen = false;
render();
});
}
window.addEventListener("navigate", (e) => {
activeTab = e.detail;
render();
});
function renderLogin() {
app.innerHTML = `
<div class="min-h-screen bg-slate-950 text-slate-100 flex items-center justify-center p-4">
<div class="bg-slate-900 border border-slate-800 p-8 rounded-2xl shadow-2xl w-full max-w-md">
<h1 class="text-2xl font-bold text-center mb-6">Giriş Yap</h1>
<form id="loginForm" class="space-y-4">
<input type="text" id="identity" placeholder="E-posta / Kullanıcı Adı" required class="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white focus:outline-none focus:border-indigo-500" />
<input type="password" id="password" placeholder="Şifre" required class="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white focus:outline-none focus:border-indigo-500" />
<button type="submit" class="w-full bg-indigo-600 hover:bg-indigo-500 py-2.5 rounded-xl text-white font-medium transition-all">Giriş Yap</button>
</form>
</div>
</div>
`;
document.getElementById("loginForm").addEventListener("submit", async (e) => {
e.preventDefault();
try {
await pb
.collection("users")
.authWithPassword(
document.getElementById("identity").value,
document.getElementById("password").value,
);
render();
} catch {
alert("Giriş başarısız! Bilgilerinizi kontrol edin.");
}
});
}
// Uygulamayı başlat
render();