@@ -240,32 +240,39 @@ export const InAppWalletSettingsUI: React.FC<
240240
241241 return (
242242 < Form { ...form } >
243- < form
244- autoComplete = "off"
245- className = "flex flex-col gap-6"
246- onSubmit = { handleSubmit }
247- >
243+ < form autoComplete = "off" className = "space-y-6" onSubmit = { handleSubmit } >
248244 { /* Branding */ }
249245 < BrandingFieldset
250246 client = { props . client }
251247 form = { form }
252248 requiredPlan = { brandingRequiredPlan }
253249 teamPlan = { props . teamPlan }
254250 teamSlug = { props . teamSlug }
251+ isUpdating = { props . isUpdating }
255252 />
256253
257- < NativeAppsFieldset form = { form } />
254+ < NativeAppsFieldset form = { form } isUpdating = { props . isUpdating } />
258255
259256 { /* Authentication */ }
260- < Fieldset legend = "Authentication" >
257+ < Fieldset
258+ legend = "Authentication"
259+ footer = {
260+ < div className = "flex justify-end p-4 md:px-6 border-t border-dashed" >
261+ < Button className = "gap-2" type = "submit" size = "sm" >
262+ { props . isUpdating && < Spinner className = "size-4" /> }
263+ Save
264+ </ Button >
265+ </ div >
266+ }
267+ >
261268 < JSONWebTokenFields
262269 form = { form }
263270 requiredPlan = { authRequiredPlan }
264271 teamPlan = { props . teamPlan }
265272 teamSlug = { props . teamSlug }
266273 />
267274
268- < div className = "h-5 " />
275+ < div className = "my-5 border-t border-dashed " />
269276
270277 < AuthEndpointFields
271278 form = { form }
@@ -274,7 +281,7 @@ export const InAppWalletSettingsUI: React.FC<
274281 teamSlug = { props . teamSlug }
275282 />
276283
277- < div className = "h-5 " />
284+ < div className = "my-5 border-t border-dashed " />
278285
279286 < SMSCountryFields
280287 form = { form }
@@ -284,13 +291,6 @@ export const InAppWalletSettingsUI: React.FC<
284291 teamSlug = { props . teamSlug }
285292 />
286293 </ Fieldset >
287-
288- < div className = "flex justify-end" >
289- < Button className = "gap-2" type = "submit" variant = "primary" >
290- { props . isUpdating && < Spinner className = "size-4" /> }
291- Save changes
292- </ Button >
293- </ div >
294294 </ form >
295295 </ Form >
296296 ) ;
@@ -302,14 +302,22 @@ function BrandingFieldset(props: {
302302 teamSlug : string ;
303303 requiredPlan : Team [ "billingPlan" ] ;
304304 client : ThirdwebClient ;
305+ isUpdating : boolean ;
305306} ) {
306307 return (
307- < Fieldset legend = "Branding" >
308- < SwitchContainer
309- description = "Pass a custom logo and app name to be used in the emails sent to users."
310- switchId = "branding-switch"
311- title = "Custom email logo and name"
312- >
308+ < FieldsetWithDescription
309+ legend = "Branding"
310+ description = "Set a app name and logo to be used in the emails sent to users."
311+ footer = {
312+ < div className = "flex justify-end p-4 md:px-6 border-t border-dashed" >
313+ < Button className = "gap-2" type = "submit" size = "sm" >
314+ { props . isUpdating && < Spinner className = "size-4" /> }
315+ Save
316+ </ Button >
317+ </ div >
318+ }
319+ >
320+ < div className = "absolute top-8 right-6" >
313321 < GatedSwitch
314322 currentPlan = { props . teamPlan }
315323 requiredPlan = { props . requiredPlan }
@@ -330,26 +338,39 @@ function BrandingFieldset(props: {
330338 teamSlug = { props . teamSlug }
331339 trackingLabel = "customEmailLogoAndName"
332340 />
333- </ SwitchContainer >
341+ </ div >
334342
335343 < GatedCollapsibleContainer
336- className = "grid grid-cols-1 gap-6 lg:grid-cols-2 "
344+ className = "grid grid-cols-1 gap-16 lg:grid-cols-[1fr_1.5fr] "
337345 currentPlan = { props . teamPlan }
338346 isExpanded = { ! ! props . form . watch ( "branding" ) }
339347 requiredPlan = { props . requiredPlan }
340348 >
341- { /* Application Image */ }
349+ { /* Application Name */ }
350+ < FormField
351+ control = { props . form . control }
352+ name = "branding.applicationName"
353+ render = { ( { field } ) => (
354+ < FormItem >
355+ < FormLabel > Application Name</ FormLabel >
356+ < FormDescription >
357+ Name that will be displayed in the emails sent to users.{ " " }
358+ < br className = "max-sm:hidden" /> Defaults to your API Key's
359+ name.
360+ </ FormDescription >
361+ < FormControl >
362+ < Input { ...field } />
363+ </ FormControl >
364+ < FormMessage />
365+ </ FormItem >
366+ ) }
367+ />
368+
342369 < FormField
343370 control = { props . form . control }
344371 name = "branding.applicationImageUrl"
345372 render = { ( ) => (
346- < FormItem className = "space-y-1" >
347- < FormLabel > Application Image URL</ FormLabel >
348- < FormDescription className = "!mb-4" >
349- Logo that will display in the emails sent to users.{ " " }
350- < br className = "max-sm:hidden" /> The image must be squared with
351- recommended size of 72x72 px.
352- </ FormDescription >
373+ < FormItem className = "flex flex-col lg:flex-row lg:items-center gap-4" >
353374 < FormControl >
354375 < AppImageFormControl
355376 client = { props . client }
@@ -362,32 +383,22 @@ function BrandingFieldset(props: {
362383 uri = { props . form . watch ( "branding.applicationImageUrl" ) }
363384 />
364385 </ FormControl >
365- < FormMessage />
366- </ FormItem >
367- ) }
368- />
369386
370- { /* Application Name */ }
371- < FormField
372- control = { props . form . control }
373- name = "branding.applicationName"
374- render = { ( { field } ) => (
375- < FormItem >
376- < FormLabel > Application Name</ FormLabel >
377- < FormDescription className = "!mb-2" >
378- Name that will be displayed in the emails sent to users.{ " " }
379- < br className = "max-sm:hidden" /> Defaults to your API Key's
380- name.
381- </ FormDescription >
382- < FormControl >
383- < Input { ...field } />
384- </ FormControl >
385- < FormMessage />
387+ < div className = "space-y-1" >
388+ < FormLabel > Application Image URL</ FormLabel >
389+ < FormDescription className = "!mb-4" >
390+ Logo that will display in the emails sent to users.{ " " }
391+ < br className = "max-sm:hidden" /> The image must be squared
392+ with recommended size of 72x72 px.
393+ </ FormDescription >
394+
395+ < FormMessage />
396+ </ div >
386397 </ FormItem >
387398 ) }
388399 />
389400 </ GatedCollapsibleContainer >
390- </ Fieldset >
401+ </ FieldsetWithDescription >
391402 ) ;
392403}
393404
@@ -743,10 +754,21 @@ function AuthEndpointFieldsContent(props: {
743754
744755function NativeAppsFieldset ( props : {
745756 form : UseFormReturn < ApiKeyEmbeddedWalletsValidationSchema > ;
757+ isUpdating : boolean ;
746758} ) {
747759 const { form } = props ;
748760 return (
749- < Fieldset legend = "Native Apps" >
761+ < Fieldset
762+ legend = "Native Apps"
763+ footer = {
764+ < div className = "flex justify-end p-4 md:px-6 border-t border-dashed" >
765+ < Button className = "gap-2" type = "submit" size = "sm" >
766+ { props . isUpdating && < Spinner className = "size-4" /> }
767+ Save
768+ </ Button >
769+ </ div >
770+ }
771+ >
750772 < FormField
751773 control = { form . control }
752774 name = "redirectUrls"
@@ -789,21 +811,54 @@ function GatedCollapsibleContainer(props: {
789811 return null ;
790812 }
791813
792- return < div className = { cn ( "mt-6 " , props . className ) } > { props . children } </ div > ;
814+ return < div className = { cn ( "mt-5 " , props . className ) } > { props . children } </ div > ;
793815}
794816
795- function Fieldset ( props : { legend : string ; children : React . ReactNode } ) {
817+ function Fieldset ( props : {
818+ legend : string ;
819+ children : React . ReactNode ;
820+ footer ?: React . ReactNode ;
821+ } ) {
796822 return (
797- < DynamicHeight >
798- < fieldset className = "rounded-lg border border-border bg-card p-4 md:p-6" >
799- { /* put inside div to remove default styles on legend */ }
800- < div className = "mb-4 font-semibold text-xl tracking-tight" >
801- < legend > { props . legend } </ legend >
802- </ div >
823+ < div className = "rounded-lg border bg-card relative" >
824+ < DynamicHeight >
825+ < fieldset >
826+ { /* put inside div to remove default styles on legend */ }
827+ < div className = "p-4 md:py-5 md:px-6 border-b border-dashed font-semibold text-xl tracking-tight" >
828+ < legend > { props . legend } </ legend >
829+ </ div >
803830
804- { props . children }
805- </ fieldset >
806- </ DynamicHeight >
831+ < div className = "p-4 md:p-6" > { props . children } </ div >
832+ </ fieldset >
833+ </ DynamicHeight >
834+ { props . footer }
835+ </ div >
836+ ) ;
837+ }
838+
839+ function FieldsetWithDescription ( props : {
840+ legend : string ;
841+ children : React . ReactNode ;
842+ footer ?: React . ReactNode ;
843+ description : React . ReactNode ;
844+ } ) {
845+ return (
846+ < div className = "rounded-lg border bg-card relative" >
847+ < DynamicHeight >
848+ < fieldset className = "p-4 md:p-6" >
849+ { /* put inside div to remove default styles on legend */ }
850+ < div className = "pr-20" >
851+ < legend className = "font-semibold text-xl tracking-tight" >
852+ { props . legend }
853+ </ legend >
854+ < p className = "text-muted-foreground text-sm" > { props . description } </ p >
855+ </ div >
856+
857+ { props . children }
858+ </ fieldset >
859+ </ DynamicHeight >
860+ { props . footer }
861+ </ div >
807862 ) ;
808863}
809864
0 commit comments