11"use client" ;
22
33import type { Project } from "@/api/projects" ;
4+ import type { SMSCountryTiers } from "@/api/sms" ;
45import { DynamicHeight } from "@/components/ui/DynamicHeight" ;
56import { Spinner } from "@/components/ui/Spinner/Spinner" ;
67import { UnderlineLink } from "@/components/ui/UnderlineLink" ;
@@ -36,13 +37,15 @@ import { type UseFormReturn, useFieldArray, useForm } from "react-hook-form";
3637import { toast } from "sonner" ;
3738import { toArrFromList } from "utils/string" ;
3839import type { Team } from "../../../@/api/team" ;
40+ import CountrySelector from "./sms-country-select/country-selector" ;
3941
4042type InAppWalletSettingsPageProps = {
4143 trackingCategory : string ;
4244 project : Project ;
4345 teamId : string ;
4446 teamSlug : string ;
4547 validTeamPlan : Team [ "billingPlan" ] ;
48+ smsCountryTiers : SMSCountryTiers ;
4649} ;
4750
4851const TRACKING_CATEGORY = "embedded-wallet" ;
@@ -108,6 +111,7 @@ export function InAppWalletSettingsPage(props: InAppWalletSettingsPageProps) {
108111 canEditAdvancedFeatures = { props . validTeamPlan !== "free" }
109112 updateApiKey = { handleUpdateProject }
110113 isUpdating = { updateProject . isPending }
114+ smsCountryTiers = { props . smsCountryTiers }
111115 />
112116 ) ;
113117}
@@ -120,6 +124,7 @@ const InAppWalletSettingsPageUI: React.FC<
120124 trackingData : UpdateAPIKeyTrackingData ,
121125 ) => void ;
122126 isUpdating : boolean ;
127+ smsCountryTiers : SMSCountryTiers ;
123128 }
124129> = ( props ) => {
125130 const embeddedWalletService = props . project . services . find (
@@ -185,6 +190,11 @@ export const InAppWalletSettingsUI: React.FC<
185190 }
186191 : undefined ) ,
187192 redirectUrls : ( config . redirectUrls || [ ] ) . join ( "\n" ) ,
193+ smsEnabledCountryISOs : config . smsEnabledCountryISOs
194+ ? config . smsEnabledCountryISOs
195+ : canEditAdvancedFeatures
196+ ? [ "US" , "CA" ]
197+ : [ ] ,
188198 } ,
189199 } ) ;
190200
@@ -228,6 +238,7 @@ export const InAppWalletSettingsUI: React.FC<
228238 applicationImageUrl : branding ?. applicationImageUrl ,
229239 applicationName : branding ?. applicationName || props . project . name ,
230240 redirectUrls : toArrFromList ( redirectUrls || "" , true ) ,
241+ smsEnabledCountryISOs : values . smsEnabledCountryISOs ,
231242 } ;
232243 } ) ;
233244
@@ -256,6 +267,8 @@ export const InAppWalletSettingsUI: React.FC<
256267 canEditAdvancedFeatures = { canEditAdvancedFeatures }
257268 />
258269
270+ < NativeAppsFieldset form = { form } />
271+
259272 { /* Authentication */ }
260273 < Fieldset legend = "Authentication" >
261274 < JSONWebTokenFields
@@ -269,9 +282,15 @@ export const InAppWalletSettingsUI: React.FC<
269282 form = { form }
270283 canEditAdvancedFeatures = { canEditAdvancedFeatures }
271284 />
272- </ Fieldset >
273285
274- < NativeAppsFieldset form = { form } />
286+ < div className = "h-5" />
287+
288+ < SMSCountryFields
289+ form = { form }
290+ canEditAdvancedFeatures = { canEditAdvancedFeatures }
291+ smsCountryTiers = { props . smsCountryTiers }
292+ />
293+ </ Fieldset >
275294
276295 < div className = "flex justify-end" >
277296 < Button type = "submit" variant = "primary" className = "gap-2" >
@@ -364,6 +383,61 @@ function BrandingFieldset(props: {
364383 ) ;
365384}
366385
386+ function SMSCountryFields ( props : {
387+ form : UseFormReturn < ApiKeyEmbeddedWalletsValidationSchema > ;
388+ canEditAdvancedFeatures : boolean ;
389+ smsCountryTiers : SMSCountryTiers ;
390+ } ) {
391+ return (
392+ < div >
393+ < SwitchContainer
394+ switchId = "sms-switch"
395+ title = "SMS"
396+ description = "Optionally allow users in selected countries to login via SMS OTP."
397+ >
398+ < GatedSwitch
399+ id = "sms-switch"
400+ trackingLabel = "sms"
401+ checked = {
402+ ! ! props . form . watch ( "smsEnabledCountryISOs" ) . length &&
403+ props . canEditAdvancedFeatures
404+ }
405+ upgradeRequired = { ! props . canEditAdvancedFeatures }
406+ onCheckedChange = { ( checked ) =>
407+ props . form . setValue (
408+ "smsEnabledCountryISOs" ,
409+ checked
410+ ? // by default, enable US and CA only
411+ [ "US" , "CA" ]
412+ : [ ] ,
413+ )
414+ }
415+ />
416+ </ SwitchContainer >
417+
418+ < AdvancedConfigurationContainer
419+ className = "grid grid-cols-1"
420+ show = {
421+ props . canEditAdvancedFeatures &&
422+ ! ! props . form . watch ( "smsEnabledCountryISOs" ) . length
423+ }
424+ >
425+ < FormField
426+ control = { props . form . control }
427+ name = "smsEnabledCountryISOs"
428+ render = { ( { field } ) => (
429+ < CountrySelector
430+ countryTiers = { props . smsCountryTiers }
431+ selected = { field . value }
432+ onChange = { field . onChange }
433+ />
434+ ) }
435+ />
436+ </ AdvancedConfigurationContainer >
437+ </ div >
438+ ) ;
439+ }
440+
367441function JSONWebTokenFields ( props : {
368442 form : UseFormReturn < ApiKeyEmbeddedWalletsValidationSchema > ;
369443 canEditAdvancedFeatures : boolean ;
0 commit comments