1+ import { useState } from 'react' ;
12import { useParams } from 'react-router' ;
3+ import { reactClient as vincentApiClient } from '@lit-protocol/vincent-registry-sdk' ;
4+
5+ import { AppUnavailableConnect } from './AppUnavailableConnect' ;
6+ import { AppVersionNotInRegistryConnect } from './AppVersionNotInRegistry' ;
7+ import { AuthConnectScreen } from './AuthConnectScreen' ;
8+ import { BadRedirectUriError } from './BadRedirectUriError' ;
29import { ConnectPage } from './ConnectPage' ;
3- import { UnifiedConnectSkeleton } from './UnifiedConnectSkeleton' ;
10+ import { DisabledVersionConnect } from './DisabledVersionConnect' ;
11+ import { EditPermissionsCard } from './EditPermissionsCard' ;
412import { GeneralErrorScreen } from './GeneralErrorScreen' ;
5- import { BadRedirectUriError } from './BadRedirectUriError' ;
6- import { AuthConnectScreen } from './AuthConnectScreen' ;
7- import { useConnectInfo } from '@/hooks/user-dashboard/connect/useConnectInfo' ;
8- import { useCheckAppVersionExists } from '@/hooks/user-dashboard/connect/useCheckAppVersionExists' ;
9- import useReadAuthInfo from '@/hooks/user-dashboard/useAuthInfo' ;
10- import { useAgentPkpForApp } from '@/hooks/user-dashboard/useAgentPkpForApp' ;
11- import { reactClient as vincentApiClient } from '@lit-protocol/vincent-registry-sdk' ;
13+ import { RepermitConnect } from './RepermitConnect' ;
1214import { ReturningUserConnect } from './ReturningUserConnect' ;
13- import { AppVersionNotInRegistryConnect } from './AppVersionNotInRegistry' ;
15+ import { UnifiedConnectSkeleton } from './UnifiedConnectSkeleton' ;
16+ import { UpdateVersionCard } from './UpdateVersionCard' ;
17+ import { useCheckAppVersionExists } from '@/hooks/user-dashboard/connect/useCheckAppVersionExists' ;
18+ import { useConnectInfo } from '@/hooks/user-dashboard/connect/useConnectInfo' ;
1419import { useUriPrecheck } from '@/hooks/user-dashboard/connect/useUriPrecheck' ;
15- import { RepermitConnect } from './RepermitConnect' ;
16- import { DisabledVersionConnect } from './DisabledVersionConnect' ;
17- import { AppUnavailableConnect } from './AppUnavailableConnect' ;
20+ import { useFetchUserPermissions } from '@/hooks/user-dashboard/dashboard/useFetchUserPermissions' ;
21+ import { useAgentPkpForApp } from '@/hooks/user-dashboard/useAgentPkpForApp' ;
22+ import useReadAuthInfo from '@/hooks/user-dashboard/useAuthInfo' ;
23+
24+ type ViewMode = 'consent' | 'edit-permissions' | 'update-version' ;
1825
1926export function ConnectPageWrapper ( ) {
2027 const { appId } = useParams ( ) ;
28+ const [ viewMode , setViewMode ] = useState < ViewMode > ( 'consent' ) ;
2129
2230 const { authInfo, sessionSigs, isProcessing, error } = useReadAuthInfo ( ) ;
2331 const {
@@ -28,7 +36,15 @@ export function ConnectPageWrapper() {
2836 error : agentPKPError ,
2937 } = useAgentPkpForApp ( authInfo ?. userPKP ?. ethAddress , appId ? Number ( appId ) : undefined ) ;
3038
31- const { isLoading, isError, errors, data } = useConnectInfo ( appId || '' ) ;
39+ const versionsToFetch =
40+ viewMode === 'edit-permissions' && permittedVersion ? [ permittedVersion ] : undefined ;
41+ const useActiveVersion = viewMode !== 'edit-permissions' ;
42+
43+ const { isLoading, isError, errors, data } = useConnectInfo (
44+ appId || '' ,
45+ versionsToFetch ,
46+ useActiveVersion ,
47+ ) ;
3248 const {
3349 appExists,
3450 activeVersionExists,
@@ -70,6 +86,12 @@ export function ConnectPageWrapper() {
7086 ? data . versionsByApp [ appId ! ] ?. find ( ( v ) => v . version === data . app . activeVersion )
7187 : undefined ;
7288
89+ // Fetch user permissions data (only when user is permitted and editing permissions)
90+ const { existingData, isLoading : isExistingDataLoading } = useFetchUserPermissions ( {
91+ appId : Number ( appId ) ,
92+ pkpEthAddress : agentPKP ?. ethAddress || '' ,
93+ } ) ;
94+
7395 // Wait for ALL critical data to load before making routing decisions
7496 const isUserAuthed = authInfo ?. userPKP && sessionSigs ;
7597
@@ -82,7 +104,9 @@ export function ConnectPageWrapper() {
82104 ! isProcessing &&
83105 // Only wait for version check and agent PKP loading if user is authenticated
84106 ( isUserAuthed ? ! actualIsVersionCheckLoading && ! agentPKPLoading : true ) &&
85- ( ! permittedVersion || ! versionDataLoading ) ;
107+ ( ! permittedVersion || ! versionDataLoading ) &&
108+ // When showing edit permissions, also wait for permissions data
109+ ( viewMode !== 'edit-permissions' || ! isExistingDataLoading ) ;
86110
87111 // Now make routing decisions with complete information
88112 let content ;
@@ -94,12 +118,13 @@ export function ConnectPageWrapper() {
94118 content = < GeneralErrorScreen errorDetails = { errorMessage } /> ;
95119 } else if ( ! isAllDataLoaded ) {
96120 content = < UnifiedConnectSkeleton mode = { isUserAuthed ? 'consent' : 'auth' } /> ;
97- } else if ( isRedirectUriAuthorized === false && redirectUri ) {
121+ } else if ( ! redirectUri ) {
98122 content = (
99- < BadRedirectUriError
100- redirectUri = { redirectUri || undefined }
101- authorizedUris = { data . app ?. redirectUris }
102- />
123+ < GeneralErrorScreen errorDetails = "No redirect URI provided. This page is for app authentication flow only." />
124+ ) ;
125+ } else if ( isRedirectUriAuthorized === false ) {
126+ content = (
127+ < BadRedirectUriError redirectUri = { redirectUri } authorizedUris = { data . app ?. redirectUris } />
103128 ) ;
104129 }
105130 // Check for unpublished app version (check this early, before auth)
@@ -146,17 +171,44 @@ export function ConnectPageWrapper() {
146171 }
147172 // Check for existing user permissions
148173 else if ( isPermitted === true && permittedVersion && versionData ) {
149- content = (
150- < ReturningUserConnect
151- appData = { data . app }
152- version = { permittedVersion }
153- versionData = { versionData }
154- activeVersionData = { activeVersionData }
155- redirectUri = { redirectUri || undefined }
156- readAuthInfo = { { authInfo, sessionSigs, isProcessing, error } }
157- agentPKP = { agentPKP ! }
158- />
159- ) ;
174+ // Toggle between consent, edit permissions, and update version views
175+ if ( viewMode === 'edit-permissions' ) {
176+ content = (
177+ < EditPermissionsCard
178+ connectInfoMap = { data }
179+ readAuthInfo = { { authInfo, sessionSigs, isProcessing, error } }
180+ agentPKP = { agentPKP ! }
181+ existingData = { existingData }
182+ permittedVersion = { permittedVersion }
183+ redirectUri = { redirectUri }
184+ onBackToConsent = { ( ) => setViewMode ( 'consent' ) }
185+ />
186+ ) ;
187+ } else if ( viewMode === 'update-version' ) {
188+ content = (
189+ < UpdateVersionCard
190+ connectInfoMap = { data }
191+ readAuthInfo = { { authInfo, sessionSigs, isProcessing, error } }
192+ agentPKP = { agentPKP ! }
193+ currentVersion = { permittedVersion }
194+ redirectUri = { redirectUri }
195+ onBackToConsent = { ( ) => setViewMode ( 'consent' ) }
196+ />
197+ ) ;
198+ } else {
199+ content = (
200+ < ReturningUserConnect
201+ appData = { data . app }
202+ version = { permittedVersion }
203+ versionData = { versionData }
204+ activeVersionData = { activeVersionData }
205+ readAuthInfo = { { authInfo, sessionSigs, isProcessing, error } }
206+ agentPKP = { agentPKP ! }
207+ onEditPermissions = { ( ) => setViewMode ( 'edit-permissions' ) }
208+ onUpdateVersion = { ( ) => setViewMode ( 'update-version' ) }
209+ />
210+ ) ;
211+ }
160212 }
161213 // Check if both user's version and active version are disabled - app is unavailable
162214 else if (
0 commit comments