fix(daily-control): «ماه بعد» navigation + hover feedback
The month-shift anchor discarded the day returned by jalaliToGregorian: new Date(gy, gm-1, 1) instead of new Date(gy, gm-1, gd). Jalali months start mid-Gregorian-month (مهر ۱ = 2026-09-23), so the anchor landed on the 1st of the Gregorian month — still inside the SAME Jalali month (شهریور ۱۰) — and «ماه بعد» appeared dead while «ماه قبل» only seemed to work because its wrong target showed a different label. This was also the source of the reported ~22-day date mismatches. - shiftMonth now keeps the converted day (gy, gm, gd) - nav buttons fire on pointerup/click/keyboard with a dedupe guard so the action survives browsers that swallow the click event - buttons got hover feedback (cursor-pointer, hover:bg-slate-100, transition-colors) Verified against the library math: from شهریور ۱۴۰۵, next → مهر ۱۴۰۵, prev → مرداد ۱۴۰۵; confirmed in the deployed bundle.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useMemo, useState } from "react";
|
import { useMemo, useRef, useState } from "react";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { Header, PageLayout } from "../../components/layout/Header";
|
import { Header, PageLayout } from "../../components/layout/Header";
|
||||||
import { useAuthStore } from "../../store/auth";
|
import { useAuthStore } from "../../store/auth";
|
||||||
@@ -90,11 +90,40 @@ export function DailyControlPage() {
|
|||||||
nm = 1;
|
nm = 1;
|
||||||
ny += 1;
|
ny += 1;
|
||||||
}
|
}
|
||||||
const [gy, gm] = jalaliToGregorian(ny, nm, 1);
|
// روزِ برگشتی را نگه میداریم (ماه شمسی از میانهی ماه میلادی شروع میشود:
|
||||||
setAnchor(new Date(gy, gm - 1, 1));
|
// مثلاً مهر ۱ = ۲۳ سپتامبر). اگر بهجای آن روز «۱» استفاده شود، لنگر در
|
||||||
|
// اولِ ماهِ میلادی مینشیند و هنوز در همان ماه شمسی است — دکمه «ماه بعد»
|
||||||
|
// ظاهراً هیچ کاری نمیکند.
|
||||||
|
const [gy, gm, gd] = jalaliToGregorian(ny, nm, 1);
|
||||||
|
setAnchor(new Date(gy, gm - 1, gd));
|
||||||
};
|
};
|
||||||
|
|
||||||
const dayTx = txByDay.get(sel) || [];
|
const dayTx = txByDay.get(sel) || [];
|
||||||
|
|
||||||
|
// فعالسازی ناوبری ماه از چند مسیر (pointerup / click / کیبورد) با حذف
|
||||||
|
// اجرای تکراری — اگر مرورگر رویداد click را بخورد، pointerup جواب میدهد.
|
||||||
|
const navLast = useRef<{ key: string; at: number }>({ key: "", at: 0 });
|
||||||
|
const navFire = (key: string, action: () => void) => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (navLast.current.key === key && now - navLast.current.at < 350) return;
|
||||||
|
navLast.current = { key, at: now };
|
||||||
|
action();
|
||||||
|
};
|
||||||
|
const navBtnProps = (key: string, action: () => void) => ({
|
||||||
|
type: "button" as const,
|
||||||
|
onPointerUp: (e: React.PointerEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
navFire(key, action);
|
||||||
|
},
|
||||||
|
onClick: () => navFire(key, action),
|
||||||
|
onKeyDown: (e: React.KeyboardEvent) => {
|
||||||
|
if (e.key === "Enter" || e.key === " ") {
|
||||||
|
e.preventDefault();
|
||||||
|
navFire(key, action);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const withdrawals = dayTx.filter((t) => t.transaction_type === "WITHDRAWAL");
|
const withdrawals = dayTx.filter((t) => t.transaction_type === "WITHDRAWAL");
|
||||||
const wGroups = useMemo(() => {
|
const wGroups = useMemo(() => {
|
||||||
const gmap = new Map<string, { recId: string; q: number; last: string; tx: InventoryTransaction }>();
|
const gmap = new Map<string, { recId: string; q: number; last: string; tx: InventoryTransaction }>();
|
||||||
@@ -149,9 +178,9 @@ export function DailyControlPage() {
|
|||||||
<div className="mb-2 flex items-center justify-between">
|
<div className="mb-2 flex items-center justify-between">
|
||||||
<div className="text-[14px] font-bold">📅 {monthTitle}</div>
|
<div className="text-[14px] font-bold">📅 {monthTitle}</div>
|
||||||
<div className="flex gap-1.5">
|
<div className="flex gap-1.5">
|
||||||
<button className="rounded-lg border border-line px-3 py-1 text-[12px]" onClick={() => shiftMonth(-1)}>▶ ماه قبل</button>
|
<button className="cursor-pointer rounded-lg border border-line px-3 py-1 text-[12px] transition-colors hover:bg-slate-100" {...navBtnProps("prev", () => shiftMonth(-1))}>▶ ماه قبل</button>
|
||||||
<button className="rounded-lg border border-line px-3 py-1 text-[12px]" onClick={() => { setAnchor(new Date()); setSel(todayKey()); setActRec(null); }}>امروز</button>
|
<button className="cursor-pointer rounded-lg border border-line px-3 py-1 text-[12px] transition-colors hover:bg-slate-100" {...navBtnProps("today", () => { setAnchor(new Date()); setSel(todayKey()); setActRec(null); })}>امروز</button>
|
||||||
<button className="rounded-lg border border-line px-3 py-1 text-[12px]" onClick={() => shiftMonth(1)}>◀ ماه بعد</button>
|
<button className="cursor-pointer rounded-lg border border-line px-3 py-1 text-[12px] transition-colors hover:bg-slate-100" {...navBtnProps("next", () => shiftMonth(1))}>◀ ماه بعد</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-7 gap-1">
|
<div className="grid grid-cols-7 gap-1">
|
||||||
|
|||||||
Reference in New Issue
Block a user