update page header

This commit is contained in:
Yi 2024-09-18 18:32:33 +08:00
parent d7d7281c93
commit 792595a46f
11 changed files with 97 additions and 69 deletions

View File

@ -35,8 +35,11 @@ const Container = () => {
const containerRef = useRef<HTMLDivElement>(null)
return (
<div ref={containerRef} className='grow relative flex flex-col rounded-t-xl bg-components-panel-bg border-t
border-divider-subtle overflow-y-auto'>
<div
ref={containerRef}
className='grow relative flex flex-col rounded-t-xl bg-components-panel-bg border-t
border-divider-subtle overflow-y-auto'
>
<div className='flex min-h-[60px] px-12 pt-4 pb-2 items-center self-stretch gap-1'>
<div className='flex justify-between items-center w-full'>
<div className='flex-1'>
@ -96,12 +99,15 @@ const Container = () => {
</div>
</div>
</div>
<div className='flex flex-col flex-grow pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'>
<div className='flex flex-col pt-1 pb-3 px-12 justify-center items-start gap-3 self-stretch'>
<div className='h-px self-stretch bg-divider-subtle'></div>
<div className='flex items-center gap-2 self-stretch'>
{/* Content for active tab will go here */}
{/* Filter goes here */}
</div>
</div>
<div className='flex px-12 items-start content-start gap-2 flex-grow self-stretch flex-wrap'>
{/* Plugin cards go here */}
</div>
<div className='flex items-center justify-center py-4 gap-2 text-text-quaternary'>
<RiDragDropLine className='w-4 h-4' />
<span className='system-xs-regular'>Drop plugin package here to install</span>

View File

@ -1,7 +1,6 @@
'use client'
import type { FC } from 'react'
import classNames from '@/utils/classnames'
import { useSelector } from '@/context/app-context'
type LogoSiteProps = {
className?: string
@ -10,17 +9,10 @@ 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={src}
className={classNames('block w-auto h-10', className)}
src={'/logo/logo.png'}
className={classNames('block w-[22.651px] h-[24.5px]', className)}
alt='logo'
/>
)

View File

@ -7,11 +7,13 @@ import cn from '@/utils/classnames'
import { useProviderContext } from '@/context/provider-context'
type Props = {
onClick: () => void
onClick?: () => void
isDisplayOnly?: boolean
}
const HeaderBillingBtn: FC<Props> = ({
onClick,
isDisplayOnly = false,
}) => {
const { plan, enableBilling, isFetchedPlan } = useProviderContext()
const {
@ -25,9 +27,9 @@ const HeaderBillingBtn: FC<Props> = ({
})()
const classNames = (() => {
if (type === Plan.professional)
return 'border-[#E0F2FE] hover:border-[#B9E6FE] bg-[#E0F2FE] text-[#026AA2]'
return `border-[#E0F2FE] ${!isDisplayOnly ? 'hover:border-[#B9E6FE]' : ''} bg-[#E0F2FE] text-[#026AA2]`
if (type === Plan.team)
return 'border-[#E0EAFF] hover:border-[#C7D7FE] bg-[#E0EAFF] text-[#3538CD]'
return `border-[#E0EAFF] ${!isDisplayOnly ? 'hover:border-[#C7D7FE]' : ''} bg-[#E0EAFF] text-[#3538CD]`
return ''
})()
@ -35,10 +37,22 @@ const HeaderBillingBtn: FC<Props> = ({
return null
if (type === Plan.sandbox)
return <UpgradeBtn onClick={onClick} isShort />
return <UpgradeBtn onClick={isDisplayOnly ? undefined : onClick} isShort />
const handleClick = () => {
if (!isDisplayOnly && onClick)
onClick()
}
return (
<div onClick={onClick} className={cn(classNames, 'flex items-center h-[22px] px-2 rounded-md border text-xs font-semibold uppercase cursor-pointer')}>
<div
onClick={handleClick}
className={cn(
classNames,
'flex items-center h-[22px] px-2 rounded-md border text-xs font-semibold uppercase',
isDisplayOnly ? 'cursor-default' : 'cursor-pointer',
)}
>
{name}
</div>
)

View File

@ -9,7 +9,6 @@ import { Menu, Transition } from '@headlessui/react'
import Indicator from '../indicator'
import AccountAbout from '../account-about'
import { mailToSupport } from '../utils/util'
import WorkplaceSelector from './workplace-selector'
import classNames from '@/utils/classnames'
import I18n from '@/context/i18n'
import Avatar from '@/app/components/base/avatar'
@ -101,10 +100,6 @@ export default function AppSelector({ isMobile }: IAppSelector) {
</div>
</div>
</Menu.Item>
<div className='px-1 py-1'>
<div className='mt-2 px-3 text-xs font-medium text-gray-500'>{t('common.userProfile.workspace')}</div>
<WorkplaceSelector />
</div>
<div className="px-1 py-1">
<Menu.Item>
<div className={itemClassName} onClick={() => setShowAccountSettingModal({ payload: 'account' })}>

View File

@ -2,33 +2,20 @@ import { Fragment } from 'react'
import { useContext } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { Menu, Transition } from '@headlessui/react'
import s from './index.module.css'
import { RiArrowDownSLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import { switchWorkspace } from '@/service/common'
import { useWorkspacesContext } from '@/context/workspace-context'
import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows'
import { Check } from '@/app/components/base/icons/src/vender/line/general'
import HeaderBillingBtn from '@/app/components/billing/header-billing-btn'
import { useProviderContext } from '@/context/provider-context'
import { ToastContext } from '@/app/components/base/toast'
const itemClassName = `
flex items-center px-3 py-2 h-10 cursor-pointer
`
const itemIconClassName = `
shrink-0 mr-2 flex items-center justify-center w-6 h-6 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600
`
const itemNameClassName = `
grow mr-2 text-sm text-gray-700 text-left
`
const itemCheckClassName = `
shrink-0 w-4 h-4 text-primary-600
`
const WorkplaceSelector = () => {
const { t } = useTranslation()
const { notify } = useContext(ToastContext)
const { workspaces } = useWorkspacesContext()
const { enableBilling } = useProviderContext()
const currentWorkspace = workspaces.find(v => v.current)
const handleSwitchWorkspace = async (tenant_id: string) => {
try {
if (currentWorkspace?.id === tenant_id)
@ -49,13 +36,13 @@ const WorkplaceSelector = () => {
<>
<Menu.Button className={cn(
`
${itemClassName} w-full
group hover:bg-gray-50 cursor-pointer ${open && 'bg-gray-50'} rounded-lg
flex items-center p-0.5 gap-1.5 w-full
group hover:bg-state-base-hover cursor-pointer ${open && 'bg-state-base-hover'} rounded-[10px]
`,
)}>
<div className={itemIconClassName}>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
<div className={`${itemNameClassName} truncate`}>{currentWorkspace?.name}</div>
<ChevronRight className='shrink-0 w-[14px] h-[14px] text-gray-500' />
<div className='flex items-center justify-center w-7 h-7 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{currentWorkspace?.name[0].toLocaleUpperCase()}</div>
<div className={'truncate max-w-[80px] line-clamp-1 overflow-hidden text-text-secondary text-ellipsis system-sm-medium'}>{currentWorkspace?.name}</div>
<RiArrowDownSLine className='w-4 h-4 text-text-secondary' />
</Menu.Button>
<Transition
as={Fragment}
@ -69,19 +56,24 @@ const WorkplaceSelector = () => {
<Menu.Items
className={cn(
`
absolute top-[1px] min-w-[200px] max-h-[70vh] overflow-y-scroll z-10 bg-white border-[0.5px] border-gray-200
divide-y divide-gray-100 origin-top-right rounded-xl
flex w-[280px] flex-col items-start absolute left-[-15px] mt-1 rounded-xl shadows-shadow-lg
`,
s.popup,
)}
>
<div className="px-1 py-1">
<div className="flex flex-col p-1 pb-2 items-start self-stretch w-full rounded-xl border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadows-shadow-lg ">
<div className='flex px-3 pt-1 pb-0.5 items-start self-stretch'>
<span className='flex-1 text-text-tertiary system-xs-medium-uppercase'>{t('common.userProfile.workspace')}</span>
</div>
{
workspaces.map(workspace => (
<div className={itemClassName} key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
<div className={itemIconClassName}>{workspace.name[0].toLocaleUpperCase()}</div>
<div className={itemNameClassName}>{workspace.name}</div>
{workspace.current && <Check className={itemCheckClassName} />}
<div className='flex py-1 pl-3 pr-2 items-center gap-2 self-stretch hover:bg-state-base-hover rounded-lg' key={workspace.id} onClick={() => handleSwitchWorkspace(workspace.id)}>
<div className='flex items-center justify-center w-7 h-7 bg-[#EFF4FF] rounded-md text-xs font-medium text-primary-600'>{workspace.name[0].toLocaleUpperCase()}</div>
<div className='line-clamp-1 flex-grow overflow-hidden text-text-secondary text-ellipsis system-md-regular'>{workspace.name}</div>
{enableBilling && (
<div className='select-none'>
<HeaderBillingBtn isDisplayOnly={true} />
</div>
)}
</div>
))
}

View File

@ -16,6 +16,7 @@ import GithubStar from './github-star'
import { WorkspaceProvider } from '@/context/workspace-context'
import { useAppContext } from '@/context/app-context'
import LogoSite from '@/app/components/base/logo/logo-site'
import WorkplaceSelector from '@/app/components/header/account-dropdown/workplace-selector'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import { useProviderContext } from '@/context/provider-context'
import { useModalContext } from '@/context/modal-context'
@ -48,7 +49,7 @@ const Header = () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedSegment])
return (
<div className='flex flex-1 items-center justify-between px-4'>
<div className='flex flex-1 items-center justify-between pr-3'>
<div className='flex items-center'>
{isMobile && <div
className='flex items-center justify-center h-8 w-8 cursor-pointer'
@ -56,23 +57,31 @@ const Header = () => {
>
<Bars3Icon className="h-4 w-4 text-gray-500" />
</div>}
{!isMobile && <>
<Link href="/apps" className='flex items-center mr-4'>
{!isMobile
&& <div className='flex w-64 p-2 pl-3 gap-1.5 items-center shrink-0 self-stretch'>
<Link href="/apps" className='flex w-8 h-8 items-center justify-center gap-2 shrink-0'>
<LogoSite className='object-contain' />
</Link>
{enableBilling && (
<div className='select-none'>
<HeaderBillingBtn onClick={handlePlanClick} />
</div>
)}
<GithubStar />
</>}
<div className='font-light text-divider-deep'>/</div>
<div className='flex items-center gap-0.5'>
<WorkspaceProvider>
<WorkplaceSelector />
</WorkspaceProvider>
{enableBilling && (
<div className='select-none'>
<HeaderBillingBtn onClick={handlePlanClick} />
</div>
)}
</div>
</div>
}
</div>
{isMobile && (
<div className='flex'>
<Link href="/apps" className='flex items-center mr-4'>
<LogoSite />
</Link>
<div className='font-light text-divider-deep'>/</div>
{enableBilling && (
<div className='select-none'>
<HeaderBillingBtn onClick={handlePlanClick} />
@ -94,9 +103,7 @@ const Header = () => {
<div className='mr-3'>
<PluginsNav />
</div>
<WorkspaceProvider>
<AccountDropdown isMobile={isMobile} />
</WorkspaceProvider>
<AccountDropdown isMobile={isMobile} />
</div>
{(isMobile && isShowNavMenu) && (
<div className='w-full flex flex-col p-2 gap-y-1'>

View File

@ -68,7 +68,7 @@ const Nav = ({
{
curNav && isActivated && (
<>
<div className='font-light text-gray-300 '>/</div>
<div className='font-light text-divider-deep'>/</div>
<NavSelector
isApp={isApp}
curNav={curNav}

View File

@ -0,0 +1,7 @@
.textGradient {
background: linear-gradient(92deg, #2250F2 -29.55%, #0EBCF3 75.22%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}

View File

@ -1,5 +1,10 @@
const translation = {
plugins: {
title: 'Plugins',
},
discover: {
title: 'Explore Marketplace',
},
}
export default translation

View File

@ -0,0 +1,10 @@
const translation = {
plugins: {
title: '插件',
},
discover: {
title: '探索市场',
},
}
export default translation

BIN
web/public/logo/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB