fix(payg): land usage-limit modal CTAs on the Plan section (#6630)

This commit is contained in:
ConnorYoh
2026-06-11 21:42:59 +01:00
committed by GitHub
parent 22379fd5ab
commit eddc54c6c0
3 changed files with 20 additions and 13 deletions
@@ -8,7 +8,7 @@ import LocalIcon from "@app/components/shared/LocalIcon";
import Overview from "@app/components/shared/config/configSections/Overview";
import { createSaasConfigNavSections } from "@app/components/shared/config/saasConfigNavSections";
import { NavKey } from "@app/components/shared/config/types";
import { withBasePath } from "@app/constants/app";
import { stripBasePath, withBasePath } from "@app/constants/app";
import { COOKIE_CONSENT_SCROLL_SHARD } from "@app/hooks/useCookieConsent";
import "@app/components/shared/AppConfigModal.css";
import {
@@ -47,6 +47,21 @@ const AppConfigModal: React.FC<AppConfigModalProps> = ({ opened, onClose }) => {
);
}, []);
// When the modal opens via a /settings/<section> deep link (navigateToSettings — e.g. the
// usage-limit modal CTAs, which need to land on the Plan section), select that section. The
// opener (QuickAccessBar) opens the modal whenever the path is /settings/*, but doesn't carry
// the section, and `active` defaults to "overview" — so without this a deep link would open on
// Overview rather than the linked section.
useEffect(() => {
if (!opened) return;
const match = stripBasePath(window.location.pathname).match(
/^\/settings\/([^/?#]+)/,
);
if (match) {
setActive(match[1] as NavKey);
}
}, [opened]);
// Listen for notice updates (e.g., "Not enough credits..." next to Plan title)
useEffect(() => {
const handler = (ev: Event) => {
@@ -5,7 +5,7 @@ import CelebrationIcon from "@mui/icons-material/CelebrationOutlined";
import AnimatedSlideBackground from "@app/components/onboarding/slides/AnimatedSlideBackground";
import styles from "@app/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css";
import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from "@app/styles/zIndex";
import { openPlanSettings } from "@app/utils/appSettings";
import { navigateToSettings } from "@app/utils/settingsNavigation";
import {
FreeMeterPanel,
freeSnapshotFromWallet,
@@ -69,11 +69,7 @@ export function FreeLimitReachedModal({ onClose }: FreeLimitReachedModalProps) {
const handleUpgrade = () => {
onClose();
// Open the App Config modal AND select the Plan section. navigateToSettings("plan") only
// pushes a /settings/plan URL, which in SaaS opens config at its default section rather than
// the Plan page; openPlanSettings dispatches the appConfig:open + appConfig:navigate events the
// config modal actually listens for.
openPlanSettings();
navigateToSettings("plan");
};
return (
@@ -5,7 +5,7 @@ import TrendingUpIcon from "@mui/icons-material/TrendingUpOutlined";
import AnimatedSlideBackground from "@app/components/onboarding/slides/AnimatedSlideBackground";
import styles from "@app/components/onboarding/InitialOnboardingModal/InitialOnboardingModal.module.css";
import { Z_INDEX_OVER_FULLSCREEN_SURFACE } from "@app/styles/zIndex";
import { openPlanSettings } from "@app/utils/appSettings";
import { navigateToSettings } from "@app/utils/settingsNavigation";
import {
SpendCapMeterPanel,
spendCapSnapshotFromWallet,
@@ -69,11 +69,7 @@ export function SpendCapReachedModal({ onClose }: SpendCapReachedModalProps) {
const handleRaiseCap = () => {
onClose();
// Open the App Config modal AND select the Plan section. navigateToSettings("plan") only
// pushes a /settings/plan URL, which in SaaS opens config at its default section rather than
// the Plan page; openPlanSettings dispatches the appConfig:open + appConfig:navigate events the
// config modal actually listens for.
openPlanSettings();
navigateToSettings("plan");
};
return (