11import { useEffect , useState } from 'react' ;
2- import { CircleCheck , Loader2 , CircleX } from 'lucide-react' ;
2+ import { CircleCheck , Loader2 , CircleX , EyeIcon , EyeOffIcon } from 'lucide-react' ;
3+ import { Link } from 'react-router-dom' ;
34import { aiHealthcheck , subscribeToMailingList } from '@/lib/server' ;
45import { useSettings } from '@/components/use-settings' ;
56import { AiProviderType , getDefaultModel , type CodeLanguageType } from '@srcbook/shared' ;
@@ -21,6 +22,7 @@ function Settings() {
2122 aiProvider,
2223 aiModel,
2324 aiBaseUrl,
25+ codeiumApiKey,
2426 openaiKey : configOpenaiKey ,
2527 anthropicKey : configAnthropicKey ,
2628 updateConfig : updateConfigContext ,
@@ -35,6 +37,7 @@ function Settings() {
3537 const [ model , setModel ] = useState < string > ( aiModel ) ;
3638 const [ baseUrl , setBaseUrl ] = useState < string > ( aiBaseUrl || '' ) ;
3739 const [ email , setEmail ] = useState < string > ( isSubscribed ? subscriptionEmail : '' ) ;
40+ const [ codeiumApiKeyVisible , setCodeiumApiKeyVisible ] = useState ( false ) ;
3841
3942 const updateDefaultLanguage = ( value : CodeLanguageType ) => {
4043 updateConfigContext ( { defaultLanguage : value } ) ;
@@ -81,6 +84,8 @@ function Settings() {
8184 }
8285 } ;
8386
87+ const codeiumCallbackUrl = `${ window . location . href } /codeium-callback` ;
88+
8489 return (
8590 < div >
8691 < h4 className = "h4 mx-auto mb-6" > Settings</ h4 >
@@ -206,6 +211,49 @@ function Settings() {
206211 ) }
207212 </ div >
208213 </ div >
214+ < div >
215+ < h2 className = "text-xl pb-2" > AI Autocomplete</ h2 >
216+ < div className = "flex flex-col" >
217+ { codeiumApiKey ? (
218+ < div >
219+ < div className = "opacity-70 text-sm pb-2" > Codeium API Key:</ div >
220+ < div className = "flex justify-between items-center gap-2" >
221+ < Input
222+ name = "codeiumApiKey"
223+ type = { codeiumApiKeyVisible ? "text" : "password" }
224+ value = { codeiumApiKey }
225+ readOnly
226+ />
227+ < Button size = "icon" variant = "secondary" onClick = { ( ) => setCodeiumApiKeyVisible ( n => ! n ) } >
228+ { codeiumApiKeyVisible ? (
229+ < EyeIcon size = { 16 } />
230+ ) : (
231+ < EyeOffIcon size = { 16 } />
232+ ) }
233+ </ Button >
234+ < Button variant = "secondary" onClick = { ( ) => {
235+ updateConfigContext ( { codeiumApiKey : null } ) . then ( ( ) => {
236+ toast . success ( 'Removed Codeium api key.' ) ;
237+ } ) . catch ( err => {
238+ console . error ( 'Error removing Codeium api key:' , err ) ;
239+ toast . error ( 'Error removing Codeium key!' ) ;
240+ } ) ;
241+ } } >
242+ Remove
243+ </ Button >
244+ </ div >
245+ </ div >
246+ ) : (
247+ < div >
248+ < Button asChild >
249+ < Link to = { `https://www.codeium.com/profile?response_type=token&redirect_uri=${ codeiumCallbackUrl } &state=a&scope=openid%20profile%20email&redirect_parameters_type=query` } >
250+ Start Codeium OAuth
251+ </ Link >
252+ </ Button >
253+ </ div >
254+ ) }
255+ </ div >
256+ </ div >
209257
210258 < div >
211259 < h2 className = "text-xl pb-2" > Get product updates</ h2 >
0 commit comments