Files
frontend-app/src/pages/desktop.js
T

221 lines
8.5 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 { gregorianToHijri } from "../utils/hijri.js";
import {
fetchWeather,
getWeatherIcon,
getWeatherDesc,
} from "../utils/weather.js";
import { fetchPrayerTimes } from "../utils/prayerTimes.js";
export function renderDesktop(selectedCity = "Edremit", pb) {
const hijri = gregorianToHijri();
const today = new Date();
const dateStr = today.toLocaleDateString("tr-TR", {
weekday: "long",
year: "numeric",
month: "long",
day: "numeric",
});
const html = `
<!-- Paneli Tam Sağa Yapıştırma ve Boyunu Uzatma Kapsayıcısı -->
<div class="fixed top-0 right-0 h-screen w-80 md:w-96 bg-slate-900/85 border-l border-white/10 p-6 shadow-2xl z-20 flex flex-col justify-between overflow-y-auto">
<div class="space-y-6">
<!-- CANLI DİJİTAL SAAT WIDGET'I -->
<div class="bg-slate-950/60 border border-white/10 p-5 rounded-3xl text-center space-y-1 shadow-inner">
<p class="text-xs font-semibold text-indigo-400 tracking-widest uppercase">CANLI SAAT</p>
<div id="liveClock" class="text-4xl font-black text-white tracking-wider font-mono">
00:00:00
</div>
<p class="text-[11px] text-slate-400 font-medium">${dateStr}</p>
</div>
<!-- GENEL KAZA İLERLEME WIDGET'I -->
<div id="desktopKazaProgressWidget" class="bg-slate-950/60 border border-white/10 p-4 rounded-2xl space-y-2">
<div class="flex items-center justify-between text-xs">
<span class="font-bold text-indigo-300 flex items-center gap-1.5">
<span>📊</span> KAZA İLERLEMESİ
</span>
<span id="desktopKazaPct" class="font-extrabold text-emerald-400">%0</span>
</div>
<div class="w-full h-3 bg-slate-900 rounded-full overflow-hidden border border-white/5 p-0.5">
<div id="desktopKazaBar" class="h-full bg-linear-to-r from-indigo-500 via-purple-500 to-emerald-400 rounded-full transition-all duration-700 ease-out w-[0%]"></div>
</div>
<p id="desktopKazaSub" class="text-[10px] text-slate-400 text-right">Yükleniyor...</p>
</div>
<hr class="border-white/5" />
<!-- HİCRİ TAKVİM -->
<div class="space-y-1">
<div class="flex items-center gap-2 text-xs font-semibold text-emerald-400">
<span>🌙</span> HİCRİ TAKVİM
</div>
<p class="text-white font-bold text-base">${hijri.day} ${hijri.monthName} ${hijri.year}</p>
<p class="text-xs text-slate-400">${hijri.weekday}</p>
</div>
<hr class="border-white/5" />
<!-- HAVA DURUMU -->
<div class="space-y-1" id="weatherWidget">
<div class="text-xs text-slate-400">Hava durumu yükleniyor...</div>
</div>
<hr class="border-white/5" />
<!-- İMSAKİYE & VAKİTLER -->
<div class="space-y-2" id="imsakiyeWidget">
<div class="text-xs text-slate-400">Namaz vakitleri yükleniyor...</div>
</div>
</div>
<!-- KAZA NAMAZI KISAYOLU (ALT KISIM) -->
<div id="kazaShortcut" class="mt-6 bg-indigo-600/30 hover:bg-indigo-600/50 border border-indigo-500/30 p-3.5 rounded-2xl cursor-pointer transition-all group flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="text-xl group-hover:scale-110 transition-transform">📿</span>
<div>
<h3 class="text-xs font-bold text-white">Kaza Namazı Takibi</h3>
<p class="text-[10px] text-indigo-300">Detaylı sayaç & takip</p>
</div>
</div>
<span class="text-slate-400 group-hover:translate-x-1 transition-transform text-xs">➔</span>
</div>
</div>
`;
return {
html,
initEvents: (container) => {
startClock(container);
loadWeather(container, selectedCity);
loadImsakiye(container, selectedCity);
if (pb) loadDesktopKazaProgress(container, pb);
container
.querySelector("#kazaShortcut")
?.addEventListener("click", () => {
window.dispatchEvent(new CustomEvent("navigate", { detail: "kaza" }));
});
},
};
}
// Canlı Saat Mantığı (Saniyede Bir Güncellenir)
function startClock(container) {
const clockEl = container.querySelector("#liveClock");
if (!clockEl) return;
const update = () => {
const now = new Date();
clockEl.textContent = now.toLocaleTimeString("tr-TR");
};
update();
setInterval(update, 1000);
}
// PocketBase üzerindeki sabit hedeflere (target_*) göre kaza durumunu okuma
async function loadDesktopKazaProgress(container, pb) {
const user = pb.authStore.model;
if (!user) return;
let totalTarget = 0;
let totalCompleted = 0;
try {
const record = await pb
.collection("kaza_logs")
.getFirstListItem(`user = "${user.id}"`);
if (record) {
totalTarget =
(record.target_fajr || 0) +
(record.target_dhuhr || 0) +
(record.target_asr || 0) +
(record.target_maghrib || 0) +
(record.target_isha || 0) +
(record.target_vitr || 0);
totalCompleted =
(record.fajr || 0) +
(record.dhuhr || 0) +
(record.asr || 0) +
(record.maghrib || 0) +
(record.isha || 0) +
(record.vitr || 0);
}
} catch {}
const remaining = Math.max(0, totalTarget - totalCompleted);
const pct =
totalTarget > 0
? Math.min(100, Math.round((totalCompleted / totalTarget) * 100))
: 0;
const bar = container.querySelector("#desktopKazaBar");
const pctText = container.querySelector("#desktopKazaPct");
const subText = container.querySelector("#desktopKazaSub");
if (bar) bar.style.width = `${pct}%`;
if (pctText) pctText.textContent = `%${pct}`;
if (subText)
subText.textContent = `${totalCompleted} kılınan / ${remaining} kalan`;
}
async function loadWeather(container, selectedCity) {
const widget = container.querySelector("#weatherWidget");
if (!widget) return;
const data = await fetchWeather(selectedCity);
if (!data) {
widget.innerHTML = `<span class="text-xs text-rose-400">Hava durumu alınamadı</span>`;
return;
}
const icon = getWeatherIcon(data.weathercode);
const desc = getWeatherDesc(data.weathercode);
const temp = Math.round(data.temperature);
widget.innerHTML = `
<div class="flex items-center justify-between">
<div>
<div class="flex items-center gap-2 text-xs font-semibold text-sky-400">
<span>🌤️</span> HAVA DURUMU
</div>
<p class="text-xs text-slate-300 mt-1">${desc}</p>
</div>
<div class="flex items-center gap-2">
<span class="text-3xl">${icon}</span>
<span class="text-2xl font-bold text-white">${temp}°C</span>
</div>
</div>
`;
}
async function loadImsakiye(container, selectedCity) {
const widget = container.querySelector("#imsakiyeWidget");
if (!widget) return;
const times = await fetchPrayerTimes(selectedCity);
if (!times) {
widget.innerHTML = `<span class="text-xs text-rose-400">Vakitler alınamadı</span>`;
return;
}
const activeKey = times.currentPrayer?.key;
widget.innerHTML = `
<div class="flex items-center justify-between mb-2">
<span class="text-xs font-semibold text-orange-400">🕌 NAMAZ VAKİTLERİ</span>
<span class="text-[10px] bg-indigo-500/20 text-indigo-300 border border-indigo-500/30 px-2 py-0.5 rounded-full">Şu an: ${times.currentPrayer?.name}</span>
</div>
<div class="grid grid-cols-2 gap-2 text-xs">
<div class="p-2 rounded-xl ${activeKey === "fajr" ? "bg-emerald-500/20 border border-emerald-500/40 text-emerald-300 font-bold" : "bg-slate-900/40 text-slate-300"}">İmsak: ${times.imsak}</div>
<div class="p-2 rounded-xl bg-slate-900/40 text-slate-300">Güneş: ${times.sunrise}</div>
<div class="p-2 rounded-xl ${activeKey === "dhuhr" ? "bg-emerald-500/20 border border-emerald-500/40 text-emerald-300 font-bold" : "bg-slate-900/40 text-slate-300"}">Öğle: ${times.dhuhr}</div>
<div class="p-2 rounded-xl ${activeKey === "asr" ? "bg-emerald-500/20 border border-emerald-500/40 text-emerald-300 font-bold" : "bg-slate-900/40 text-slate-300"}">İkindi: ${times.asr}</div>
<div class="p-2 rounded-xl ${activeKey === "maghrib" ? "bg-emerald-500/20 border border-emerald-500/40 text-emerald-300 font-bold" : "bg-slate-900/40 text-slate-300"}">Akşam: ${times.maghrib}</div>
<div class="p-2 rounded-xl ${activeKey === "isha" ? "bg-emerald-500/20 border border-emerald-500/40 text-emerald-300 font-bold" : "bg-slate-900/40 text-slate-300"}">Yatsı: ${times.isha}</div>
</div>
`;
}