@@ -17,8 +17,8 @@ import type {
1717 PreferencesSubTabType ,
1818} from "@cocalc/util/types/settings" ;
1919
20- import { Flex , Menu , Space } from "antd" ;
21- import { useEffect } from "react" ;
20+ import { Button , Flex , Menu , Space } from "antd" ;
21+ import { useEffect , useState } from "react" ;
2222import { useIntl } from "react-intl" ;
2323
2424import { SignOut } from "@cocalc/frontend/account/sign-out" ;
@@ -35,6 +35,7 @@ import { cloudFilesystemsEnabled } from "@cocalc/frontend/compute";
3535import CloudFilesystems from "@cocalc/frontend/compute/cloud-filesystem/cloud-filesystems" ;
3636import { Footer } from "@cocalc/frontend/customize" ;
3737import { appBasePath } from "@cocalc/frontend/customize/app-base-path" ;
38+ import { IS_MOBILE } from "@cocalc/frontend/feature" ;
3839import { labels } from "@cocalc/frontend/i18n" ;
3940import BalanceButton from "@cocalc/frontend/purchases/balance-button" ;
4041import PayAsYouGoPage from "@cocalc/frontend/purchases/payg-page" ;
@@ -48,6 +49,8 @@ import {
4849 KUCALC_COCALC_COM ,
4950 KUCALC_ON_PREMISES ,
5051} from "@cocalc/util/db-schema/site-defaults" ;
52+ import { COLORS } from "@cocalc/util/theme" ;
53+ import { VALID_PREFERENCES_SUB_TYPES } from "@cocalc/util/types/settings" ;
5154import { AccountPreferencesAI } from "./account-preferences-ai" ;
5255import {
5356 AccountPreferencesAppearance ,
@@ -82,7 +85,6 @@ import { I18NSelector } from "./i18n-selector";
8285import { LicensesPage } from "./licenses/licenses-page" ;
8386import { PublicPaths } from "./public-paths/public-paths" ;
8487import { SettingsOverview } from "./settings-index" ;
85- import { VALID_PREFERENCES_SUB_TYPES } from "@cocalc/util/types/settings" ;
8688import { UpgradesPage } from "./upgrades/upgrades-page" ;
8789
8890export const ACCOUNT_SETTINGS_ICON_NAME : IconName = "settings" ;
@@ -116,6 +118,8 @@ const LOAD_ACCOUNT_INFO_TIMEOUT = 15_000;
116118
117119export const AccountPage : React . FC = ( ) => {
118120 const intl = useIntl ( ) ;
121+ const [ hidden , setHidden ] = useState ( IS_MOBILE ) ;
122+ const [ openKeys , setOpenKeys ] = useState < string [ ] > ( [ "preferences" ] ) ;
119123
120124 const { width : windowWidth } = useWindowDimensions ( ) ;
121125 const isWide = windowWidth > 800 ;
@@ -445,31 +449,61 @@ export const AccountPage: React.FC = () => {
445449
446450 // Process tabs to handle nested children for sub-tabs
447451 const children = { } ;
448- const titles = { } ;
452+ const titles = { } ; // Always store full labels for renderTitle()
449453 for ( const tab of tabs ) {
450454 if ( tab . type == "divider" ) {
451455 continue ;
452456 }
453457 if ( tab . key === "preferences" && Array . isArray ( tab . children ) ) {
454458 // Handle sub-tabs for preferences
455459 const subTabs = tab . children ;
456- tab . children = subTabs . map ( ( subTab ) => ( {
457- key : subTab . key ,
458- label : subTab . label ,
459- } ) ) ;
460- // Store sub-tab children
460+ tab . children = subTabs . map ( ( subTab ) => {
461+ // Extract just the icon (first child) from the span when hidden
462+ const label = hidden ? (
463+ < span style = { { paddingLeft : "5px" } } >
464+ { subTab . label . props . children [ 0 ] }
465+ </ span >
466+ ) : (
467+ subTab . label
468+ ) ;
469+ return {
470+ key : subTab . key ,
471+ label,
472+ } ;
473+ } ) ;
474+ // Store sub-tab children and full labels
461475 for ( const subTab of subTabs ) {
462476 children [ subTab . key ] = subTab . children ;
463- titles [ subTab . key ] = subTab . label ;
477+ titles [ subTab . key ] = subTab . label ; // Always store original full label
464478 }
465479 } else if ( tab . key === "settings" || tab . key === "profile" ) {
466480 // Handle settings and profile as top-level pages
481+ // Store original full label for renderTitle()
482+ const originalLabel = tab . label ;
483+ // Extract just the icon (first child) from the span when hidden
484+ tab . label = hidden ? (
485+ < span style = { { paddingLeft : "5px" } } >
486+ { tab . label . props . children [ 0 ] }
487+ </ span >
488+ ) : (
489+ tab . label
490+ ) ;
467491 children [ tab . key ] = tab . children ;
468- titles [ tab . key ] = tab . label ;
492+ titles [ tab . key ] = originalLabel ; // Store original label
469493 delete tab . children ;
470494 } else {
495+ // Store original full label for renderTitle()
496+ const originalLabel = tab . label ;
497+ // Extract just the icon (first child) from the span when hidden
498+ tab . label = hidden ? (
499+ < span style = { { paddingLeft : "5px" } } >
500+ { tab . label . props . children [ 0 ] }
501+ </ span >
502+ ) : (
503+ tab . label
504+ ) ;
471505 children [ tab . key ] = tab . children ;
472- titles [ tab . key ] = tab . label ;
506+ titles [ tab . key ] = originalLabel ; // Store original label
473507 delete tab . children ;
474508 }
475509 }
@@ -516,6 +550,10 @@ export const AccountPage: React.FC = () => {
516550 ) ;
517551 }
518552
553+ function handleHideToggle ( ) {
554+ setHidden ( ! hidden ) ;
555+ }
556+
519557 return (
520558 < div className = "smc-vfill" style = { { flexDirection : "row" } } >
521559 < div
@@ -528,6 +566,8 @@ export const AccountPage: React.FC = () => {
528566 >
529567 < Menu
530568 defaultOpenKeys = { [ "preferences" ] }
569+ openKeys = { hidden ? [ "preferences" ] : openKeys }
570+ onOpenChange = { hidden ? undefined : setOpenKeys }
531571 mode = "inline"
532572 items = { tabs }
533573 onClick = { ( e ) => {
@@ -536,14 +576,38 @@ export const AccountPage: React.FC = () => {
536576 selectedKeys = {
537577 active_sub_tab ? [ active_page , active_sub_tab ] : [ active_page ]
538578 }
579+ inlineIndent = { hidden ? 0 : 24 }
539580 style = { {
540- width : 200 ,
581+ width : hidden ? 50 : 200 ,
541582 background : "#00000005" ,
542583 flex : "1 1 auto" ,
543584 overflowY : "auto" ,
544585 minHeight : 0 ,
586+ borderBottom : `1px solid ${ COLORS . GRAY_DDD } ` ,
545587 } }
546588 />
589+ < Button
590+ block
591+ size = "small"
592+ type = "text"
593+ style = { {
594+ flex : "0 0 auto" ,
595+ minHeight : 0 ,
596+ textAlign : "left" ,
597+ padding : "15px 0" ,
598+ color : COLORS . GRAY_M ,
599+ } }
600+ onClick = { handleHideToggle }
601+ icon = {
602+ < Icon
603+ name = {
604+ hidden ? "vertical-left-outlined" : "vertical-right-outlined"
605+ }
606+ />
607+ }
608+ >
609+ { hidden ? "" : "Hide" }
610+ </ Button >
547611 </ div >
548612 < div
549613 className = "smc-vfill"
@@ -553,7 +617,7 @@ export const AccountPage: React.FC = () => {
553617 paddingRight : "15px" ,
554618 } }
555619 >
556- < Flex style = { { marginTop : "5px" } } >
620+ < Flex style = { { marginTop : "5px" } } wrap >
557621 { renderTitle ( ) }
558622 < div style = { { flex : 1 } } />
559623 { renderExtraContent ( ) }
0 commit comments