Files
nobat724_front/components/register/verificationPage/Recode.js
T
hamedandClaude Sonnet 4.6 59e0a0fe4f fix: resolve critical bugs and security issues across the project
Security:
- Disable SSL verification only in development (lib/req.js)
- Wrap all JSON.parse(cookie) calls in try-catch via safeJsonParse utility
- Sanitize dangerouslySetInnerHTML in blog/clinic with sanitizeHtml utility
- Fix open redirect in payment page — validate URL origin before redirect
- Fix cookie cleanup on 401 — use js-cookie with correct domain scope

Performance:
- Wrap ItemDoctor with React.memo to prevent unnecessary re-renders
- Replace <img> with Next.js <Image> in blog Caption component

Functionality:
- Fix memory leak in Recode.js — store intervals in refs, cleanup on unmount
- Add null guard on retryIcon.current before classList manipulation
- Fix getParsedUserInfo in helper to handle malformed cookie gracefully

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 09:19:20 +03:30

96 lines
2.6 KiB
JavaScript

import RetryLogin from "@/components/icons/RetryLogin";
import { changeNumToDefault } from "@/helper";
import { request } from "@/services/response";
import { Button } from "@mui/material";
import { useEffect, useRef } from "react";
const time_resend_code = 120;
function Recode({ retryIcon, timer, setUuid, num, setTimer }) {
const timerIntervalRef = useRef(null);
const animIntervalRef = useRef(null);
useEffect(() => {
return () => {
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
if (animIntervalRef.current) clearInterval(animIntervalRef.current);
};
}, []);
const handleTimer = () => {
setTimer("loading");
if (timerIntervalRef.current) clearInterval(timerIntervalRef.current);
setTimeout(() => {
setTimer(time_resend_code);
let timePresent = time_resend_code;
timerIntervalRef.current = setInterval(() => {
timePresent--;
setTimer(timePresent);
if (!timePresent) {
clearInterval(timerIntervalRef.current);
timerIntervalRef.current = null;
}
}, 1000);
}, 1000);
};
const rotateIcon = () => {
if (!retryIcon.current) return;
retryIcon.current.classList.add("retry-icon");
setTimeout(() => {
retryIcon.current?.classList.remove("retry-icon");
}, 1000);
};
const handleReq = () => {
rotateIcon();
if (animIntervalRef.current) clearInterval(animIntervalRef.current);
animIntervalRef.current = setInterval(() => {
rotateIcon();
}, 1200);
request
.sendCode(changeNumToDefault(num), "")
.then((response) => {
clearInterval(animIntervalRef.current);
animIntervalRef.current = null;
if (response.uuid) {
setUuid(response.uuid);
handleTimer();
}
})
.catch(() => {
clearInterval(animIntervalRef.current);
animIntervalRef.current = null;
});
};
return (
<Button
className="flex !p-1 items-center justify-start gap-1 hover-rotate-90 cursor-pointer"
disabled={typeof timer === "number" && timer !== 0}
onClick={() => {
if (!timer && timer !== "loading") {
handleReq();
}
}}
>
{timer && timer !== "loading" ? (
<p className="text-[#F17732] text-[14px] font-normal select-none">
{timer} ثانیه
</p>
) : (
<>
<div ref={retryIcon}>
<RetryLogin />
</div>
<p className="text-[#F17732] text-[14px] font-normal select-none">
دریافت مجدد کد
</p>
</>
)}
</Button>
);
}
export default Recode;