@@ -7,7 +7,7 @@ import { UpgradeGuard } from "./components/upgradeGuard";
77import { cookies , headers } from "next/headers" ;
88import { getSelectorsByUserAgent } from "react-device-detect" ;
99import { MobileUnsupportedSplashScreen } from "./components/mobileUnsupportedSplashScreen" ;
10- import { MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME } from "@/lib/constants" ;
10+ import { MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME , OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAME } from "@/lib/constants" ;
1111import { SyntaxReferenceGuide } from "./components/syntaxReferenceGuide" ;
1212import { SyntaxGuideProvider } from "./components/syntaxGuideProvider" ;
1313import { IS_BILLING_ENABLED } from "@/ee/features/billing/stripe" ;
@@ -23,6 +23,8 @@ import { JoinOrganizationCard } from "@/app/components/joinOrganizationCard";
2323import { LogoutEscapeHatch } from "@/app/components/logoutEscapeHatch" ;
2424import { GitHubStarToast } from "./components/githubStarToast" ;
2525import { UpgradeToast } from "./components/upgradeToast" ;
26+ import { getUnlinkedIntegrationProviders , userNeedsToLinkIdentityProvider } from "@/ee/features/permissionSyncing/actions" ;
27+ import { LinkAccounts } from "@/ee/features/permissionSyncing/linkAccounts" ;
2628
2729interface LayoutProps {
2830 children : React . ReactNode ,
@@ -123,6 +125,49 @@ export default async function Layout(props: LayoutProps) {
123125 )
124126 }
125127
128+ if ( hasEntitlement ( "permission-syncing" ) ) {
129+ const unlinkedAccounts = await getUnlinkedIntegrationProviders ( ) ;
130+ if ( isServiceError ( unlinkedAccounts ) ) {
131+ return (
132+ < div className = "min-h-screen flex flex-col items-center justify-center p-6" >
133+ < LogoutEscapeHatch className = "absolute top-0 right-0 p-6" />
134+ < div className = "bg-red-50 border border-red-200 rounded-md p-6 max-w-md w-full text-center" >
135+ < h2 className = "text-lg font-semibold text-red-800 mb-2" > An error occurred</ h2 >
136+ < p className = "text-red-700 mb-1" >
137+ { typeof unlinkedAccounts . message === 'string'
138+ ? unlinkedAccounts . message
139+ : "A server error occurred while checking your account status. Please try again or contact support." }
140+ </ p >
141+ </ div >
142+ </ div >
143+ )
144+ }
145+
146+ if ( unlinkedAccounts . length > 0 ) {
147+ // Separate required and optional providers
148+ const requiredProviders = unlinkedAccounts . filter ( p => p . required !== false ) ;
149+ const hasRequiredProviders = requiredProviders . length > 0 ;
150+
151+ // Check if user has skipped optional providers
152+ const cookieStore = await cookies ( ) ;
153+ const hasSkippedOptional = cookieStore . has ( OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAME ) ;
154+
155+ // Show LinkAccounts if:
156+ // 1. There are required providers, OR
157+ // 2. There are only optional providers AND user hasn't skipped yet
158+ const shouldShowLinkAccounts = hasRequiredProviders || ! hasSkippedOptional ;
159+
160+ if ( shouldShowLinkAccounts ) {
161+ return (
162+ < div className = "min-h-screen flex items-center justify-center p-6" >
163+ < LogoutEscapeHatch className = "absolute top-0 right-0 p-6" />
164+ < LinkAccounts unlinkedAccounts = { unlinkedAccounts } />
165+ </ div >
166+ )
167+ }
168+ }
169+ }
170+
126171 if ( IS_BILLING_ENABLED ) {
127172 const subscription = await getSubscriptionInfo ( domain ) ;
128173 if (
0 commit comments