kaza namazı hesaplama düzeltildi.
This commit is contained in:
+130
-67
@@ -24,7 +24,7 @@ export function renderKaza(pb) {
|
||||
<span class="text-3xl">📿</span>
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-white">Kaza Namazı Sayaç & Takip</h2>
|
||||
<p class="text-slate-400 text-xs">Tamamladığın vakitler anlık olarak PocketBase hesabında güncellenir.</p>
|
||||
<p class="text-slate-400 text-xs">Kaza namazı borçlarınızı sabitleyin ve kıldıkça düşün.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -47,26 +47,38 @@ export function renderKaza(pb) {
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="w-full bg-indigo-600 hover:bg-indigo-500 text-white py-2.5 rounded-xl text-sm font-semibold transition-all">
|
||||
Hesapla ve Başla
|
||||
Kaydet
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
`
|
||||
: `
|
||||
<!-- GENEL İLERLEME BARI (XP/PERCENTAGE) -->
|
||||
<div class="bg-slate-950/60 border border-white/10 p-5 rounded-2xl mb-6 mt-2">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-bold text-indigo-300 flex items-center gap-1.5">
|
||||
<span>🎯</span> GENEL KAZA BİTİRME ORANI
|
||||
</span>
|
||||
<span id="overallPercentage" class="text-sm font-extrabold text-emerald-400">%0</span>
|
||||
<!-- HESAPLAMA VE İLERLEME BARI -->
|
||||
<div class="bg-slate-950/60 border border-white/10 p-5 rounded-2xl mb-6 mt-2 flex flex-col gap-4">
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 border-b border-white/10 pb-3">
|
||||
<div>
|
||||
<h3 class="text-xs font-bold text-indigo-300 uppercase tracking-wider">Borç Tanımlama</h3>
|
||||
<p class="text-[11px] text-slate-400">Doğum tarihinize göre kaza borcunuzu hesaplayıp veritabanına sabitler.</p>
|
||||
</div>
|
||||
<button id="calcAndSaveBtn" class="bg-indigo-600 hover:bg-indigo-500 text-white px-4 py-2 rounded-xl text-xs font-semibold transition-all shadow-md active:scale-95">
|
||||
⚡ Kaza Borçlarını Otomatik Hesapla & Kaydet
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-full h-4 bg-slate-900 rounded-full overflow-hidden border border-white/5 p-0.5">
|
||||
<div id="overallProgressBar" 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>
|
||||
<div class="flex justify-between items-center text-[11px] text-slate-400 mt-2.5">
|
||||
<span>Kılınan Toplam: <b id="totalCompletedText" class="text-emerald-400">0</b> vakit</span>
|
||||
<span>Kalan Toplam Borç: <b id="totalRemainingText" class="text-amber-400">0</b> vakit</span>
|
||||
|
||||
<div>
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs font-bold text-indigo-300 flex items-center gap-1.5">
|
||||
<span>📊</span> GENEL KAZA BİTİRME ORANI
|
||||
</span>
|
||||
<span id="overallPercentage" class="text-sm font-extrabold text-emerald-400">%0</span>
|
||||
</div>
|
||||
<div class="w-full h-4 bg-slate-900 rounded-full overflow-hidden border border-white/5 p-0.5">
|
||||
<div id="overallProgressBar" 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>
|
||||
<div class="flex justify-between items-center text-[11px] text-slate-400 mt-2.5">
|
||||
<span>Kılınan Toplam: <b id="totalCompletedText" class="text-emerald-400">0</b> vakit</span>
|
||||
<span>Kalan Toplam Borç: <b id="totalRemainingText" class="text-amber-400">0</b> vakit</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -76,8 +88,8 @@ export function renderKaza(pb) {
|
||||
(p) => `
|
||||
<div class="bg-slate-950/40 border border-white/10 p-3.5 rounded-2xl text-center relative overflow-hidden group">
|
||||
<p class="text-[11px] font-bold text-slate-300 mb-1">${p.name}</p>
|
||||
<p class="text-xs text-slate-400">Kalan: <span id="remaining-${p.id}" class="font-extrabold text-emerald-300">-</span></p>
|
||||
<p class="text-[10px] text-slate-500 mt-0.5">Kılınan: <span id="completed-${p.id}" class="text-slate-300">0</span></p>
|
||||
<p class="text-xs text-slate-400">Kalan: <span id="remaining-${p.id}" class="font-extrabold text-amber-300">-</span></p>
|
||||
<p class="text-[10px] text-slate-500 mt-0.5">Kılınan: <span id="completed-${p.id}" class="text-emerald-400">0</span></p>
|
||||
<div class="w-full bg-slate-800 h-1.5 rounded-full mt-2.5 overflow-hidden">
|
||||
<div id="progress-${p.id}" class="bg-emerald-400 h-full w-[0%] transition-all duration-500"></div>
|
||||
</div>
|
||||
@@ -88,7 +100,7 @@ export function renderKaza(pb) {
|
||||
|
||||
<!-- HIZLI SAYAÇ GÜNCELLEME ALANI -->
|
||||
<div class="bg-slate-950/40 border border-white/10 p-5 rounded-2xl mb-auto">
|
||||
<h3 class="text-xs font-bold text-slate-300 uppercase tracking-wider mb-3">Kaza Sayacı İşlem</h3>
|
||||
<h3 class="text-xs font-bold text-slate-300 uppercase tracking-wider mb-3">Kaza Kıldım / Düzenle</h3>
|
||||
<form id="addKazaForm" class="flex flex-wrap items-center gap-3">
|
||||
<select id="kazaPrayerType" class="bg-slate-900 border border-slate-800 rounded-xl px-4 py-2.5 text-white text-sm focus:outline-none">
|
||||
${PRAYERS.map((p) => `<option value="${p.id}">${p.name}</option>`).join("")}
|
||||
@@ -96,7 +108,7 @@ export function renderKaza(pb) {
|
||||
<input type="number" id="kazaCount" min="1" value="1" required class="w-24 bg-slate-900 border border-slate-800 rounded-xl px-4 py-2.5 text-white text-sm text-center focus:outline-none font-bold" />
|
||||
|
||||
<button type="button" id="addKazaBtn" class="bg-emerald-600 hover:bg-emerald-500 text-white px-5 py-2.5 rounded-xl text-sm font-semibold transition-all shadow-lg active:scale-95 flex items-center gap-1.5">
|
||||
<span>✓</span> Kıldım / Ekle (+)
|
||||
<span>✓</span> Kıldım (+1)
|
||||
</button>
|
||||
<button type="button" id="removeKazaBtn" class="bg-rose-600/30 hover:bg-rose-600/50 text-rose-300 border border-rose-500/30 px-4 py-2.5 rounded-xl text-sm font-medium transition-all active:scale-95">
|
||||
Geri Al (-)
|
||||
@@ -125,7 +137,6 @@ export function renderKaza(pb) {
|
||||
e.preventDefault();
|
||||
const bInput = container.querySelector("#birthDateInput").value;
|
||||
const gInput = container.querySelector("#genderInput").value;
|
||||
|
||||
try {
|
||||
await pb.collection("users").update(pb.authStore.model.id, {
|
||||
birthdate: bInput,
|
||||
@@ -138,31 +149,83 @@ export function renderKaza(pb) {
|
||||
new CustomEvent("navigate", { detail: "kaza" }),
|
||||
);
|
||||
} catch (err) {
|
||||
alert(
|
||||
"Profil kaydedilemedi. PocketBase alan adlarını kontrol edin.",
|
||||
);
|
||||
alert("Profil kaydedilemedi.");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
refreshKazaStats(container, pb, birthDate, gender);
|
||||
refreshKazaStats(container, pb);
|
||||
|
||||
// Hesapla & Kaydet Butonu Tıklanması
|
||||
container
|
||||
.querySelector("#calcAndSaveBtn")
|
||||
?.addEventListener("click", async () => {
|
||||
if (
|
||||
confirm(
|
||||
"Kaza borçlarınız doğum tarihinize göre yeniden hesaplanıp veritabanına sabitlenecek. Onaylıyor musunuz?",
|
||||
)
|
||||
) {
|
||||
await initAndSaveInitialKaza(pb, birthDate, gender);
|
||||
await refreshKazaStats(container, pb);
|
||||
showKazaMsg(
|
||||
container.querySelector("#kazaMsg"),
|
||||
"Kaza borçları hesaplandı ve PocketBase'e kaydedildi!",
|
||||
true,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
container
|
||||
.querySelector("#addKazaBtn")
|
||||
?.addEventListener("click", async () => {
|
||||
await updateKazaCount(container, pb, birthDate, gender, 1);
|
||||
await updateKazaCount(container, pb, 1);
|
||||
});
|
||||
|
||||
container
|
||||
.querySelector("#removeKazaBtn")
|
||||
?.addEventListener("click", async () => {
|
||||
await updateKazaCount(container, pb, birthDate, gender, -1);
|
||||
await updateKazaCount(container, pb, -1);
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function updateKazaCount(container, pb, birthDate, gender, direction) {
|
||||
// Otomatik hesaplayıp PocketBase'e toplam borç olarak kaydetme
|
||||
async function initAndSaveInitialKaza(pb, birthDate, gender) {
|
||||
const calc = calculateMissedPrayers(birthDate, gender, 12);
|
||||
const userId = pb.authStore.model.id;
|
||||
|
||||
let userRecord = null;
|
||||
try {
|
||||
userRecord = await pb
|
||||
.collection("kaza_logs")
|
||||
.getFirstListItem(`user = "${userId}"`);
|
||||
} catch {}
|
||||
|
||||
const initialData = {
|
||||
user: userId,
|
||||
target_fajr: calc.fajr,
|
||||
target_dhuhr: calc.dhuhr,
|
||||
target_asr: calc.asr,
|
||||
target_maghrib: calc.maghrib,
|
||||
target_isha: calc.isha,
|
||||
target_vitr: calc.vitr,
|
||||
fajr: userRecord?.fajr || 0,
|
||||
dhuhr: userRecord?.dhuhr || 0,
|
||||
asr: userRecord?.asr || 0,
|
||||
maghrib: userRecord?.maghrib || 0,
|
||||
isha: userRecord?.isha || 0,
|
||||
vitr: userRecord?.vitr || 0,
|
||||
};
|
||||
|
||||
if (userRecord) {
|
||||
await pb.collection("kaza_logs").update(userRecord.id, initialData);
|
||||
} else {
|
||||
await pb.collection("kaza_logs").create(initialData);
|
||||
}
|
||||
}
|
||||
|
||||
async function updateKazaCount(container, pb, direction) {
|
||||
const prayerId = container.querySelector("#kazaPrayerType").value;
|
||||
const countInput = container.querySelector("#kazaCount");
|
||||
const amount =
|
||||
@@ -171,22 +234,15 @@ async function updateKazaCount(container, pb, birthDate, gender, direction) {
|
||||
|
||||
try {
|
||||
const userId = pb.authStore.model.id;
|
||||
let userRecord = null;
|
||||
let userRecord = await pb
|
||||
.collection("kaza_logs")
|
||||
.getFirstListItem(`user = "${userId}"`);
|
||||
|
||||
try {
|
||||
userRecord = await pb
|
||||
.collection("kaza_logs")
|
||||
.getFirstListItem(`user = "${userId}"`);
|
||||
} catch {
|
||||
userRecord = await pb.collection("kaza_logs").create({
|
||||
user: userId,
|
||||
fajr: 0,
|
||||
dhuhr: 0,
|
||||
asr: 0,
|
||||
maghrib: 0,
|
||||
isha: 0,
|
||||
vitr: 0,
|
||||
});
|
||||
if (!userRecord) {
|
||||
alert(
|
||||
"Önce 'Kaza Borçlarını Otomatik Hesapla & Kaydet' butonuna basmalısınız.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const currentCompleted = userRecord[prayerId] || 0;
|
||||
@@ -199,44 +255,49 @@ async function updateKazaCount(container, pb, birthDate, gender, direction) {
|
||||
showKazaMsg(
|
||||
msg,
|
||||
amount > 0
|
||||
? `🎉 ${amount} vakit kılınanlara eklendi!`
|
||||
? `✓ ${amount} vakit kılınanlara eklendi!`
|
||||
: `${Math.abs(amount)} vakit düşüldü.`,
|
||||
true,
|
||||
);
|
||||
|
||||
if (countInput) countInput.value = "1";
|
||||
await refreshKazaStats(container, pb, birthDate, gender);
|
||||
await refreshKazaStats(container, pb);
|
||||
} catch (err) {
|
||||
console.error("Sayaç güncelleme hatası:", err);
|
||||
showKazaMsg(
|
||||
msg,
|
||||
"Güncelleme başarısız! PocketBase alanlarını kontrol edin.",
|
||||
false,
|
||||
);
|
||||
console.error("Güncelleme hatası:", err);
|
||||
showKazaMsg(msg, "Güncelleme başarısız. Lütfen kontrol edin.", false);
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshKazaStats(container, pb, birthDate, gender) {
|
||||
const calc = calculateMissedPrayers(birthDate, gender, 12);
|
||||
async function refreshKazaStats(container, pb) {
|
||||
const userId = pb.authStore.model.id;
|
||||
|
||||
let userRecord = { fajr: 0, dhuhr: 0, asr: 0, maghrib: 0, isha: 0, vitr: 0 };
|
||||
let userRecord = null;
|
||||
|
||||
try {
|
||||
const record = await pb
|
||||
userRecord = await pb
|
||||
.collection("kaza_logs")
|
||||
.getFirstListItem(`user = "${userId}"`);
|
||||
if (record) userRecord = record;
|
||||
} catch (err) {}
|
||||
|
||||
let grandTotalMissed = 0;
|
||||
if (!userRecord) {
|
||||
// Kayıt yoksa kartları sıfır göster
|
||||
PRAYERS.forEach((p) => {
|
||||
const remainEl = container.querySelector(`#remaining-${p.id}`);
|
||||
const completedEl = container.querySelector(`#completed-${p.id}`);
|
||||
if (remainEl) remainEl.textContent = "Hesaplanmadı";
|
||||
if (completedEl) completedEl.textContent = "0";
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let grandTotalTarget = 0;
|
||||
let grandTotalCompleted = 0;
|
||||
|
||||
PRAYERS.forEach((p) => {
|
||||
const totalMissed = calc[p.id] || 0;
|
||||
const target = userRecord[`target_${p.id}`] || 0;
|
||||
const completed = userRecord[p.id] || 0;
|
||||
const remaining = Math.max(0, totalMissed - completed);
|
||||
const remaining = Math.max(0, target - completed);
|
||||
|
||||
grandTotalMissed += totalMissed;
|
||||
grandTotalTarget += target;
|
||||
grandTotalCompleted += completed;
|
||||
|
||||
const remainEl = container.querySelector(`#remaining-${p.id}`);
|
||||
@@ -245,21 +306,24 @@ async function refreshKazaStats(container, pb, birthDate, gender) {
|
||||
|
||||
if (remainEl) remainEl.textContent = remaining;
|
||||
if (completedEl) completedEl.textContent = completed;
|
||||
|
||||
if (progressEl) {
|
||||
const pct =
|
||||
totalMissed > 0
|
||||
? Math.min(100, Math.round((completed / totalMissed) * 100))
|
||||
target > 0
|
||||
? Math.min(100, Math.round((completed / target) * 100))
|
||||
: 100;
|
||||
progressEl.style.width = `${pct}%`;
|
||||
}
|
||||
});
|
||||
|
||||
const grandTotalRemaining = Math.max(
|
||||
0,
|
||||
grandTotalTarget - grandTotalCompleted,
|
||||
);
|
||||
const overallPct =
|
||||
grandTotalMissed > 0
|
||||
grandTotalTarget > 0
|
||||
? Math.min(
|
||||
100,
|
||||
Math.round((grandTotalCompleted / grandTotalMissed) * 100),
|
||||
Math.round((grandTotalCompleted / grandTotalTarget) * 100),
|
||||
)
|
||||
: 100;
|
||||
|
||||
@@ -271,8 +335,7 @@ async function refreshKazaStats(container, pb, birthDate, gender) {
|
||||
if (bar) bar.style.width = `${overallPct}%`;
|
||||
if (pctText) pctText.textContent = `%${overallPct}`;
|
||||
if (compText) compText.textContent = grandTotalCompleted;
|
||||
if (remText)
|
||||
remText.textContent = Math.max(0, grandTotalMissed - grandTotalCompleted);
|
||||
if (remText) remText.textContent = grandTotalRemaining;
|
||||
}
|
||||
|
||||
function showKazaMsg(el, text, success) {
|
||||
|
||||
Reference in New Issue
Block a user