Browse Source

chore: layout UI upgrade (#6577)

Joel 9 months ago
parent
commit
6a9d202414

+ 1 - 1
web/app/(commonLayout)/layout.tsx

@@ -3,7 +3,7 @@ import type { ReactNode } from 'react'
 import SwrInitor from '@/app/components/swr-initor'
 import { AppContextProvider } from '@/context/app-context'
 import GA, { GaType } from '@/app/components/base/ga'
-import HeaderWrapper from '@/app/components/header/HeaderWrapper'
+import HeaderWrapper from '@/app/components/header/header-wrapper'
 import Header from '@/app/components/header'
 import { EventEmitterContextProvider } from '@/context/event-emitter'
 import { ProviderContextProvider } from '@/context/provider-context'

+ 1 - 1
web/app/components/app-sidebar/app-info.tsx

@@ -218,7 +218,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
             </div>
             {expand && (
               <div className="grow w-0">
-                <div className='flex justify-between items-center text-sm leading-5 font-medium text-gray-900'>
+                <div className='flex justify-between items-center text-sm leading-5 font-medium text-text-secondary'>
                   <div className='truncate' title={appDetail.name}>{appDetail.name}</div>
                   {isCurrentWorkspaceEditor && <RiArrowDownSLine className='shrink-0 ml-[2px] w-3 h-3 text-gray-500' />}
                 </div>

+ 4 - 4
web/app/components/app-sidebar/index.tsx

@@ -49,7 +49,7 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
   return (
     <div
       className={`
-        shrink-0 flex flex-col bg-white border-r border-gray-200 transition-all
+        shrink-0 flex flex-col bg-background-default-subtle border-r border-divider-burn transition-all
         ${expand ? 'w-[216px]' : 'w-14'}
       `}
     >
@@ -60,7 +60,7 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
         `}
       >
         {iconType === 'app' && (
-          <AppInfo expand={expand}/>
+          <AppInfo expand={expand} />
         )}
         {iconType !== 'app' && (
           <AppBasic
@@ -74,11 +74,11 @@ const AppDetailNav = ({ title, desc, icon, icon_background, navigation, extraInf
         )}
       </div>
       {!expand && (
-        <div className='mt-1 mx-auto w-6 h-[1px] bg-gray-100'/>
+        <div className='mt-1 mx-auto w-6 h-[1px] bg-divider-subtle' />
       )}
       <nav
         className={`
-          grow space-y-1 bg-white
+          grow space-y-1
           ${expand ? 'p-4' : 'px-2.5 py-4'}
         `}
       >

+ 1 - 2
web/app/components/app-sidebar/navLink.tsx

@@ -44,7 +44,7 @@ export default function NavLink({
       key={name}
       href={href}
       className={classNames(
-        isActive ? 'bg-primary-50 text-primary-600 font-semibold' : 'text-gray-700 hover:bg-gray-100 hover:text-gray-700',
+        isActive ? 'bg-state-accent-active text-text-accent font-semibold' : 'text-components-menu-item-text hover:bg-gray-100 hover:text-components-menu-item-text-hover',
         'group flex items-center h-9 rounded-md py-2 text-sm font-normal',
         mode === 'expand' ? 'px-3' : 'px-2.5',
       )}
@@ -53,7 +53,6 @@ export default function NavLink({
       <NavIcon
         className={classNames(
           'h-4 w-4 flex-shrink-0',
-          isActive ? 'text-primary-600' : 'text-gray-700',
           mode === 'expand' ? 'mr-2' : 'mr-0',
         )}
         aria-hidden="true"

+ 10 - 1
web/app/components/base/logo/logo-site.tsx

@@ -1,5 +1,7 @@
+'use client'
 import type { FC } from 'react'
 import classNames from '@/utils/classnames'
+import { useSelector } from '@/context/app-context'
 
 type LogoSiteProps = {
   className?: string
@@ -8,9 +10,16 @@ type LogoSiteProps = {
 const LogoSite: FC<LogoSiteProps> = ({
   className,
 }) => {
+  const { theme } = useSelector((s) => {
+    return {
+      theme: s.theme,
+    }
+  })
+
+  const src = theme === 'light' ? '/logo/logo-site.png' : `/logo/logo-site-${theme}.png`
   return (
     <img
-      src='/logo/logo-site.png'
+      src={src}
       className={classNames('block w-auto h-10', className)}
       alt='logo'
     />

+ 2 - 2
web/app/components/header/explore-nav/index.tsx

@@ -22,8 +22,8 @@ const ExploreNav = ({
   return (
     <Link href="/explore/apps" className={classNames(
       className, 'group',
-      actived && 'bg-white shadow-md',
-      actived ? 'text-primary-600' : 'text-gray-500 hover:bg-gray-200',
+      actived && 'bg-components-main-nav-nav-button-bg-active shadow-md',
+      actived ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text hover:bg-components-main-nav-nav-button-bg-hover',
     )}>
       {
         actived

+ 1 - 1
web/app/components/header/HeaderWrapper.tsx → web/app/components/header/header-wrapper.tsx

@@ -15,7 +15,7 @@ const HeaderWrapper = ({
 
   return (
     <div className={classNames(
-      'sticky top-0 left-0 right-0 z-30 flex flex-col bg-gray-100 grow-0 shrink-0 basis-auto min-h-[56px]',
+      'sticky top-0 left-0 right-0 z-30 flex flex-col grow-0 shrink-0 basis-auto min-h-[56px]',
       s.header,
       isBordered ? 'border-b border-gray-200' : '',
     )}

+ 4 - 4
web/app/components/header/nav/index.tsx

@@ -39,16 +39,16 @@ const Nav = ({
   return (
     <div className={`
       flex items-center h-8 mr-0 sm:mr-3 px-0.5 rounded-xl text-sm shrink-0 font-medium
-      ${isActived && 'bg-white shadow-md font-semibold'}
-      ${!curNav && !isActived && 'hover:bg-gray-200'}
+      ${isActived && 'bg-components-main-nav-nav-button-bg-active shadow-md font-semibold'}
+      ${!curNav && !isActived && 'hover:bg-components-main-nav-nav-button-bg-hover'}
     `}>
       <Link href={link}>
         <div
           onClick={() => setAppDetail()}
           className={classNames(`
             flex items-center h-7 px-2.5 cursor-pointer rounded-[10px]
-            ${isActived ? 'text-primary-600' : 'text-gray-500'}
-            ${curNav && isActived && 'hover:bg-primary-50'}
+            ${isActived ? 'text-components-main-nav-nav-button-text-active' : 'text-components-main-nav-nav-button-text'}
+            ${curNav && isActived && 'hover:bg-components-main-nav-nav-button-bg-active-hover'}
           `)}
           onMouseEnter={() => setHovered(true)}
           onMouseLeave={() => setHovered(false)}

+ 2 - 2
web/app/components/header/nav/nav-selector/index.tsx

@@ -55,8 +55,8 @@ const NavSelector = ({ curNav, navs, createText, isApp, onCreate, onLoadmore }:
         {({ open }) => (
           <>
             <Menu.Button className={cn(
-              'group inline-flex items-center w-full h-7 justify-center rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold text-primary-600 hover:bg-primary-50',
-              open && 'bg-primary-50',
+              'group inline-flex items-center w-full h-7 justify-center rounded-[10px] pl-2 pr-2.5 text-[14px] font-semibold text-components-main-nav-nav-button-text-active hover:hover:bg-components-main-nav-nav-button-bg-active-hover',
+              open && 'bg-components-main-nav-nav-button-bg-active',
             )}>
               <div className='max-w-[180px] truncate' title={curNav?.name}>{curNav?.name}</div>
               <RiArrowDownSLine

+ 19 - 1
web/context/app-context.tsx

@@ -8,10 +8,13 @@ import { fetchAppList } from '@/service/apps'
 import Loading from '@/app/components/base/loading'
 import { fetchCurrentWorkspace, fetchLanggeniusVersion, fetchUserProfile } from '@/service/common'
 import type { App } from '@/types/app'
+import { Theme } from '@/types/app'
 import type { ICurrentWorkspace, LangGeniusVersionResponse, UserProfileResponse } from '@/models/common'
 import MaintenanceNotice from '@/app/components/header/maintenance-notice'
 
 export type AppContextValue = {
+  theme: Theme
+  setTheme: (theme: Theme) => void
   apps: App[]
   mutateApps: VoidFunction
   userProfile: UserProfileResponse
@@ -49,6 +52,8 @@ const initialWorkspaceInfo: ICurrentWorkspace = {
 }
 
 const AppContext = createContext<AppContextValue>({
+  theme: Theme.light,
+  setTheme: () => { },
   apps: [],
   mutateApps: () => { },
   userProfile: {
@@ -112,11 +117,24 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
       setCurrentWorkspace(currentWorkspaceResponse)
   }, [currentWorkspaceResponse])
 
+  const [theme, setTheme] = useState<Theme>(Theme.light)
+  const handleSetTheme = useCallback((theme: Theme) => {
+    setTheme(theme)
+    globalThis.document.documentElement.setAttribute('data-theme', theme)
+  }, [])
+
+  useEffect(() => {
+    globalThis.document.documentElement.setAttribute('data-theme', theme)
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, [])
+
   if (!appList || !userProfile)
     return <Loading type='app' />
 
   return (
     <AppContext.Provider value={{
+      theme,
+      setTheme: handleSetTheme,
       apps: appList.data,
       mutateApps,
       userProfile,
@@ -133,7 +151,7 @@ export const AppContextProvider: FC<AppContextProviderProps> = ({ children }) =>
     }}>
       <div className='flex flex-col h-full overflow-y-auto'>
         {globalThis.document?.body?.getAttribute('data-public-maintenance-notice') && <MaintenanceNotice />}
-        <div ref={pageContainerRef} className='grow relative flex flex-col overflow-y-auto overflow-x-hidden bg-gray-100'>
+        <div ref={pageContainerRef} className='grow relative flex flex-col overflow-y-auto overflow-x-hidden bg-background-body'>
           {children}
         </div>
       </div>

BIN
web/public/logo/logo-site-dark.png


+ 1 - 0
web/tailwind.config.js

@@ -4,6 +4,7 @@ module.exports = {
   content: [
     './app/**/*.{js,ts,jsx,tsx}',
     './components/**/*.{js,ts,jsx,tsx}',
+    './context/**/*.{js,ts,jsx,tsx}',
   ],
   theme: {
     typography: require('./typography'),

+ 5 - 0
web/types/app.ts

@@ -3,6 +3,11 @@ import type { CollectionType } from '@/app/components/tools/types'
 import type { LanguagesSupported } from '@/i18n/language'
 import type { Tag } from '@/app/components/base/tag-management/constant'
 
+export enum Theme {
+  light = 'light',
+  dark = 'dark',
+}
+
 export enum ProviderType {
   openai = 'openai',
   anthropic = 'anthropic',