@@ -22,6 +22,7 @@ import type { TabType, TabVisibilityConfig, Profile } from './types';
2222import { TAB_LABELS , DEFAULT_TAB_CONFIG } from './constants' ;
2323import { DialogTitle } from '~/components/ui/Dialog' ;
2424import { AvatarDropdown } from './AvatarDropdown' ;
25+ import BackgroundRays from '~/components/ui/BackgroundRays' ;
2526
2627// Import all tab components
2728import ProfileTab from '~/components/@settings/tabs/profile/ProfileTab' ;
@@ -83,7 +84,7 @@ const TAB_DESCRIPTIONS: Record<TabType, string> = {
8384} ;
8485
8586// Beta status for experimental features
86- const BETA_TABS = new Set < TabType > ( [ 'task-manager' , 'service-status' ] ) ;
87+ const BETA_TABS = new Set < TabType > ( [ 'task-manager' , 'service-status' , 'update' , 'local-providers' ] ) ;
8788
8889const BetaLabel = ( ) => (
8990 < div className = "absolute top-2 right-2 px-1.5 py-0.5 rounded-full bg-purple-500/10 dark:bg-purple-500/20" >
@@ -415,108 +416,114 @@ export const ControlPanel = ({ open, onClose }: ControlPanelProps) => {
415416 'rounded-2xl shadow-2xl' ,
416417 'border border-[#E5E5E5] dark:border-[#1A1A1A]' ,
417418 'flex flex-col overflow-hidden' ,
419+ 'relative' ,
418420 ) }
419421 initial = { { opacity : 0 , scale : 0.95 , y : 20 } }
420422 animate = { { opacity : 1 , scale : 1 , y : 0 } }
421423 exit = { { opacity : 0 , scale : 0.95 , y : 20 } }
422424 transition = { { duration : 0.2 } }
423425 >
424- { /* Header */ }
425- < div className = "flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700" >
426- < div className = "flex items-center space-x-4" >
427- { ( activeTab || showTabManagement ) && (
426+ < div className = "absolute inset-0 overflow-hidden rounded-2xl" >
427+ < BackgroundRays />
428+ </ div >
429+ < div className = "relative z-10 flex flex-col h-full" >
430+ { /* Header */ }
431+ < div className = "flex items-center justify-between px-6 py-4 border-b border-gray-200 dark:border-gray-700" >
432+ < div className = "flex items-center space-x-4" >
433+ { ( activeTab || showTabManagement ) && (
434+ < button
435+ onClick = { handleBack }
436+ className = "flex items-center justify-center w-8 h-8 rounded-full bg-transparent hover:bg-purple-500/10 dark:hover:bg-purple-500/20 group transition-all duration-200"
437+ >
438+ < div className = "i-ph:arrow-left w-4 h-4 text-gray-500 dark:text-gray-400 group-hover:text-purple-500 transition-colors" />
439+ </ button >
440+ ) }
441+ < DialogTitle className = "text-xl font-semibold text-gray-900 dark:text-white" >
442+ { showTabManagement ? 'Tab Management' : activeTab ? TAB_LABELS [ activeTab ] : 'Control Panel' }
443+ </ DialogTitle >
444+ </ div >
445+
446+ < div className = "flex items-center gap-6" >
447+ { /* Mode Toggle */ }
448+ < div className = "flex items-center gap-2 min-w-[140px] border-r border-gray-200 dark:border-gray-800 pr-6" >
449+ < AnimatedSwitch
450+ id = "developer-mode"
451+ checked = { developerMode }
452+ onCheckedChange = { handleDeveloperModeChange }
453+ label = { developerMode ? 'Developer Mode' : 'User Mode' }
454+ />
455+ </ div >
456+
457+ { /* Avatar and Dropdown */ }
458+ < div className = "border-l border-gray-200 dark:border-gray-800 pl-6" >
459+ < AvatarDropdown onSelectTab = { handleTabClick } />
460+ </ div >
461+
462+ { /* Close Button */ }
428463 < button
429- onClick = { handleBack }
464+ onClick = { onClose }
430465 className = "flex items-center justify-center w-8 h-8 rounded-full bg-transparent hover:bg-purple-500/10 dark:hover:bg-purple-500/20 group transition-all duration-200"
431466 >
432- < div className = "i-ph:arrow-left w-4 h-4 text-gray-500 dark:text-gray-400 group-hover:text-purple-500 transition-colors" />
467+ < div className = "i-ph:x w-4 h-4 text-gray-500 dark:text-gray-400 group-hover:text-purple-500 transition-colors" />
433468 </ button >
434- ) }
435- < DialogTitle className = "text-xl font-semibold text-gray-900 dark:text-white" >
436- { showTabManagement ? 'Tab Management' : activeTab ? TAB_LABELS [ activeTab ] : 'Control Panel' }
437- </ DialogTitle >
438- </ div >
439-
440- < div className = "flex items-center gap-6" >
441- { /* Mode Toggle */ }
442- < div className = "flex items-center gap-2 min-w-[140px] border-r border-gray-200 dark:border-gray-800 pr-6" >
443- < AnimatedSwitch
444- id = "developer-mode"
445- checked = { developerMode }
446- onCheckedChange = { handleDeveloperModeChange }
447- label = { developerMode ? 'Developer Mode' : 'User Mode' }
448- />
449- </ div >
450-
451- { /* Avatar and Dropdown */ }
452- < div className = "border-l border-gray-200 dark:border-gray-800 pl-6" >
453- < AvatarDropdown onSelectTab = { handleTabClick } />
454469 </ div >
455-
456- { /* Close Button */ }
457- < button
458- onClick = { onClose }
459- className = "flex items-center justify-center w-8 h-8 rounded-full bg-transparent hover:bg-purple-500/10 dark:hover:bg-purple-500/20 group transition-all duration-200"
460- >
461- < div className = "i-ph:x w-4 h-4 text-gray-500 dark:text-gray-400 group-hover:text-purple-500 transition-colors" />
462- </ button >
463470 </ div >
464- </ div >
465471
466- { /* Content */ }
467- < div
468- className = { classNames (
469- 'flex-1' ,
470- 'overflow-y-auto' ,
471- 'hover:overflow-y-auto' ,
472- 'scrollbar scrollbar-w-2' ,
473- 'scrollbar-track-transparent' ,
474- 'scrollbar-thumb-[#E5E5E5] hover:scrollbar-thumb-[#CCCCCC]' ,
475- 'dark:scrollbar-thumb-[#333333] dark:hover:scrollbar-thumb-[#444444]' ,
476- 'will-change-scroll' ,
477- 'touch-auto' ,
478- ) }
479- >
480- < motion . div
481- key = { activeTab || 'home' }
482- initial = { { opacity : 0 } }
483- animate = { { opacity : 1 } }
484- exit = { { opacity : 0 } }
485- transition = { { duration : 0.2 } }
486- className = "p-6"
487- >
488- { showTabManagement ? (
489- < TabManagement />
490- ) : activeTab ? (
491- getTabComponent ( activeTab )
492- ) : (
493- < motion . div
494- className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 relative"
495- variants = { gridLayoutVariants }
496- initial = "hidden"
497- animate = "visible"
498- >
499- < AnimatePresence mode = "popLayout" >
500- { ( visibleTabs as TabWithDevType [ ] ) . map ( ( tab : TabWithDevType ) => (
501- < motion . div key = { tab . id } layout variants = { itemVariants } className = "aspect-[1.5/1]" >
502- < TabTile
503- tab = { tab }
504- onClick = { ( ) => handleTabClick ( tab . id as TabType ) }
505- isActive = { activeTab === tab . id }
506- hasUpdate = { getTabUpdateStatus ( tab . id ) }
507- statusMessage = { getStatusMessage ( tab . id ) }
508- description = { TAB_DESCRIPTIONS [ tab . id ] }
509- isLoading = { loadingTab === tab . id }
510- className = "h-full relative"
511- >
512- { BETA_TABS . has ( tab . id ) && < BetaLabel /> }
513- </ TabTile >
514- </ motion . div >
515- ) ) }
516- </ AnimatePresence >
517- </ motion . div >
472+ { /* Content */ }
473+ < div
474+ className = { classNames (
475+ 'flex-1' ,
476+ 'overflow-y-auto' ,
477+ 'hover:overflow-y-auto' ,
478+ 'scrollbar scrollbar-w-2' ,
479+ 'scrollbar-track-transparent' ,
480+ 'scrollbar-thumb-[#E5E5E5] hover:scrollbar-thumb-[#CCCCCC]' ,
481+ 'dark:scrollbar-thumb-[#333333] dark:hover:scrollbar-thumb-[#444444]' ,
482+ 'will-change-scroll' ,
483+ 'touch-auto' ,
518484 ) }
519- </ motion . div >
485+ >
486+ < motion . div
487+ key = { activeTab || 'home' }
488+ initial = { { opacity : 0 } }
489+ animate = { { opacity : 1 } }
490+ exit = { { opacity : 0 } }
491+ transition = { { duration : 0.2 } }
492+ className = "p-6"
493+ >
494+ { showTabManagement ? (
495+ < TabManagement />
496+ ) : activeTab ? (
497+ getTabComponent ( activeTab )
498+ ) : (
499+ < motion . div
500+ className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4 relative"
501+ variants = { gridLayoutVariants }
502+ initial = "hidden"
503+ animate = "visible"
504+ >
505+ < AnimatePresence mode = "popLayout" >
506+ { ( visibleTabs as TabWithDevType [ ] ) . map ( ( tab : TabWithDevType ) => (
507+ < motion . div key = { tab . id } layout variants = { itemVariants } className = "aspect-[1.5/1]" >
508+ < TabTile
509+ tab = { tab }
510+ onClick = { ( ) => handleTabClick ( tab . id as TabType ) }
511+ isActive = { activeTab === tab . id }
512+ hasUpdate = { getTabUpdateStatus ( tab . id ) }
513+ statusMessage = { getStatusMessage ( tab . id ) }
514+ description = { TAB_DESCRIPTIONS [ tab . id ] }
515+ isLoading = { loadingTab === tab . id }
516+ className = "h-full relative"
517+ >
518+ { BETA_TABS . has ( tab . id ) && < BetaLabel /> }
519+ </ TabTile >
520+ </ motion . div >
521+ ) ) }
522+ </ AnimatePresence >
523+ </ motion . div >
524+ ) }
525+ </ motion . div >
526+ </ div >
520527 </ div >
521528 </ motion . div >
522529 </ RadixDialog . Content >
0 commit comments