From 9286a283c0f2e45d53583fd26934161214dccb24 Mon Sep 17 00:00:00 2001 From: soheil khaledabadi Date: Tue, 22 Sep 2026 01:38:00 +0330 Subject: [PATCH] feat: full profile editing (email/password/mobile/card) + lighter background particles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ModalEditProfile now lets users optionally change email, password, and card number, plus a two-step OTP flow to change their mobile number. All fields remain optional except when actively submitted. - Particle background: dropped canvas shadowBlur and the warp effect on links (the most expensive per-frame draw calls), disabled detectRetina (was rendering at 2-3x resolution on high-DPI screens), capped fps at 30, and paused rendering when the tab is hidden or the canvas is out of viewport (pauseOnBlur / pauseOnOutsideViewport) — this was the main site-wide slowdown since it renders on every page via the root layout. Co-Authored-By: Claude Sonnet 5 --- src/components/particle/index.tsx | 31 +- src/pages/profile/section/ProfileDetails.tsx | 22 +- .../section/components/ModalEditProfile.tsx | 276 ++++++++++++++++-- src/types/props.d.ts | 1 + 4 files changed, 277 insertions(+), 53 deletions(-) diff --git a/src/components/particle/index.tsx b/src/components/particle/index.tsx index b413bbb..64da63e 100644 --- a/src/components/particle/index.tsx +++ b/src/components/particle/index.tsx @@ -1,7 +1,6 @@ import { useEffect, useMemo, useState } from "react"; import Particles, { initParticlesEngine } from "@tsparticles/react"; import { - type Container, type ISourceOptions, MoveDirection, OutMode, @@ -26,10 +25,6 @@ export default function Particle() { }); }, []); - const particlesLoaded = async (container?: Container): Promise => { - console.log(container); - }; - const options: ISourceOptions = useMemo( () => ({ background: { @@ -37,7 +32,9 @@ export default function Particle() { value: "", }, }, - fpsLimit: 60, + fpsLimit: 30, + pauseOnBlur: true, + pauseOnOutsideViewport: true, interactivity: { events: { onClick: { @@ -69,20 +66,6 @@ export default function Particle() { enable: true, opacity: 0.8, width: 1, - shadow: { - enable: true, - blur: 5, - color: "#71fbb2", - }, - warp: { - enable: true, - speed: 2, - }, - animation: { - enable: true, - speed: 0.5, - sync: true, - }, }, move: { direction: MoveDirection.none, @@ -110,7 +93,7 @@ export default function Particle() { value: { min: 1, max: 5 }, }, }, - detectRetina: true, + detectRetina: false, }), [] ); @@ -121,11 +104,7 @@ export default function Particle() { if (init) { return ( - + ); } diff --git a/src/pages/profile/section/ProfileDetails.tsx b/src/pages/profile/section/ProfileDetails.tsx index d325aa0..a5cec46 100644 --- a/src/pages/profile/section/ProfileDetails.tsx +++ b/src/pages/profile/section/ProfileDetails.tsx @@ -16,7 +16,12 @@ const ProfileDetails = ({ }: ProfileDetailsProps) => { return (
- + { +const EditProfile = ({ + nationalId, + email, + mobile, + cardNumber, +}: { + nationalId?: string | null; + email?: string | null; + mobile?: string | null; + cardNumber?: string | null; +}) => { const [isOpen, setIsOpen] = useState(false); const dispatch = useDispatch(); return ( @@ -39,6 +54,9 @@ const EditProfile = ({ nationalId }: { nationalId?: string | null }) => { isOpen={isOpen} setIsOpen={setIsOpen} nationalId={nationalId} + email={email} + mobile={mobile} + cardNumber={cardNumber} /> + )} +
+ ) : ( +
+ + کد تایید به شماره {newMobile} پیامک شد. + + + setMobileCode(e.target.value.replace(/[^0-9]/g, "")) + } + /> +
+ + +
+
+ )} + + + setEmailValue(e.target.value)} + /> + +
+ setPassword(e.target.value)} + /> + {password && ( + setPasswordConfirmation(e.target.value)} + /> + )} +
+ + + setCardNumberValue(e.target.value.replace(/[^0-9]/g, "")) + } + /> + کد ملی برای احراز هویت شاهکار در خریدهای با مبلغ بالا لازم است. diff --git a/src/types/props.d.ts b/src/types/props.d.ts index 262532a..c54e781 100644 --- a/src/types/props.d.ts +++ b/src/types/props.d.ts @@ -218,6 +218,7 @@ type UserProfile = { email: string; mobile: string; national_id?: string | null; + card_number?: string | null; }; // تعریف تایپ پیکربندی‌ها