metacubexd/src/components/Header.tsx

197 lines
4.7 KiB
TypeScript
Raw Normal View History

2023-09-01 23:25:37 +08:00
import { useI18n } from '@solid-primitives/i18n'
2023-08-27 22:25:41 +08:00
import { A, useLocation, useNavigate } from '@solidjs/router'
2023-08-24 04:20:53 +08:00
import {
2023-08-30 00:22:40 +08:00
IconArrowsExchange,
2023-08-24 04:20:53 +08:00
IconFileStack,
IconGlobe,
IconHome,
2023-09-01 23:57:58 +08:00
IconLanguage,
2023-08-30 00:22:40 +08:00
IconMenu,
2023-08-24 04:20:53 +08:00
IconNetwork,
2023-08-28 22:28:30 +08:00
IconPalette,
2023-08-24 04:20:53 +08:00
IconRuler,
IconSettings,
} from '@tabler/icons-solidjs'
2023-08-31 02:21:41 +08:00
import { For, ParentComponent, Show, createSignal } from 'solid-js'
import { twMerge } from 'tailwind-merge'
2023-08-27 22:25:41 +08:00
import { themes } from '~/constants'
import { setCurTheme, setSelectedEndpoint } from '~/signals'
2023-08-24 04:20:53 +08:00
2023-08-29 00:03:32 +08:00
const Nav: ParentComponent<{ href: string; tooltip: string }> = ({
href,
tooltip,
children,
}) => (
<li>
<A
2023-08-31 01:30:08 +08:00
class="tooltip rounded-box tooltip-bottom"
2023-08-29 00:03:32 +08:00
href={href}
data-tip={tooltip}
>
{children}
</A>
</li>
)
2023-08-30 00:22:40 +08:00
const ThemeSwitcher = () => (
<div class="drawer drawer-end w-auto sm:ml-auto">
<input id="themes" type="checkbox" class="drawer-toggle" />
2023-08-24 04:20:53 +08:00
2023-08-30 00:22:40 +08:00
<div class="drawer-content flex items-center">
<label
for="themes"
class="btn btn-circle btn-primary drawer-button btn-sm"
>
<IconPalette />
</label>
</div>
2023-08-24 04:20:53 +08:00
2023-08-30 00:22:40 +08:00
<div class="drawer-side">
<label for="themes" class="drawer-overlay" />
2023-08-24 04:20:53 +08:00
<ul class="menu rounded-box gap-2 bg-base-300 p-2 shadow">
2023-08-30 00:22:40 +08:00
<For each={themes}>
{(theme) => (
<li
data-theme={theme}
class="btn btn-xs"
onClick={() => setCurTheme(theme)}
>
{theme}
</li>
)}
</For>
</ul>
</div>
</div>
)
2023-08-24 04:20:53 +08:00
2023-08-30 00:22:40 +08:00
export const Header = () => {
2023-09-01 23:57:58 +08:00
const [t, { locale }] = useI18n()
2023-09-01 23:25:37 +08:00
const navs = () => [
{
href: '/overview',
2023-09-02 00:15:19 +08:00
name: t('overview'),
2023-09-01 23:25:37 +08:00
icon: <IconHome />,
},
{
href: '/proxies',
2023-09-02 00:15:19 +08:00
name: t('proxies'),
2023-09-01 23:25:37 +08:00
icon: <IconGlobe />,
},
{
href: '/rules',
2023-09-02 00:15:19 +08:00
name: t('rules'),
2023-09-01 23:25:37 +08:00
icon: <IconRuler />,
},
{
href: '/conns',
2023-09-02 00:15:19 +08:00
name: t('connections'),
2023-09-01 23:25:37 +08:00
icon: <IconNetwork />,
},
{
href: '/logs',
2023-09-02 00:15:19 +08:00
name: t('logs'),
2023-09-01 23:25:37 +08:00
icon: <IconFileStack />,
},
{
href: '/config',
2023-09-02 00:15:19 +08:00
name: t('config'),
2023-09-01 23:25:37 +08:00
icon: <IconSettings />,
},
]
2023-08-30 00:22:40 +08:00
const location = useLocation()
const navigate = useNavigate()
2023-08-24 04:20:53 +08:00
2023-08-31 02:21:41 +08:00
const [openedDrawer, setOpenedDrawer] = createSignal(false)
2023-08-30 00:22:40 +08:00
const onSwitchEndpointClick = () => {
setSelectedEndpoint('')
navigate('/setup')
}
2023-08-24 04:20:53 +08:00
2023-08-30 00:22:40 +08:00
return (
2023-08-31 01:30:08 +08:00
<ul class="navbar rounded-box sticky inset-x-0 top-2 z-10 mx-2 mt-2 flex w-auto items-center justify-center bg-base-300 px-4">
<div class="navbar-start gap-4">
2023-08-31 02:21:41 +08:00
<div class={twMerge('drawer w-auto lg:hidden', '')}>
<input
id="navs"
type="checkbox"
class="drawer-toggle"
onChange={(e) => setOpenedDrawer(e.target.checked)}
checked={openedDrawer()}
/>
2023-08-24 04:20:53 +08:00
2023-08-30 00:22:40 +08:00
<div class="drawer-content flex items-center">
<label for="navs" class="btn btn-circle drawer-button btn-sm">
<IconMenu />
</label>
</div>
2023-08-27 22:25:41 +08:00
2023-08-30 00:22:40 +08:00
<div class="drawer-side">
<label for="navs" class="drawer-overlay" />
2023-08-27 22:25:41 +08:00
<ul class="menu rounded-box min-h-full w-2/5 gap-2 bg-base-300 pt-20 shadow">
2023-08-30 00:22:40 +08:00
<For each={navs()}>
{({ href, name }) => (
2023-08-31 02:21:41 +08:00
<li onClick={() => setOpenedDrawer(false)}>
2023-08-30 00:22:40 +08:00
<A href={href}>{name}</A>
</li>
)}
</For>
</ul>
</div>
2023-08-27 22:25:41 +08:00
</div>
2023-08-30 00:22:40 +08:00
<a
2023-08-31 01:30:08 +08:00
class="text-xl font-bold normal-case"
2023-08-30 00:22:40 +08:00
href="https://github.com/metacubex/metacubexd"
target="_blank"
>
metacubexd
</a>
</div>
<Show when={location.pathname !== '/setup'}>
<div class="navbar-center hidden lg:flex">
2023-08-31 01:30:08 +08:00
<ul class="menu menu-horizontal gap-2">
2023-08-30 00:22:40 +08:00
<For each={navs()}>
{({ href, name, icon }) => (
<Nav href={href} tooltip={name}>
{icon}
</Nav>
2023-08-27 22:25:41 +08:00
)}
</For>
</ul>
</div>
2023-08-30 00:22:40 +08:00
</Show>
<div class="navbar-end">
<div class="flex items-center gap-2">
2023-09-01 23:57:58 +08:00
<button
class="btn btn-circle btn-sm"
onClick={() => {
const curLocale = locale()
locale(curLocale === 'en-US' ? 'zh-Hans' : 'en-US')
}}
>
<IconLanguage />
</button>
2023-08-30 00:22:40 +08:00
<ThemeSwitcher />
<button
class="btn btn-circle btn-secondary btn-sm"
onClick={onSwitchEndpointClick}
>
<IconArrowsExchange />
</button>
</div>
2023-08-27 22:25:41 +08:00
</div>
2023-08-28 22:28:30 +08:00
</ul>
2023-08-24 04:20:53 +08:00
)
}