221 lines
8.5 KiB
JavaScript
Executable File
221 lines
8.5 KiB
JavaScript
Executable File
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>
|
||
`;
|
||
}
|