diff --git a/src/components/app.tsx b/src/components/app.tsx
index c0329b99d7..3eb90a9aec 100644
--- a/src/components/app.tsx
+++ b/src/components/app.tsx
@@ -4,9 +4,9 @@ import {
} from '@wordpress/components';
import { useEffect } from 'react';
import MacTitlebar from 'src/components/mac-titlebar';
+import { MainContent } from 'src/components/main-content';
import MainSidebar from 'src/components/main-sidebar';
import { NoStudioSites } from 'src/components/no-studio-sites';
-import { SiteContentTabs } from 'src/components/site-content-tabs';
import TopBar from 'src/components/top-bar';
import WindowsTitlebar from 'src/components/windows-titlebar';
import { useLocalizationSupport } from 'src/hooks/use-localization-support';
@@ -18,6 +18,7 @@ import { getIpcApi } from 'src/lib/get-ipc-api';
import { Onboarding } from 'src/modules/onboarding';
import { useOnboarding } from 'src/modules/onboarding/hooks/use-onboarding';
import { UserSettings } from 'src/modules/user-settings';
+import { VipProvider } from 'src/modules/vip/context/vip-context';
import { WhatsNewModal, useWhatsNew } from 'src/modules/whats-new';
import { useRootSelector } from 'src/stores';
import { selectOnboardingLoading } from 'src/stores/onboarding-slice';
@@ -42,7 +43,7 @@ export default function App() {
}
return (
- <>
+
{ needsOnboarding || isEmpty ? (
-
+
) }
- >
+
);
}
diff --git a/src/components/main-content.tsx b/src/components/main-content.tsx
new file mode 100644
index 0000000000..a003816b75
--- /dev/null
+++ b/src/components/main-content.tsx
@@ -0,0 +1,30 @@
+import { useSiteDetails } from 'src/hooks/use-site-details';
+import { VipContentTabs } from 'src/modules/vip/components/vip-content-tabs';
+import { useVipContext } from 'src/modules/vip/context/vip-context';
+import { SiteContentTabs } from './site-content-tabs';
+
+/**
+ * Main content area that displays either regular site content or VIP environment content
+ * based on which is currently selected.
+ *
+ * VIP environment is checked first because the regular site selection has fallback behavior
+ * that always returns a site when sites exist. When a user actively clicks a VIP environment,
+ * that selection should take priority.
+ */
+export function MainContent() {
+ const { selectedSite } = useSiteDetails();
+ const { selectedEnvironment } = useVipContext();
+
+ // If a VIP environment is selected, show VIP content (check first due to regular site fallback behavior)
+ if ( selectedEnvironment ) {
+ return ;
+ }
+
+ // If a regular site is selected, show regular site content
+ if ( selectedSite ) {
+ return ;
+ }
+
+ // Default to regular site content tabs (which handles the "no site selected" state)
+ return ;
+}
diff --git a/src/components/main-sidebar.tsx b/src/components/main-sidebar.tsx
index 2328d05602..de155c48e4 100644
--- a/src/components/main-sidebar.tsx
+++ b/src/components/main-sidebar.tsx
@@ -5,6 +5,7 @@ import { useSiteDetails } from 'src/hooks/use-site-details';
import { isMac } from 'src/lib/app-globals';
import { cx } from 'src/lib/cx';
import AddSite from 'src/modules/add-site';
+import VipSiteMenu from 'src/modules/vip/components/vip-site-menu';
interface MainSidebarProps {
className?: string;
@@ -12,6 +13,7 @@ interface MainSidebarProps {
export default function MainSidebar( { className }: MainSidebarProps ) {
const { sites: localSites } = useSiteDetails();
+ const hasLocalSites = localSites.length > 0;
return (
- { ! localSites.length ? (
-
- { __( 'Your sites will show up here once you create them' ) }
-
- ) : (
-
-
+
+
+ { hasLocalSites ? (
-
-
-
-
-
+ ) : (
+
+ { __( 'Your sites will show up here once you create them' ) }
+ ) }
+
+
+
- ) }
+
);
}
diff --git a/src/components/site-menu.tsx b/src/components/site-menu.tsx
index 542a317f03..e3a60886c0 100644
--- a/src/components/site-menu.tsx
+++ b/src/components/site-menu.tsx
@@ -15,6 +15,7 @@ import { cx } from 'src/lib/cx';
import { getIpcApi } from 'src/lib/get-ipc-api';
import { supportedEditorConfig } from 'src/modules/user-settings/lib/editor';
import { getTerminalName } from 'src/modules/user-settings/lib/terminal';
+import { useVipContext } from 'src/modules/vip/context/vip-context';
import { useGetUserEditorQuery, useGetUserTerminalQuery } from 'src/stores/installed-apps-api';
interface SiteMenuProps {
@@ -134,6 +135,7 @@ function ButtonToRun( {
}
function SiteItem( { site }: { site: SiteDetails } ) {
const { selectedSite, setSelectedSiteId, loadingServer, isSiteDeleting } = useSiteDetails();
+ const { selectEnvironment } = useVipContext();
const isSelected = site === selectedSite;
const { isSiteImporting, isSiteExporting } = useImportExport();
const { isSiteIdPulling, isSiteIdPushing } = useSyncSites();
@@ -193,6 +195,8 @@ function SiteItem( { site }: { site: SiteDetails } ) {