Files
frontend-app/src/main.js
T

191 lines
8.1 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;
}
const avatarUrl = user?.avatar
? `https://pocketbase.iontalp.com/api/files/_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 = renderKaza(pb);
} else {
currentPage = renderDesktop(selectedCity);
}
app.innerHTML = `
<div class="relative w-full h-screen overflow-hidden bg-slate-950 text-slate-100 flex">
<div class="absolute inset-0 z-0 bg-center bg-no-repeat transition-all duration-700"
style="background-image: url('${currentBg}'); background-size: cover;">
</div>
<div class="absolute inset-0 z-10 bg-slate-950/60 backdrop-blur-[2px]"></div>
<button id="globalSidebarToggle" class="fixed top-4 left-4 z-50 bg-white/10 hover:bg-white/20 text-white p-2.5 rounded-xl backdrop-blur-md transition-all border border-white/10">
${sidebarOpen ? "◀" : "▶"}
</button>
${sidebarOpen ? `<div id="sidebarOverlay" class="fixed inset-0 bg-black/50 z-30 md:hidden"></div>` : ""}
<aside id="sidebar" class="fixed md:relative z-40 md:z-30 inset-y-0 left-0 ${sidebarOpen ? "w-72 translate-x-0 p-6" : "w-72 -translate-x-full md:w-20 md:translate-x-0 md:p-3"} h-screen bg-slate-900/80 backdrop-blur-xl border-r border-white/10 flex flex-col justify-between transition-all duration-300 overflow-hidden">
<div>
<div class="flex items-center justify-between mb-8 mt-2">
<h1 class="font-bold text-white text-xl ${sidebarOpen ? "block" : "hidden md:hidden"}">Dashboard OS</h1>
</div>
<nav class="space-y-2 w-full">
<button id="navDesktop" class="w-full flex items-center ${sidebarOpen ? "" : "md:justify-center"} gap-3 px-4 py-3 rounded-xl font-medium ${activeTab === "desktop" ? "bg-indigo-600/30 text-indigo-300 border border-indigo-500/30" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span>🏠</span> <span class="${sidebarOpen ? "block" : "hidden md:hidden"}">Masaüstü</span>
</button>
<button id="navKaza" class="w-full flex items-center ${sidebarOpen ? "" : "md:justify-center"} gap-3 px-4 py-3 rounded-xl font-medium ${activeTab === "kaza" ? "bg-indigo-600/30 text-indigo-300 border border-indigo-500/30" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span>📿</span> <span class="${sidebarOpen ? "block" : "hidden md:hidden"}">Kaza Namazı</span>
</button>
<button id="navSettings" class="w-full flex items-center ${sidebarOpen ? "" : "md:justify-center"} gap-3 px-4 py-3 rounded-xl font-medium ${activeTab === "settings" ? "bg-indigo-600/30 text-indigo-300 border border-indigo-500/30" : "text-slate-400 hover:text-white hover:bg-white/5"}">
<span>⚙️</span> <span class="${sidebarOpen ? "block" : "hidden md:hidden"}">Ayarlar</span>
</button>
</nav>
</div>
<div class="space-y-3 pt-4 border-t border-white/10 w-full">
<div id="profileBtn" class="flex items-center ${sidebarOpen ? "" : "md:justify-center"} gap-3 p-2 rounded-xl hover:bg-white/5 cursor-pointer transition-all">
${
avatarUrl
? `<img src="${avatarUrl}" alt="Avatar" class="w-10 h-10 rounded-full object-cover border border-white/20 shadow-md flex-shrink-0" />`
: `<div class="w-10 h-10 rounded-full bg-indigo-600/30 border border-indigo-500/30 flex items-center justify-center font-bold text-indigo-400 flex-shrink-0">${(user.username || user.email).charAt(0).toUpperCase()}</div>`
}
<div class="${sidebarOpen ? "block" : "hidden md:hidden"} overflow-hidden">
<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 py-2.5 rounded-xl border border-rose-500/30 text-sm font-medium transition-all flex items-center justify-center gap-2">
<span>🚪</span> <span class="${sidebarOpen ? "inline" : "hidden md:hidden"}">Çıkış Yap</span>
</button>
</div>
</aside>
<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");
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.");
}
});
}
render();