feat: fe mobile responsive next (#1609)

This commit is contained in:
Yuhao
2023-11-27 11:47:48 +08:00
committed by GitHub
parent 3cc697832a
commit a9c1c7d239
89 changed files with 768 additions and 485 deletions

View File

@@ -2,7 +2,6 @@
import classNames from 'classnames'
import { usePathname } from 'next/navigation'
import s from './index.module.css'
import { useAppContext } from '@/context/app-context'
type HeaderWrapperProps = {
children: React.ReactNode
@@ -12,22 +11,16 @@ const HeaderWrapper = ({
children,
}: HeaderWrapperProps) => {
const pathname = usePathname()
const { langeniusVersionInfo } = useAppContext()
const isBordered = ['/apps', '/datasets'].includes(pathname)
return (
<div className={classNames(
'sticky top-0 left-0 right-0 z-20 flex bg-gray-100 grow-0 shrink-0 basis-auto h-14',
'sticky top-0 left-0 right-0 z-20 flex flex-col bg-gray-100 grow-0 shrink-0 basis-auto min-h-[56px]',
s.header,
isBordered ? 'border-b border-gray-200' : '',
)}
>
<div className={classNames(
s[`header-${langeniusVersionInfo.current_env}`],
'flex flex-1 items-center justify-between px-4',
)}>
{children}
</div>
{children}
</div>
)
}

View File

@@ -17,7 +17,11 @@ import { ArrowUpRight, ChevronDown } from '@/app/components/base/icons/src/vende
import { LogOut01 } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context'
export default function AppSelector() {
export type IAppSelecotr = {
isMobile: boolean
}
export default function AppSelector({ isMobile }: IAppSelecotr) {
const itemClassName = `
flex items-center w-full h-9 px-3 text-gray-700 text-[14px]
rounded-lg font-normal hover:bg-gray-50 cursor-pointer
@@ -50,12 +54,15 @@ export default function AppSelector() {
inline-flex items-center
rounded-[20px] py-1 pr-2.5 pl-1 text-sm
text-gray-700 hover:bg-gray-200
mobile:px-1
${open && 'bg-gray-200'}
`}
>
<Avatar name={userProfile.name} className='mr-2' size={32} />
{userProfile.name}
<ChevronDown className="w-3 h-3 ml-1 text-gray-700"/>
<Avatar name={userProfile.name} className='sm:mr-2 mr-0' size={32} />
{!isMobile && <>
{userProfile.name}
<ChevronDown className="w-3 h-3 ml-1 text-gray-700"/>
</>}
</Menu.Button>
</div>
<Transition

View File

@@ -70,7 +70,7 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
)
}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='w-[576px] z-[11]'>
<PortalToFollowElemContent className='w-[calc(100%-32px)] max-w-[576px] z-[11]'>
<div className='w-full rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg z-10'>
<div className='p-1'>
<div className='flex items-center justify-between px-3 pt-2 pb-1'>

View File

@@ -76,7 +76,7 @@ const DataSourceNotion = ({
: (
<div
className={
`flex items-center px-3 h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md
`flex items-center px-3 py-1 min-h-7 bg-white border-[0.5px] border-gray-200 text-xs font-medium text-primary-600 rounded-md
${isCurrentWorkspaceManager ? 'cursor-pointer' : 'grayscale opacity-50 cursor-default'}`
}
onClick={handleConnectNotion}

View File

@@ -23,6 +23,7 @@ import { User01 as User01Solid, Users01 as Users01Solid } from '@/app/components
import { Globe01 } from '@/app/components/base/icons/src/vender/line/mapsAndTravel'
import { AtSign, XClose } from '@/app/components/base/icons/src/vender/line/general'
import { CubeOutline } from '@/app/components/base/icons/src/vender/line/shapes'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
const iconClassName = `
w-4 h-4 ml-3 mr-2
@@ -42,6 +43,10 @@ export default function AccountSetting({
}: IAccountSettingProps) {
const [activeMenu, setActiveMenu] = useState(activeTab)
const { t } = useTranslation()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const menuItems = [
{
key: 'workspace-group',
@@ -130,9 +135,9 @@ export default function AccountSetting({
wrapperClassName='!z-20 pt-[60px]'
>
<div className='flex'>
<div className='w-[200px] p-4 border border-gray-100'>
<div className='mb-8 ml-2 text-base font-medium leading-6 text-gray-900'>{t('common.userProfile.settings')}</div>
<div>
<div className='w-[44px] sm:w-[200px] px-[1px] py-4 sm:p-4 border border-gray-100 shrink-0 sm:shrink-1 flex flex-col items-center sm:items-start'>
<div className='mb-8 ml-0 sm:ml-2 text-sm sm:text-base font-medium leading-6 text-gray-900'>{t('common.userProfile.settings')}</div>
<div className='w-full'>
{
menuItems.map(menuItem => (
<div key={menuItem.key} className='mb-4'>
@@ -150,7 +155,7 @@ export default function AccountSetting({
onClick={() => setActiveMenu(item.key)}
>
{activeMenu === item.key ? item.activeIcon : item.icon}
<div className='truncate'>{item.name}</div>
{!isMobile && <div className='truncate'>{item.name}</div>}
</div>
))
}
@@ -167,7 +172,7 @@ export default function AccountSetting({
<XClose className='w-4 h-4 text-gray-500' />
</div>
</div>
<div className='px-8 pt-2'>
<div className='px-4 sm:px-8 pt-2'>
{activeMenu === 'account' && <AccountPage />}
{activeMenu === 'members' && <MembersPage />}
{activeMenu === 'integrations' && <IntegrationsPage />}

View File

@@ -51,13 +51,13 @@ const MembersPage = () => {
{t('common.members.invite')}
</div>
</div>
<div>
<div className='flex items-center py-[7px] border-b border-gray-200'>
<div className='overflow-x-auto'>
<div className='flex items-center py-[7px] border-b border-gray-200 min-w-[480px]'>
<div className='grow px-3 text-xs font-medium text-gray-500'>{t('common.members.name')}</div>
<div className='shrink-0 w-[104px] text-xs font-medium text-gray-500'>{t('common.members.lastActive')}</div>
<div className='shrink-0 w-[96px] px-3 text-xs font-medium text-gray-500'>{t('common.members.role')}</div>
</div>
<div>
<div className='min-w-[480px]'>
{
accounts.map(account => (
<div key={account.id} className='flex border-b border-gray-100'>

View File

@@ -218,7 +218,7 @@ const ModelPage = () => {
}
<SystemModel onUpdate={() => mutateProviders()} />
</div>
<div className='grid grid-cols-2 gap-4 mb-6'>
<div className='grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6'>
{
MODEL_CARD_LIST.map((model, index) => (
<ModelCard

View File

@@ -34,7 +34,7 @@ const ModelItem: FC<ModelItemProps> = ({
return (
<div className='mb-2 bg-gray-50 rounded-xl'>
<div className='flex justify-between items-center px-4 h-14'>
<div className='flex justify-between items-center p-4 min-h-[56px] flex-wrap gap-y-1'>
<div className='flex items-center'>
{modelItem.titleIcon[locale]}
{

View File

@@ -159,7 +159,7 @@ const Form: FC<FormProps> = ({
options?.map(option => (
<div
className={`
flex items-center px-3 h-9 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer
flex items-center px-3 py-2 rounded-lg border border-gray-100 bg-gray-25 cursor-pointer
${value?.[field.key] === option.key && 'bg-white border-[1.5px] border-primary-400 shadow-sm'}
`}
onClick={() => handleFormChange(field.key, option.key)}

View File

@@ -96,7 +96,7 @@ const ModelModal: FC<ModelModalProps> = ({
<PortalToFollowElem open>
<PortalToFollowElemContent className='w-full h-full z-[60]'>
<div className='fixed inset-0 flex items-center justify-center bg-black/[.25]'>
<div className='w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
<div className='mx-2 w-[640px] max-h-[calc(100vh-120px)] bg-white shadow-xl rounded-2xl overflow-y-auto'>
<div className='px-8 pt-8'>
<div className='flex justify-between items-center mb-2'>
<div className='text-xl font-semibold text-gray-900'>{renderTitlePrefix()}</div>
@@ -113,7 +113,7 @@ const ModelModal: FC<ModelModalProps> = ({
onClearedChange={setCleared}
onValidating={handleValidating}
/>
<div className='flex justify-between items-center py-6'>
<div className='flex justify-between items-center py-6 flex-wrap gap-y-2'>
<a
href={modelModal?.link.href}
target='_blank'

View File

@@ -1,43 +1,90 @@
'use client'
import Link from 'next/link'
import { useSelectedLayoutSegment } from 'next/navigation'
import classNames from 'classnames'
import { useEffect } from 'react'
import { Bars3Icon } from '@heroicons/react/20/solid'
import { useBoolean } from 'ahooks'
import AccountDropdown from './account-dropdown'
import AppNav from './app-nav'
import DatasetNav from './dataset-nav'
import EnvNav from './env-nav'
import ExploreNav from './explore-nav'
import GithubStar from './github-star'
import s from './index.module.css'
import { WorkspaceProvider } from '@/context/workspace-context'
import { useAppContext } from '@/context/app-context'
import LogoSite from '@/app/components/base/logo/logo-site'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
const navClassName = `
flex items-center relative mr-3 px-3 h-8 rounded-xl
flex items-center relative mr-3 px-3 h-9 rounded-xl
font-medium text-sm
cursor-pointer
`
const Header = () => {
const { isCurrentWorkspaceManager } = useAppContext()
const selectedSegment = useSelectedLayoutSegment()
const { isCurrentWorkspaceManager, langeniusVersionInfo } = useAppContext()
const media = useBreakpoints()
const isMobile = media === MediaType.mobile
const [isShowNavMenu, { toggle, setFalse: hideNavMenu }] = useBoolean(false)
useEffect(() => {
hideNavMenu()
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedSegment])
return (
<>
<div className='flex items-center'>
<Link href="/apps" className='flex items-center mr-4'>
<LogoSite />
</Link>
<GithubStar />
</div>
<div className='flex items-center'>
<ExploreNav className={navClassName} />
<AppNav />
{isCurrentWorkspaceManager && <DatasetNav />}
</div>
<div className='flex items-center flex-shrink-0'>
<EnvNav />
<WorkspaceProvider>
<AccountDropdown />
</WorkspaceProvider>
<div className={classNames(
s[`header-${langeniusVersionInfo.current_env}`],
'flex flex-1 items-center justify-between px-4',
)}>
<div className='flex items-center'>
{isMobile && <div
className='flex items-center justify-center h-8 w-8 cursor-pointer'
onClick={toggle}
>
<Bars3Icon className="h-4 w-4 text-gray-500" />
</div>}
{!isMobile && <>
<Link href="/apps" className='flex items-center mr-4'>
<LogoSite />
</Link>
<GithubStar />
</>}
</div>
{isMobile && (
<div className='flex'>
<Link href="/apps" className='flex items-center mr-4'>
<LogoSite />
</Link>
<GithubStar />
</div>
)}
{!isMobile && (
<div className='flex items-center'>
<ExploreNav className={navClassName} />
<AppNav />
{isCurrentWorkspaceManager && <DatasetNav />}
</div>
)}
<div className='flex items-center flex-shrink-0'>
<EnvNav />
<WorkspaceProvider>
<AccountDropdown isMobile={isMobile} />
</WorkspaceProvider>
</div>
</div>
{(isMobile && isShowNavMenu) && (
<div className='w-full flex flex-col p-2 gap-y-1'>
<ExploreNav className={navClassName} />
<AppNav />
{isCurrentWorkspaceManager && <DatasetNav />}
</div>
)}
</>
)
}

View File

@@ -34,7 +34,7 @@ const Nav = ({
return (
<div className={`
flex items-center h-8 mr-3 px-0.5 rounded-xl text-sm shrink-0 font-medium
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'}
`}>