@@ -3,14 +3,15 @@ import type { ComponentProps } from 'react';
33import { useState } from 'react' ;
44
55import { useEnvironment , useOAuthConsentContext } from '@/ui/contexts' ;
6- import { Box , Button , Flex , Flow , Grid , Icon , Text } from '@/ui/customizables' ;
6+ import { Box , Button , Flex , Flow , Grid , Icon , Image , Span , Text } from '@/ui/customizables' ;
77import { ApplicationLogo } from '@/ui/elements/ApplicationLogo' ;
88import { Card } from '@/ui/elements/Card' ;
99import { withCardStateProvider } from '@/ui/elements/contexts' ;
1010import { Header } from '@/ui/elements/Header' ;
1111import { Modal } from '@/ui/elements/Modal' ;
12+ import { Select , SelectButton , SelectOptionList } from '@/ui/elements/Select' ;
1213import { Tooltip } from '@/ui/elements/Tooltip' ;
13- import { LockDottedCircle } from '@/ui/icons' ;
14+ import { Check , LockDottedCircle } from '@/ui/icons' ;
1415import { Alert , Textarea } from '@/ui/primitives' ;
1516import type { ThemableCssProp } from '@/ui/styledSystem' ;
1617import { common } from '@/ui/styledSystem' ;
@@ -24,6 +25,18 @@ export function OAuthConsentInternal() {
2425 const { user } = useUser ( ) ;
2526 const { applicationName, logoImageUrl } = useEnvironment ( ) . displayConfig ;
2627 const [ isUriModalOpen , setIsUriModalOpen ] = useState ( false ) ;
28+ const [ selectedValue , setSelectedValue ] = useState < string | null > ( 'clerk-nation' ) ;
29+
30+ const selectOptions = [
31+ { value : 'clerk-nation' , label : 'Clerk Nation' , logoUrl : 'https://img.clerk.com/static/clerk.png' } ,
32+ {
33+ value : 'perky-clerky' ,
34+ label : 'Perky Clerky Clerk Nation Clerk Nation Clerk Nation' ,
35+ logoUrl : 'https://img.clerk.com/static/clerk.png' ,
36+ } ,
37+ { value : 'clerk' , label : 'Clerk' , logoUrl : 'https://img.clerk.com/static/clerk.png' } ,
38+ { value : 'clerk-of-oz' , label : 'The Clerk of Oz' , logoUrl : 'https://img.clerk.com/static/clerk.png' } ,
39+ ] ;
2740
2841 const primaryIdentifier = user ?. primaryEmailAddress ?. emailAddress || user ?. primaryPhoneNumber ?. phoneNumber ;
2942
@@ -108,6 +121,90 @@ export function OAuthConsentInternal() {
108121 < Header . Title localizationKey = { oAuthApplicationName } />
109122 < Header . Subtitle localizationKey = { `wants to access ${ applicationName } on behalf of ${ primaryIdentifier } ` } />
110123 </ Header . Root >
124+
125+ < Box >
126+ < Select
127+ options = { selectOptions }
128+ value = { selectedValue }
129+ onChange = { option => setSelectedValue ( option . value ) }
130+ renderOption = { ( option , _index , isSelected ) => (
131+ < Box
132+ as = 'span'
133+ sx = { theme => ( {
134+ width : '100%' ,
135+ display : 'grid' ,
136+ gridTemplateColumns : `${ theme . sizes . $5 } 1fr ${ theme . sizes . $3 } ` ,
137+ columnGap : theme . space . $2 ,
138+ paddingInline : theme . space . $1 ,
139+ paddingBlock : theme . space . $1 ,
140+ alignItems : 'center' ,
141+ borderRadius : theme . radii . $md ,
142+ '&:hover, &[data-focused="true"]' : {
143+ background : common . mutedBackground ( theme ) ,
144+ } ,
145+ } ) }
146+ >
147+ < Image
148+ src = { option . logoUrl }
149+ alt = { option . label }
150+ sx = { theme => ( {
151+ width : theme . sizes . $5 ,
152+ height : theme . sizes . $5 ,
153+ objectFit : 'contain' ,
154+ flexShrink : 0 ,
155+ } ) }
156+ />
157+ < Text
158+ sx = { { flex : 1 , textAlign : 'start' , minWidth : 0 , maxInlineSize : '200px' } }
159+ truncate
160+ as = 'span'
161+ >
162+ { option . label }
163+ </ Text >
164+ { isSelected && (
165+ < Icon
166+ icon = { Check }
167+ size = 'sm'
168+ sx = { theme => ( { color : theme . colors . $primary500 } ) }
169+ />
170+ ) }
171+ </ Box >
172+ ) }
173+ >
174+ < SelectButton
175+ sx = { theme => ( {
176+ inlineSize : 'min(100%, 16rem)' ,
177+ paddingInline : theme . space . $3 ,
178+ } ) }
179+ >
180+ < Image
181+ src = { selectOptions . find ( option => option . value === selectedValue ) ?. logoUrl || '' }
182+ alt = { selectOptions . find ( option => option . value === selectedValue ) ?. label || '' }
183+ sx = { theme => ( {
184+ width : theme . sizes . $5 ,
185+ height : theme . sizes . $5 ,
186+ borderRadius : theme . radii . $md ,
187+ objectFit : 'contain' ,
188+ flexShrink : 0 ,
189+ } ) }
190+ />
191+ < Text
192+ colorScheme = 'body'
193+ as = 'span'
194+ truncate
195+ sx = { {
196+ flex : 1 ,
197+ minWidth : 0 ,
198+ textAlign : 'start' ,
199+ } }
200+ >
201+ { selectOptions . find ( option => option . value === selectedValue ) ?. label || 'Select an option' }
202+ </ Text >
203+ </ SelectButton >
204+ < SelectOptionList />
205+ </ Select >
206+ </ Box >
207+
111208 < Box
112209 sx = { t => ( {
113210 textAlign : 'start' ,
0 commit comments