Files
frontend-app/src/pages/kaza.js
T
2026-07-29 03:00:02 +02:00

331 lines
13 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,
calculateMissedPrayers,
getHijriAge,
getHijriBirthDate,
} from "../utils/hijri.js";
const PRAYERS = [
{ id: "fajr", name: "SABAH", arabic: "Fecr" },
{ id: "dhuhr", name: "ÖĞLE", arabic: "Zuhur" },
{ id: "asr", name: "İKİNDİ", arabic: "Asr" },
{ id: "maghrib", name: "AKŞAM", arabic: "Mağrib" },
{ id: "isha", name: "YATSI", arabic: "İşa" },
{ id: "vitr", name: "VİTR", arabic: "Vitr" },
];
export function renderKaza(pb) {
const pbBirthDate = pb.authStore.model?.birthdate;
const pbGender = pb.authStore.model?.gender;
const profileS = localStorage.getItem("kaza_profile");
let profile = profileS ? JSON.parse(profileS) : null;
const birthDate = pbBirthDate || profile?.birthDate;
const gender = pbGender || profile?.gender;
const html = `
<div class="bg-slate-900/60 backdrop-blur-2xl border border-white/10 p-8 rounded-3xl shadow-2xl max-w-4xl w-full h-[80vh] flex flex-col">
<button id="closeBtn" class="absolute top-4 right-4 bg-rose-500/20 hover:bg-rose-500/40 text-rose-300 border border-rose-500/30 w-8 h-8 rounded-full flex items-center justify-center font-bold text-xs transition-all">
</button>
<h2 class="text-2xl font-bold text-white mb-1">🕌 Kaza Namaz Takibi</h2>
<p class="text-slate-400 text-sm mb-6">
Hicri yaşını ve kalan kaza namazını takip et.
</p>
${
!birthDate
? `
<div class="bg-slate-900/40 border border-white/10 p-6 rounded-2xl mb-6">
<h3 class="text-sm font-semibold text-slate-300 mb-4">Profil Bilgileri</h3>
<form id="profileForm" class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div>
<label class="block text-xs text-slate-400 mb-1">Doğum Tarihi</label>
<input type="date" id="birthDate" required class="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white text-sm" />
</div>
<div>
<label class="block text-xs text-slate-400 mb-1">Cinsiyet</label>
<select id="gender" required class="w-full bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white text-sm">
<option value="male">Erkek</option>
<option value="female">Kadın</option>
</select>
</div>
<div class="flex items-end">
<button type="submit" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-xl text-sm font-medium transition-all">
Hesapla
</button>
</div>
</form>
</div>
`
: `
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3 mb-6">
<div class="bg-slate-900/40 border border-white/10 p-3 rounded-2xl text-center">
<p class="text-[10px] text-slate-400 mb-1">Hicri Doğum Tarihi</p>
<p class="text-sm font-bold text-white" id="hijriBirthDateDisplay">-</p>
</div>
${PRAYERS.map(
(p) => `
<div class="bg-slate-900/40 border border-white/10 p-3 rounded-2xl text-center">
<p class="text-[10px] text-slate-400 mb-1">${p.name}</p>
<p class="text-xs text-white">Kalan: <span id="remaining-${p.id}" class="font-bold text-emerald-300">-</span></p>
<p class="text-[10px] text-slate-500 mt-1">Toplam: <span id="total-${p.id}">-</span></p>
</div>
`,
).join("")}
</div>
<div class="bg-slate-900/40 border border-white/10 p-4 rounded-2xl mb-6">
<h3 class="text-sm font-semibold text-slate-300 mb-3">Kaza Namaz Ekle / Çıkar</h3>
<form id="addKazaForm" class="flex items-center gap-3">
<select id="kazaPrayerType" class="bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white text-sm">
${PRAYERS.map((p) => `<option value="${p.id}">${p.name}</option>`).join("")}
</select>
<input type="number" id="kazaCount" min="1" value="1" required class="w-20 bg-slate-950 border border-slate-800 rounded-xl px-4 py-2 text-white text-sm" />
<button type="button" id="addKazaBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-xl text-sm font-medium transition-all">
Ekle
</button>
<button type="button" id="removeKazaBtn" class="bg-rose-600 hover:bg-rose-700 text-white px-4 py-2 rounded-xl text-sm font-medium transition-all">
Çıkar
</button>
</form>
<p id="kazaMsg" class="text-xs mt-2 hidden"></p>
</div>
<div class="flex-1 overflow-y-auto pr-2">
<h3 class="text-sm font-semibold text-slate-300 mb-4">Bugünkü Namazlar</h3>
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3 mb-6">
${PRAYERS.map((p) => {
const todayKey = new Date().toISOString().split("T")[0];
const alreadyDone = profile?.todayLogs?.some(
(l) => l.prayerId === p.id && l.date === todayKey,
);
return `
<div class="bg-slate-900/40 border ${alreadyDone ? "border-emerald-500/50 bg-emerald-500/10" : "border-white/10"} rounded-2xl p-4 text-center transition-all">
<p class="text-xs text-slate-400">${p.arabic}</p>
<p class="text-sm font-semibold text-white">${p.name}</p>
${alreadyDone ? "<p class='text-xs text-emerald-400 mt-1'>✓ Kılındı</p>" : ""}
</div>
`;
}).join("")}
</div>
<h3 class="text-sm font-semibold text-slate-300 mb-4">Son İşlemler</h3>
<div class="space-y-2" id="logsContainer">
<p class="text-xs text-slate-500">Yükleniyor...</p>
</div>
</div>
`
}
</div>
`;
return {
html,
initEvents: (container) => {
const closeBtn = container.querySelector("#closeBtn");
if (closeBtn) {
closeBtn.addEventListener("click", () => {
const event = new CustomEvent("navigate", { detail: "desktop" });
window.dispatchEvent(event);
});
}
if (!birthDate) {
const form = container.querySelector("#profileForm");
const genderSelect = container.querySelector("#gender");
if (gender && genderSelect) {
genderSelect.value = gender;
}
if (form) {
form.addEventListener("submit", async (e) => {
e.preventDefault();
const birthDateInput = container.querySelector("#birthDate").value;
const genderInput = container.querySelector("#gender").value;
if (!birthDateInput) {
alert("Lütfen doğum tarihinizi girin.");
return;
}
try {
await pb.collection("users").update(pb.authStore.model.id, {
birthDate: birthDateInput,
gender: genderInput,
});
} catch (err) {
console.error("PocketBase kaydedilemedi:", err);
}
profile = {
gender: genderInput,
logs: profile?.logs || [],
todayLogs: profile?.todayLogs || [],
createdAt: profile?.createdAt || new Date().toISOString(),
};
localStorage.setItem("kaza_profile", JSON.stringify(profile));
const event = new CustomEvent("navigate", { detail: "kaza" });
window.dispatchEvent(event);
});
}
} else {
refreshKazaStats(container, pb, birthDate, gender, profile);
const addBtn = container.querySelector("#addKazaBtn");
const removeBtn = container.querySelector("#removeKazaBtn");
if (addBtn) {
addBtn.addEventListener("click", async () => {
const prayerId = container.querySelector("#kazaPrayerType").value;
const countInput = container.querySelector("#kazaCount");
const count = Math.max(1, parseInt(countInput?.value || "1", 10));
const msg = container.querySelector("#kazaMsg");
try {
await pb.collection("kaza_logs").create({
user: pb.authStore.model.id,
prayerId,
count,
date: new Date().toISOString().split("T")[0],
});
showKazaMsg(msg, `${count} kaza namaz eklendi!`, true);
if (countInput) countInput.value = "1";
await refreshKazaStats(container, pb, birthDate, gender, profile);
} catch (err) {
console.error("Kaza eklenemedi:", err);
showKazaMsg(
msg,
"Eklenemedi. PocketBase bağlantısını kontrol et.",
false,
);
}
});
}
if (removeBtn) {
removeBtn.addEventListener("click", async () => {
const prayerId = container.querySelector("#kazaPrayerType").value;
const countInput = container.querySelector("#kazaCount");
const count = Math.max(1, parseInt(countInput?.value || "1", 10));
const msg = container.querySelector("#kazaMsg");
try {
const records = await pb.collection("kaza_logs").getFullList({
filter: `user = "${pb.authStore.model.id}" && prayerId = "${prayerId}"`,
sort: "-createdAt",
});
let remaining = count;
for (const record of records) {
if (remaining <= 0) break;
const recordCount = record.count || 1;
if (recordCount > remaining) {
await pb.collection("kaza_logs").update(record.id, {
count: recordCount - remaining,
});
remaining = 0;
} else {
await pb.collection("kaza_logs").delete(record.id);
remaining -= recordCount;
}
}
showKazaMsg(msg, `${count} kaza namaz çıkarıldı!`, true);
if (countInput) countInput.value = "1";
await refreshKazaStats(container, pb, birthDate, gender, profile);
} catch (err) {
console.error("Kaza çıkarılamadı:", err);
showKazaMsg(
msg,
"Çıkarılamadı. PocketBase bağlantısını kontrol et.",
false,
);
}
});
}
}
},
};
}
async function refreshKazaStats(container, pb, birthDate, gender, profile) {
if (!birthDate) return;
const calc = calculateMissedPrayers(birthDate, gender);
const hijriBirth = getHijriBirthDate(birthDate);
const birthDateEl = container.querySelector("#hijriBirthDateDisplay");
if (birthDateEl) {
birthDateEl.textContent = `${hijriBirth.day} ${hijriBirth.monthName} ${hijriBirth.year}`;
}
let logs = [];
let logsByPrayer = {};
try {
const records = await pb.collection("kaza_logs").getFullList({
filter: `user = "${pb.authStore.model.id}"`,
sort: "-createdAt",
});
logs = records.map((r) => ({
id: r.id,
prayerId: r.prayerId,
count: r.count || 1,
date: r.date,
createdAt: r.createdAt,
}));
logs.forEach((l) => {
logsByPrayer[l.prayerId] =
(logsByPrayer[l.prayerId] || 0) + (l.count || 1);
});
} catch (err) {
console.error("Loglar yüklenemedi:", err);
}
PRAYERS.forEach((p) => {
const totalEl = container.querySelector(`#total-${p.id}`);
const remainEl = container.querySelector(`#remaining-${p.id}`);
const missed = calc[p.id] || 0;
const completed = logsByPrayer[p.id] || 0;
const remaining = Math.max(0, missed - completed);
if (totalEl) totalEl.textContent = missed;
if (remainEl) remainEl.textContent = remaining;
});
const todayKey = new Date().toISOString().split("T")[0];
const todayLogs = logs.filter((l) => l.date === todayKey);
if (profile) {
profile.todayLogs = todayLogs;
localStorage.setItem("kaza_profile", JSON.stringify(profile));
}
const logsContainer = container.querySelector("#logsContainer");
if (logsContainer) {
logsContainer.innerHTML =
logs
.slice(0, 20)
.map((log) => {
const prayer = PRAYERS.find((p) => p.id === log.prayerId);
return `
<div class="flex items-center justify-between bg-slate-900/20 border border-white/5 rounded-xl px-4 py-2">
<span class="text-xs text-slate-300">${prayer?.name || log.prayerId} x${log.count} - ${log.date}</span>
<span class="text-xs text-emerald-400">+${log.count}</span>
</div>
`;
})
.join("") || '<p class="text-xs text-slate-500">Henüz kayıt yok.</p>';
}
}
function showKazaMsg(el, text, success) {
el.textContent = text;
el.className = `text-xs mt-2 ${success ? "text-emerald-400" : "text-rose-400"}`;
el.classList.remove("hidden");
}