@@ -89,8 +89,20 @@ import { UpgradesPage } from "./upgrades/upgrades-page";
8989
9090export const ACCOUNT_SETTINGS_ICON_NAME : IconName = "settings" ;
9191
92+ const BILLING_MENU_KEYS = new Set ( [
93+ "subscriptions" ,
94+ "licenses" ,
95+ "payg" ,
96+ "upgrades" ,
97+ "purchases" ,
98+ "payments" ,
99+ "payment-methods" ,
100+ "statements" ,
101+ ] ) ;
102+
92103function getParentMenuKey ( key ?: string ) : string | undefined {
93104 if ( ! key ) return ;
105+ if ( BILLING_MENU_KEYS . has ( key ) ) return "billing" ;
94106 const dashIndex = key . indexOf ( "-" ) ;
95107 if ( dashIndex === - 1 ) return ;
96108 return key . slice ( 0 , dashIndex ) ;
@@ -323,85 +335,102 @@ export const AccountPage: React.FC = () => {
323335 items . push ( { type : "divider" } ) ;
324336
325337 if ( is_commercial ) {
326- items . push ( {
327- key : "subscriptions" ,
328- label : (
329- < span >
330- < Icon name = "calendar" /> { intl . formatMessage ( labels . subscriptions ) }
331- </ span >
332- ) ,
333- children : active_page === "subscriptions" && < SubscriptionsPage /> ,
334- } ) ;
335- items . push ( {
336- key : "licenses" ,
337- label : (
338- < span >
339- < Icon name = "key" /> { intl . formatMessage ( labels . licenses ) }
340- </ span >
341- ) ,
342- children : active_page === "licenses" && < LicensesPage /> ,
343- } ) ;
344- items . push ( {
345- key : "payg" ,
346- label : (
347- < span >
348- < Icon name = "line-chart" /> { " " }
349- { intl . formatMessage ( labels . pay_as_you_go ) }
350- </ span >
351- ) ,
352- children : active_page === "payg" && < PayAsYouGoPage /> ,
353- } ) ;
354- if ( is_commercial && kucalc === KUCALC_COCALC_COM ) {
355- // these have been deprecated for ~ 5 years, but some customers still have them.
356- items . push ( {
357- key : "upgrades" ,
338+ const billingChildren = [
339+ {
340+ key : "subscriptions" ,
358341 label : (
359342 < span >
360- < Icon name = "arrow-circle-up " /> { " " }
361- { intl . formatMessage ( labels . upgrades ) }
343+ < Icon name = "calendar " /> { " " }
344+ { intl . formatMessage ( labels . subscriptions ) }
362345 </ span >
363346 ) ,
364- children : active_page === "upgrades" && < UpgradesPage /> ,
365- } ) ;
366- }
367- items . push ( { type : "divider" } ) ;
368- items . push ( {
369- key : "purchases" ,
370- label : (
371- < span >
372- < Icon name = "money-check" /> { intl . formatMessage ( labels . purchases ) }
373- </ span >
374- ) ,
375- children : active_page === "purchases" && < PurchasesPage /> ,
376- } ) ;
377- items . push ( {
378- key : "payments" ,
379- label : (
380- < span >
381- < Icon name = "credit-card" /> { intl . formatMessage ( labels . payments ) }
382- </ span >
383- ) ,
384- children : active_page === "payments" && < PaymentsPage /> ,
385- } ) ;
386- items . push ( {
387- key : "payment-methods" ,
388- label : (
389- < span >
390- < Icon name = "credit-card" /> { " " }
391- { intl . formatMessage ( labels . payment_methods ) }
392- </ span >
393- ) ,
394- children : active_page === "payment-methods" && < PaymentMethodsPage /> ,
395- } ) ;
347+ children : active_page === "subscriptions" && < SubscriptionsPage /> ,
348+ } ,
349+ {
350+ key : "licenses" ,
351+ label : (
352+ < span >
353+ < Icon name = "key" /> { intl . formatMessage ( labels . licenses ) }
354+ </ span >
355+ ) ,
356+ children : active_page === "licenses" && < LicensesPage /> ,
357+ } ,
358+ {
359+ key : "payg" ,
360+ label : (
361+ < span >
362+ < Icon name = "line-chart" /> { " " }
363+ { intl . formatMessage ( labels . pay_as_you_go ) }
364+ </ span >
365+ ) ,
366+ children : active_page === "payg" && < PayAsYouGoPage /> ,
367+ } ,
368+ ...( is_commercial && kucalc === KUCALC_COCALC_COM
369+ ? [
370+ {
371+ key : "upgrades" ,
372+ label : (
373+ < span >
374+ < Icon name = "arrow-circle-up" /> { " " }
375+ { intl . formatMessage ( labels . upgrades ) }
376+ </ span >
377+ ) ,
378+ children : active_page === "upgrades" && < UpgradesPage /> ,
379+ } ,
380+ ]
381+ : [ ] ) ,
382+ {
383+ key : "purchases" ,
384+ label : (
385+ < span >
386+ < Icon name = "money-check" /> { " " }
387+ { intl . formatMessage ( labels . purchases ) }
388+ </ span >
389+ ) ,
390+ children : active_page === "purchases" && < PurchasesPage /> ,
391+ } ,
392+ {
393+ key : "payments" ,
394+ label : (
395+ < span >
396+ < Icon name = "credit-card" /> { " " }
397+ { intl . formatMessage ( labels . payments ) }
398+ </ span >
399+ ) ,
400+ children : active_page === "payments" && < PaymentsPage /> ,
401+ } ,
402+ {
403+ key : "payment-methods" ,
404+ label : (
405+ < span >
406+ < Icon name = "credit-card" /> { " " }
407+ { intl . formatMessage ( labels . payment_methods ) }
408+ </ span >
409+ ) ,
410+ children : active_page === "payment-methods" && (
411+ < PaymentMethodsPage />
412+ ) ,
413+ } ,
414+ {
415+ key : "statements" ,
416+ label : (
417+ < span >
418+ < Icon name = "calendar-week" /> { " " }
419+ { intl . formatMessage ( labels . statements ) }
420+ </ span >
421+ ) ,
422+ children : active_page === "statements" && < StatementsPage /> ,
423+ } ,
424+ ] ;
425+
396426 items . push ( {
397- key : "statements " ,
427+ key : "billing " ,
398428 label : (
399429 < span >
400- < Icon name = "calendar-week" /> { " " }
401- { intl . formatMessage ( labels . statements ) }
430+ < Icon name = "money-check" /> { intl . formatMessage ( labels . billing ) }
402431 </ span >
403432 ) ,
404- children : active_page === "statements" && < StatementsPage /> ,
433+ children : billingChildren ,
405434 } ) ;
406435 items . push ( { type : "divider" } ) ;
407436 }
@@ -455,22 +484,21 @@ export const AccountPage: React.FC = () => {
455484 const tabs = getTabs ( ) ;
456485
457486 useEffect ( ( ) => {
458- if ( ! active_sub_tab ) return ;
459- const parentKey = getParentMenuKey ( active_sub_tab ) ;
460- if ( ! parentKey ) return ;
487+ const parentKey = getParentMenuKey (
488+ active_sub_tab ? active_sub_tab : active_page ,
489+ ) ;
461490 setOpenKeys ( ( prevOpenKeys ) =>
462- prevOpenKeys . length === 1 && prevOpenKeys [ 0 ] === parentKey
463- ? prevOpenKeys
464- : [ parentKey ] ,
491+ parentKey == null
492+ ? [ ]
493+ : prevOpenKeys . length === 1 && prevOpenKeys [ 0 ] === parentKey
494+ ? prevOpenKeys
495+ : [ parentKey ] ,
465496 ) ;
466- } , [ active_sub_tab ] ) ;
497+ } , [ active_page , active_sub_tab ] ) ;
467498
468499 useEffect ( ( ) => {
469- if ( active_page !== "preferences" ) {
470- if ( active_sub_tab ) {
471- redux . getActions ( "account" ) . setState ( { active_sub_tab : undefined } ) ;
472- }
473- setOpenKeys ( [ ] ) ;
500+ if ( active_page !== "preferences" && active_sub_tab ) {
501+ redux . getActions ( "account" ) . setState ( { active_sub_tab : undefined } ) ;
474502 }
475503 } , [ active_page , active_sub_tab ] ) ;
476504
@@ -510,6 +538,25 @@ export const AccountPage: React.FC = () => {
510538 children [ subTab . key ] = subTab . children ;
511539 titles [ subTab . key ] = subTab . label ; // Always store original full label
512540 }
541+ } else if ( tab . key === "billing" && Array . isArray ( tab . children ) ) {
542+ const subTabs = tab . children ;
543+ tab . children = subTabs . map ( ( subTab ) => {
544+ const label = hidden ? (
545+ < span style = { { paddingLeft : "5px" } } >
546+ { subTab . label . props . children [ 0 ] }
547+ </ span >
548+ ) : (
549+ subTab . label
550+ ) ;
551+ return {
552+ key : subTab . key ,
553+ label,
554+ } ;
555+ } ) ;
556+ for ( const subTab of subTabs ) {
557+ children [ subTab . key ] = subTab . children ;
558+ titles [ subTab . key ] = subTab . label ;
559+ }
513560 } else if ( tab . key === "settings" || tab . key === "profile" ) {
514561 // Handle settings and profile as top-level pages
515562 // Store original full label for renderTitle()
0 commit comments