Skip to content

Commit

Permalink
refactor: clean up main navigation and ui
Browse files Browse the repository at this point in the history
  • Loading branch information
beeman committed Nov 8, 2024
1 parent b15ef3d commit cf0357e
Show file tree
Hide file tree
Showing 25 changed files with 352 additions and 252 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export function useUserFindManyCommunity(props?: Partial<UserFindManyCommunityIn
return {
items,
query,
isLoading: query.isLoading,
pagination: {
page,
setPage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function useUserGetCommunities({ username }: { username: string }) {
const items = query.data?.items ?? []

return {
isLoading: query.isLoading,
items,
query,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function UserCommunityDetailFeature() {
<UiStack gap="lg">
<UiGroup>
<Group>
<UiBack />
<UiBack to="/" />
<CommunityUiItem
community={item}
title={
Expand Down
17 changes: 3 additions & 14 deletions libs/web/community/ui/src/lib/community-ui-list-item.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { Button, Paper } from '@mantine/core'
import { Paper } from '@mantine/core'
import { Community } from '@pubkey-link/sdk'
import { AppUiDebugModal } from '@pubkey-link/web-core-ui'
import { RoleUiListWithAssets } from '@pubkey-link/web-role-ui'
import { UiGroup, UiInfo, UiLoader, UiStack } from '@pubkey-ui/core'
import { Suspense, useState } from 'react'
import { Suspense } from 'react'
import { CommunityUiItem } from './community-ui-item'
import { CommunityUiSocials } from './community-ui-socials'

export function CommunityUiListItem({ item, to, username }: { item: Community; to?: string; username: string }) {
const [showDetails, setShowDetails] = useState(false)
return (
<Paper withBorder p="md">
<UiStack>
Expand All @@ -18,21 +17,11 @@ export function CommunityUiListItem({ item, to, username }: { item: Community; t
<CommunityUiSocials community={item}>
<AppUiDebugModal data={item} />
</CommunityUiSocials>
<Button
disabled={!item?.roles?.length}
variant="subtle"
size="xs"
onClick={() => setShowDetails(!showDetails)}
>
{showDetails ? 'Hide' : 'Show'} Details
</Button>
</UiStack>
</UiGroup>
<Suspense fallback={<UiLoader />}>
{item?.roles?.length ? (
showDetails ? (
<RoleUiListWithAssets mt="xs" roles={item.roles ?? []} username={username} />
) : null
<RoleUiListWithAssets mt="xs" roles={item.roles ?? []} username={username} />
) : (
<UiInfo message="No roles." />
)}
Expand Down
79 changes: 40 additions & 39 deletions libs/web/core/feature/src/lib/web-core-layout.tsx
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
import { ActionIcon, Group } from '@mantine/core'
import { ActionIcon, Box, Group, Tooltip, UnstyledButton } from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { useAuth } from '@pubkey-link/web-auth-data-access'
import { AppLogo, UiHeaderProfile } from '@pubkey-link/web-core-ui'
import { UiHeader, UiHeaderLink, UiLayout, UiLoader } from '@pubkey-ui/core'
import { IconBug, IconSettings } from '@tabler/icons-react'
import { ReactNode, Suspense, useMemo } from 'react'
import { AppLogo, AppUiHeader, AppUiThemeSwitch } from '@pubkey-link/web-core-ui'
import { UiAvatar, UiLoader } from '@pubkey-ui/core'
import { IconLogout, IconShield } from '@tabler/icons-react'
import { ReactNode, Suspense } from 'react'
import { Link } from 'react-router-dom'

export function WebCoreLayout({ children }: { children: ReactNode }) {
const { isAdmin, isDeveloper, user } = useAuth()
const { isAdmin, user, logout } = useAuth()
const [opened, { toggle }] = useDisclosure(false)
const links: UiHeaderLink[] = useMemo(() => {
const items: UiHeaderLink[] = [
{ link: `/u`, label: 'Profile' },
{ link: '/c', label: 'Communities' },
]
if (isAdmin) {
items.push({ link: '/admin', label: 'Admin' })
}
return items
}, [isAdmin, user])
return (
<UiLayout
header={
<UiHeader
logoSmall={<AppLogo height={28} />}
logo={<AppLogo height={28} />}
opened={opened}
toggle={toggle}
links={links}
profile={
<Group gap="xs">
{isAdmin && isDeveloper && (
<ActionIcon component={Link} to="/admin/development" variant="light" size="lg">
<IconBug />
<Box>
<AppUiHeader
logoSmall={<AppLogo height={28} />}
logo={<AppLogo height={28} />}
opened={opened}
toggle={toggle}
links={[]}
profile={
<Group gap="xs" wrap="nowrap">
<AppUiThemeSwitch />
{isAdmin && (
<Tooltip label={'Admin Dashboard'} withArrow position="top">
<ActionIcon component={Link} to="/admin" variant="light" size="lg">
<IconShield />
</ActionIcon>
)}
<ActionIcon component={Link} to="/settings" variant="light" size="lg">
<IconSettings />
</Tooltip>
)}
<Tooltip label={'Logout'} withArrow position="top">
<ActionIcon onClick={logout} variant="light" size="lg">
<IconLogout />
</ActionIcon>
<UiHeaderProfile />
</Group>
}
/>
}
>
</Tooltip>
<UnstyledButton component={Link} to={user?.profileUrl ?? ''}>
<UiAvatar
url={user?.avatarUrl}
name={`${user?.username}`}
alt={user?.username ?? 'User Avatar'}
radius={100}
size={34}
/>
</UnstyledButton>
</Group>
}
/>

<Suspense fallback={<UiLoader mt="xl" size="xl" type="dots" />}>{children}</Suspense>
</UiLayout>
</Box>
)
}
15 changes: 14 additions & 1 deletion libs/web/core/feature/src/lib/web-core-routes-admin.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ActionIcon, Group, Tooltip } from '@mantine/core'
import { useAuth } from '@pubkey-link/web-auth-data-access'
import { AdminCommunityFeature } from '@pubkey-link/web-community-feature'
import { DevAdminRoutes } from '@pubkey-link/web-dev-feature'
import { AdminLogFeature } from '@pubkey-link/web-log-feature'
Expand All @@ -6,6 +8,7 @@ import { AdminUserFeature } from '@pubkey-link/web-user-feature'
import { AdminVerifyFeature } from '@pubkey-link/web-verify-feature'
import { UiContainer, UiDashboardGrid, UiDashboardItem, UiNotFound } from '@pubkey-ui/core'
import {
IconBug,
IconChartBar,
IconCheckupList,
IconFileText,
Expand All @@ -14,7 +17,7 @@ import {
IconUsersGroup,
} from '@tabler/icons-react'
import { lazy } from 'react'
import { Navigate, RouteObject, useRoutes } from 'react-router-dom'
import { Link, Navigate, RouteObject, useRoutes } from 'react-router-dom'

const AdminStatsFeature = lazy(() => import('./web-core-admin-stats'))

Expand All @@ -40,13 +43,23 @@ const routes: RouteObject[] = [
]

export default function WebCoreRoutesAdmin() {
const { isDeveloper } = useAuth()
return useRoutes([
{ index: true, element: <Navigate to="dashboard" replace /> },
{
path: 'dashboard/*',
element: (
<UiContainer>
<UiDashboardGrid links={links} />
<Group justify="center" mt="lg">
{isDeveloper && (
<Tooltip label={'Developer Playground'} withArrow position="top">
<ActionIcon component={Link} to="/admin/development" variant="light" size="lg">
<IconBug />
</ActionIcon>
</Tooltip>
)}
</Group>
</UiContainer>
),
},
Expand Down
3 changes: 2 additions & 1 deletion libs/web/core/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ export * from './lib/app-logo'
export * from './lib/identity-ui-avatar'
export * from './lib/identity-ui-avatar-group'
export * from './lib/app-ui-debug'
export * from './lib/app-ui-header'
export * from './lib/app-ui-theme-switch'
export * from './lib/ui-about'
export * from './lib/ui-address-input'
export * from './lib/ui-background-image'
export * from './lib/ui-discord-role-color'
export * from './lib/ui-discord-server-item'
export * from './lib/ui-empty-state'
export * from './lib/ui-grid'
export * from './lib/ui-header-profile'
export * from './lib/ui-icon'
export * from './lib/ui-icon-avatar'
export * from './lib/ui-modal-button'
Expand Down
32 changes: 32 additions & 0 deletions libs/web/core/ui/src/lib/app-ui-header/app-ui-header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.header {
height: rem(56px);
/*background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-9));*/
padding-left: var(--mantine-spacing-md);
padding-right: var(--mantine-spacing-md);
}

.inner {
height: rem(56px);
display: flex;
justify-content: space-between;
align-items: center;
}

.link {
display: block;
line-height: 1;
padding: rem(8px) rem(12px);
border-radius: var(--mantine-radius-sm);
text-decoration: none;
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
font-size: var(--mantine-font-size-sm);
font-weight: 500;

@mixin hover {
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-7));
}
}
.linkActive {
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8));
color: light-dark(var(--mantine-color-brand-6), var(--mantine-color-brand-4));
}
85 changes: 85 additions & 0 deletions libs/web/core/ui/src/lib/app-ui-header/app-ui-header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Anchor, Burger, Drawer, DrawerProps, Group, ScrollArea, Stack } from '@mantine/core'
import { useDisclosure } from '@mantine/hooks'
import { UiLogo, UiLogoType } from '@pubkey-ui/core'
import cx from 'clsx'
import { ReactNode } from 'react'
import { Link, useLocation } from 'react-router-dom'

import classes from './app-ui-header.module.css'

export interface UiHeaderProps {
base?: string
drawerProps?: DrawerProps
logo?: ReactNode
logoSmall?: ReactNode
links?: UiHeaderLink[]
opened?: boolean
profile?: ReactNode
toggle?: () => void
}
export interface UiHeaderLink {
link: string
label: string
}

export function AppUiHeader(props: UiHeaderProps) {
const { pathname } = useLocation()
const [drawerOpened, { toggle: drawerToggle }] = useDisclosure(false)
const opened = props.opened ?? drawerOpened
const toggle = props.toggle ?? drawerToggle
const burger = props.links?.length ? <Burger opened={opened} onClick={toggle} size="sm" hiddenFrom="md" /> : null

const items = props.links?.map((link) => (
<Anchor
component={Link}
key={link.label}
to={link.link}
className={cx(classes.link, { [classes.linkActive]: pathname.startsWith(link.link) })}
onClick={close}
>
{link.label}
</Anchor>
))

function close() {
if (!opened || !props.toggle) return
props.toggle()
}

return (
<header className={classes.header}>
<div className={classes.inner}>
<Group>
<Group>
{burger}
<Anchor component={Link} to={props.base ?? '/'} display="flex">
<Group hiddenFrom="md">{props.logoSmall ?? <UiLogo height={28} />}</Group>
<Group visibleFrom="md">{props.logo ?? <UiLogoType height={28} />}</Group>
</Anchor>
</Group>
<Group gap={5} className={classes.links} visibleFrom="md">
{items}
</Group>
</Group>

{props.profile ? <Group>{props.profile}</Group> : null}
</div>
<Drawer
opened={opened}
onClose={toggle}
title={
<Group>
<Anchor component={Link} to={props.base ?? '/'} display="flex" onClick={close}>
{props.logo ?? <UiLogoType height={28} />}
</Anchor>
</Group>
}
hiddenFrom="md"
scrollAreaComponent={ScrollArea}
{...props.drawerProps}
>
<Stack gap="sm">{items}</Stack>
</Drawer>
</header>
)
}
1 change: 1 addition & 0 deletions libs/web/core/ui/src/lib/app-ui-header/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './app-ui-header'
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { rem, Switch, SwitchProps, Tooltip, useMantineTheme } from '@mantine/core'
import { useUiColorScheme } from '@pubkey-ui/core'
import { IconMoonStars, IconSun } from '@tabler/icons-react'

export function AppUiThemeSwitch(props: SwitchProps) {
const theme = useMantineTheme()
const { toggleColorScheme, colorScheme } = useUiColorScheme()
const isDark = colorScheme === 'dark'
const sunIcon = <IconSun style={{ width: rem(16), height: rem(16) }} stroke={2.5} color={theme.colors.yellow[4]} />

const moonIcon = (
<IconMoonStars style={{ width: rem(16), height: rem(16) }} stroke={2.5} color={theme.colors['brand'][6]} />
)

return (
<Tooltip label={`Select ${isDark ? 'light' : 'dark'} theme`} withArrow position="top" refProp="rootRef">
<Switch
size="lg"
color="dark.9"
onLabel={sunIcon}
offLabel={moonIcon}
onChange={() => toggleColorScheme()}
checked={colorScheme === 'dark'}
{...props}
/>
</Tooltip>
)
}
1 change: 1 addition & 0 deletions libs/web/core/ui/src/lib/app-ui-theme-switch/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './app-ui-theme-switch'
Loading

0 comments on commit cf0357e

Please sign in to comment.