Browse Source

refactor: standardize profile opening flow using async refetching and replace deprecated useEffect-based logic across match modules

master
mortezaei 2 weeks ago
parent
commit
a99a66d801
  1. 63
      src/app/new-match/new-match-client.tsx
  2. 2
      src/app/new-match/profile/page.tsx
  3. 38
      src/app/request-accepted/request-accepted-client.tsx
  4. 33
      src/app/request-sent/request-sent-client.tsx

63
src/app/new-match/new-match-client.tsx

@ -488,9 +488,15 @@ export default function NewMatchClient() {
const { isAdvisorOpen, openAdvisors, closeAdvisors } =
useMarriageAdvisorsOverlay();
const { isProfileOpen, openProfile, closeProfile } = useMatchProfileOverlay();
const {
data: profile,
isError,
isLoading,
isFetched,
isFetching,
refetch: refetchProfile,
} = useMarriageProfileQuery();
const [isOpeningProfile, setIsOpeningProfile] = useState(false);
const { data: profile, isError, isLoading, isFetched } =
useMarriageProfileQuery();
const [isPaymentSheetOpen, setIsPaymentSheetOpen] = useState(false);
const [isDeclineConfirmOpen, setIsDeclineConfirmOpen] = useState(false);
const [paymentError, setPaymentError] = useState<string | null>(null);
@ -608,20 +614,43 @@ export default function NewMatchClient() {
// Signal Flutter to lift its loading cover immediately with 0ms latency.
useHabibWebReady(true);
const handleOpenProfile = () => {
if (profile) {
openProfile();
} else {
const handleOpenProfile = async () => {
// If profile has not yet completed its initial server fetch or is in flight:
if (!isFetched || isFetching) {
setIsOpeningProfile(true);
try {
const result = await refetchProfile();
const freshProfile = result.data ?? profile;
setIsOpeningProfile(false);
const isMaleUser = freshProfile?.gender === "male";
const hasActiveSubscription =
!!freshProfile?.active_subscription &&
freshProfile.active_subscription.is_active !== false &&
freshProfile.active_subscription.is_valid !== false;
if (isMaleUser && !hasActiveSubscription) {
setIsPaymentSheetOpen(true);
} else {
openProfile();
}
} catch (err) {
setIsOpeningProfile(false);
if (isMale && !hasActiveSub) {
setIsPaymentSheetOpen(true);
} else {
openProfile();
}
}
return;
}
};
useEffect(() => {
if (isOpeningProfile && profile) {
setIsOpeningProfile(false);
if (isMale && !hasActiveSub) {
setIsPaymentSheetOpen(true);
} else {
openProfile();
}
}, [isOpeningProfile, profile, openProfile]);
};
const isRedirecting = useMemo(() => {
if (!profile) return false;
@ -835,14 +864,8 @@ export default function NewMatchClient() {
{/* Button */}
<button
type="button"
disabled={isOpeningProfile && isLoading}
onClick={() => {
if (isMale && !hasActiveSub) {
setIsPaymentSheetOpen(true);
} else {
handleOpenProfile();
}
}}
disabled={isOpeningProfile}
onClick={handleOpenProfile}
className="
mt-2.5
flex
@ -863,7 +886,7 @@ export default function NewMatchClient() {
border-none
"
>
{isOpeningProfile && isLoading ? (
{isOpeningProfile ? (
<LoadingThreeDot />
) : (
<>

2
src/app/new-match/profile/page.tsx

@ -688,7 +688,7 @@ export default function NewMatchProfilePage({
<MatchPublicProfileFields
publicInfo={profile?.match_summary?.public_info}
isCandidateFemale={true}
isCandidateFemale={isCandidateFemale}
dictionary={t}
/>
</section>

38
src/app/request-accepted/request-accepted-client.tsx

@ -241,9 +241,14 @@ export default function RequestAcceptedClient() {
useState(false);
const [hasConfirmedFemaleContact, setHasConfirmedFemaleContact] =
useState(false);
const [showPaymentSuccessToast, setShowPaymentSuccessToast] = useState(false);
const [isOpeningProfile, setIsOpeningProfile] = useState(false);
const { data: profile, isLoading, isFetched } = useMarriageProfileQuery();
const {
data: profile,
isLoading,
isFetched,
isFetching,
refetch: refetchProfile,
} = useMarriageProfileQuery();
const isFemaleProfile = profile?.gender === "female";
const contactSharedAtStr = profile?.active_case?.contact_shared_at;
@ -264,21 +269,20 @@ export default function RequestAcceptedClient() {
// Signal Flutter to lift its loading cover immediately with 0ms latency.
useHabibWebReady(true);
const handleOpenProfile = () => {
if (profile) {
openProfile();
} else {
const handleOpenProfile = async () => {
if (!isFetched || isFetching) {
setIsOpeningProfile(true);
try {
await refetchProfile();
} finally {
setIsOpeningProfile(false);
openProfile();
}
return;
}
openProfile();
};
useEffect(() => {
if (isOpeningProfile && profile) {
setIsOpeningProfile(false);
openProfile();
}
}, [isOpeningProfile, profile, openProfile]);
const isRedirecting = useMemo(() => {
if (!profile) return false;
return getSubmitPath(profile) !== "/request-accepted";
@ -706,11 +710,11 @@ export default function RequestAcceptedClient() {
<>
<button
type="button"
disabled={isOpeningProfile && isLoading}
disabled={isOpeningProfile}
onClick={handleOpenProfile}
className="flex-1 h-[50px] px-3 rounded-[14px] border border-[#E2E8F0] bg-white/95 backdrop-blur-sm text-[#334155] font-bold text-[14px] shadow-sm flex items-center justify-center transition-transform active:scale-[0.98] cursor-pointer hover:bg-[#F8FAFC]"
>
{isOpeningProfile && isLoading ? (
{isOpeningProfile ? (
<LoadingThreeDot />
) : (
t["View Profile"]
@ -753,11 +757,11 @@ export default function RequestAcceptedClient() {
) : (
<button
type="button"
disabled={isOpeningProfile && isLoading}
disabled={isOpeningProfile}
onClick={handleOpenProfile}
className="flex-1 min-h-[48px] px-3.5 py-2.5 rounded-[14px] border border-[#E2E8F0] bg-white/95 backdrop-blur-sm text-[#475569] font-bold text-[14px] leading-tight shadow-sm flex items-center justify-center text-center whitespace-nowrap transition-all hover:bg-[#F8FAFC] active:scale-[0.98] cursor-pointer"
>
{isOpeningProfile && isLoading ? (
{isOpeningProfile ? (
<LoadingThreeDot />
) : (
primaryActionText

33
src/app/request-sent/request-sent-client.tsx

@ -34,7 +34,13 @@ export default function RequestSentClient() {
const { isProfileOpen, openProfile, closeProfile } =
useMatchProfileOverlay();
const [isOpeningProfile, setIsOpeningProfile] = useState(false);
const { data: profile, isLoading, isFetched } = useMarriageProfileQuery({
const {
data: profile,
isLoading,
isFetched,
isFetching,
refetch: refetchProfile,
} = useMarriageProfileQuery({
refetchInterval: 3000,
});
@ -59,21 +65,20 @@ export default function RequestSentClient() {
return getSubmitPath(profile) !== "/request-sent";
}, [profile]);
const handleOpenProfile = () => {
if (profile) {
openProfile();
} else {
const handleOpenProfile = async () => {
if (!isFetched || isFetching) {
setIsOpeningProfile(true);
try {
await refetchProfile();
} finally {
setIsOpeningProfile(false);
openProfile();
}
return;
}
openProfile();
};
useEffect(() => {
if (isOpeningProfile && profile) {
setIsOpeningProfile(false);
openProfile();
}
}, [isOpeningProfile, profile, openProfile]);
const copy = {
advisorTitle: t["Get an advisor"],
advisorDescription:
@ -138,12 +143,12 @@ export default function RequestSentClient() {
{/* Button */}
<button
type="button"
disabled={isOpeningProfile && isLoading}
disabled={isOpeningProfile}
onClick={handleOpenProfile}
className="mt-12 w-full max-w-[300px] cursor-pointer transition-transform active:scale-[0.97]"
>
<div className="flex items-center justify-center min-h-[54px] rounded-[14px] bg-gradient-to-r from-[#FF6687] to-[#FF456C] px-6 py-4 text-[16px] font-bold text-white shadow-sm hover:opacity-95">
{isOpeningProfile && isLoading ? (
{isOpeningProfile ? (
<LoadingThreeDot />
) : (
requestSentCopy.matchProfile

Loading…
Cancel
Save