From b53a5515d6ef2ebf50c65e636381615354c4a4d7 Mon Sep 17 00:00:00 2001 From: Sanaei Date: Sat, 15 Aug 2026 23:35:00 +0200 Subject: [PATCH] fix(frontend): make the jalali expiry clear button actually clear MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit persian-calendar-suite seeds today's date and emits it whenever it mounts without a value. Clearing the expiry remounts the picker with a null value, so the library immediately fired onChange(today) and the date came straight back — and it also painted that seeded date into its read-only input. Swallow the mount-time emit (re-armed on every clear-remount) and hide the seeded text while the value is empty, so a cleared expiry stays empty and a fresh client/inbound form no longer silently adopts today as its expiry. --- frontend/src/components/form/DateTimePicker.css | 6 ++++++ frontend/src/components/form/DateTimePicker.tsx | 13 ++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/form/DateTimePicker.css b/frontend/src/components/form/DateTimePicker.css index 5fbcbf514..b8f289f9b 100644 --- a/frontend/src/components/form/DateTimePicker.css +++ b/frontend/src/components/form/DateTimePicker.css @@ -69,3 +69,9 @@ .jdp-ultra .jdp-clear:hover { color: rgba(255, 255, 255, 0.45); } + +/* With no value the library still paints today's date into its readOnly input; + hide it so an empty (or just-cleared) expiry actually looks empty. */ +.jdp-wrap.jdp-empty input { + color: transparent !important; +} diff --git a/frontend/src/components/form/DateTimePicker.tsx b/frontend/src/components/form/DateTimePicker.tsx index f407e2b6f..0e955ed61 100644 --- a/frontend/src/components/form/DateTimePicker.tsx +++ b/frontend/src/components/form/DateTimePicker.tsx @@ -61,6 +61,16 @@ export default function DateTimePicker({ // Bumped on clear: persian-calendar-suite reads `value` only on mount, so // remounting via key is the only way to reflect an externally cleared value. const [clearNonce, setClearNonce] = useState(0); + // Mounted without a value, persian-calendar-suite seeds today and emits it — + // which would instantly undo a clear. Armed across every (re)mount. + const suppressMountEmit = useRef(true); + + useEffect(() => { + suppressMountEmit.current = false; + return () => { + suppressMountEmit.current = true; + }; + }, [clearNonce]); const persianTheme = useMemo(() => { if (isUltra) return ULTRA_DARK_THEME; @@ -80,11 +90,12 @@ export default function DateTimePicker({ if (datepicker === 'jalalian') { return ( -
+
{ + if (suppressMountEmit.current) return; if (next == null || next === '') { onChange(null); return;