mirror of https://github.com/MaxLeiter/Drift
				
				
				
			Far superior header
							parent
							
								
									41f0dd5c7a
								
							
						
					
					
						commit
						6c8e7933e1
					
				@ -0,0 +1,33 @@
 | 
			
		||||
.tabs {
 | 
			
		||||
  flex: 1 1;
 | 
			
		||||
  padding: 0 var(--gap);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tabs .current {
 | 
			
		||||
  border-bottom: 2px solid initial;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.tabs :global(.content) {
 | 
			
		||||
  display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media only screen and (max-width: 600px) {
 | 
			
		||||
  .tabs {
 | 
			
		||||
    display: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.controls {
 | 
			
		||||
  flex: 1 1;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: flex-end;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.controls :global(.menu-toggle) {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  min-width: 40px;
 | 
			
		||||
  height: 40px;
 | 
			
		||||
  padding: 0;
 | 
			
		||||
}
 | 
			
		||||
@ -1,34 +1,161 @@
 | 
			
		||||
import { Page, ButtonGroup, Button } from "@geist-ui/core";
 | 
			
		||||
import { Moon, Sun } from "@geist-ui/icons";
 | 
			
		||||
import { Page, ButtonGroup, Button, useBodyScroll, useMediaQuery, useTheme, Tabs, Loading } from "@geist-ui/core";
 | 
			
		||||
import { Moon, Sun, UserPlus as SignUpIcon, User as SignInIcon, Home as HomeIcon, Menu as MenuIcon, Tool as SettingsIcon, UserX as SignoutIcon, PlusCircle as NewIcon, List as YourIcon } from "@geist-ui/icons";
 | 
			
		||||
import { DriftProps } from "../../pages/_app";
 | 
			
		||||
import ShiftBy from "../shift-by";
 | 
			
		||||
import Link from '../Link'
 | 
			
		||||
import { useEffect, useMemo, useState } from "react";
 | 
			
		||||
import styles from './header.module.css';
 | 
			
		||||
import { useRouter } from "next/router";
 | 
			
		||||
import useSignedIn from "../../lib/hooks/use-signed-in";
 | 
			
		||||
 | 
			
		||||
const Header = ({ theme, changeTheme }: DriftProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <Page.Header height={'40px'} margin={0} paddingBottom={0} paddingTop={"var(--gap)"} >
 | 
			
		||||
            <ButtonGroup>
 | 
			
		||||
                <Button onClick={() => {
 | 
			
		||||
 | 
			
		||||
const Header = ({ changeTheme }: DriftProps) => {
 | 
			
		||||
    const router = useRouter();
 | 
			
		||||
    const [selectedTab, setSelectedTab] = useState<string>();
 | 
			
		||||
    const [expanded, setExpanded] = useState<boolean>(false)
 | 
			
		||||
    const [, setBodyHidden] = useBodyScroll(null, { scrollLayer: true })
 | 
			
		||||
    const isMobile = useMediaQuery('xs', { match: 'down' })
 | 
			
		||||
    const { isLoading, isSignedIn } = useSignedIn({ redirectIfNotAuthed: false })
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        setBodyHidden(expanded)
 | 
			
		||||
    }, [expanded, setBodyHidden])
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (!isMobile) {
 | 
			
		||||
            setExpanded(false)
 | 
			
		||||
        }
 | 
			
		||||
    }, [isMobile])
 | 
			
		||||
    const pages = useMemo(() => [
 | 
			
		||||
        {
 | 
			
		||||
            name: "Home",
 | 
			
		||||
            href: "/",
 | 
			
		||||
            icon: <HomeIcon />,
 | 
			
		||||
            condition: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "New",
 | 
			
		||||
            href: "/new",
 | 
			
		||||
            icon: <NewIcon />,
 | 
			
		||||
            condition: isSignedIn
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Yours",
 | 
			
		||||
            href: "/mine",
 | 
			
		||||
            icon: <YourIcon />,
 | 
			
		||||
            condition: isSignedIn
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Settings",
 | 
			
		||||
            href: "/",
 | 
			
		||||
            icon: <SettingsIcon />,
 | 
			
		||||
            condition: isSignedIn
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Sign out",
 | 
			
		||||
            action: () => {
 | 
			
		||||
                if (typeof window !== 'undefined') {
 | 
			
		||||
                    localStorage.clear();
 | 
			
		||||
                }}><Link href="/signin">Sign out</Link></Button>
 | 
			
		||||
                <Button>
 | 
			
		||||
                    {/* TODO: Link outside Button, but seems to break ButtonGroup */}
 | 
			
		||||
                    <Link href="/mine">
 | 
			
		||||
                        Yours
 | 
			
		||||
                    </Link>
 | 
			
		||||
                </Button>
 | 
			
		||||
                <Button>
 | 
			
		||||
                    {/* TODO: Link outside Button, but seems to break ButtonGroup */}
 | 
			
		||||
                    <Link href="/new">
 | 
			
		||||
                        New
 | 
			
		||||
                    </Link>
 | 
			
		||||
                </Button>
 | 
			
		||||
                <Button onClick={() => changeTheme()}>
 | 
			
		||||
                    <ShiftBy y={6}>{theme === 'light' ? <Moon /> : <Sun />}</ShiftBy>
 | 
			
		||||
                </Button>
 | 
			
		||||
            </ButtonGroup>
 | 
			
		||||
                    router.push("/signin");
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            icon: <SignoutIcon />,
 | 
			
		||||
            condition: isSignedIn
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Sign in",
 | 
			
		||||
            href: "/signin",
 | 
			
		||||
            icon: <SignInIcon />,
 | 
			
		||||
            condition: !isSignedIn
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            name: "Sign up",
 | 
			
		||||
            href: "/signup",
 | 
			
		||||
            icon: <SignUpIcon />,
 | 
			
		||||
            condition: !isSignedIn
 | 
			
		||||
        }
 | 
			
		||||
    ], [isSignedIn, router])
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        setSelectedTab(pages.find((page) => {
 | 
			
		||||
            if (page.href && page.href === router.asPath) {
 | 
			
		||||
                return true
 | 
			
		||||
            }
 | 
			
		||||
        })?.href)
 | 
			
		||||
    }, [pages, router, router.pathname])
 | 
			
		||||
 | 
			
		||||
    if (isLoading) {
 | 
			
		||||
        return <Page.Header height={'var(--page-nav-height)'} margin={0} paddingBottom={0} paddingTop={"var(--gap)"} >
 | 
			
		||||
 | 
			
		||||
        </Page.Header>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Page.Header height={'var(--page-nav-height)'} margin={0} paddingBottom={0} paddingTop={"var(--gap)"} >
 | 
			
		||||
            <div className={styles.tabs}>
 | 
			
		||||
                <Tabs
 | 
			
		||||
                    value={selectedTab}
 | 
			
		||||
                    leftSpace={0}
 | 
			
		||||
                    activeClassName={styles.current}
 | 
			
		||||
                    align="center"
 | 
			
		||||
                    hideDivider
 | 
			
		||||
                    hideBorder
 | 
			
		||||
                    onChange={(tab) => {
 | 
			
		||||
                        const nameMatch = pages.find(page => page.name === tab)
 | 
			
		||||
                        if (nameMatch?.action) {
 | 
			
		||||
                            nameMatch.action()
 | 
			
		||||
                        } else {
 | 
			
		||||
                            router.push(`${tab}`)
 | 
			
		||||
                        }
 | 
			
		||||
                    }}>
 | 
			
		||||
                    {pages.map((tab, index) => {
 | 
			
		||||
                        console.log(tab, tab.condition)
 | 
			
		||||
                        if (tab.condition)
 | 
			
		||||
                            return <Tabs.Item
 | 
			
		||||
                                font="14px"
 | 
			
		||||
                                label={<>{tab.icon} {tab.name}</>}
 | 
			
		||||
                                value={tab.href || tab.name}
 | 
			
		||||
                                key={`${tab.name}-${index}`}
 | 
			
		||||
                            />
 | 
			
		||||
                        else return null
 | 
			
		||||
                    })}
 | 
			
		||||
                </Tabs>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div className="controls">
 | 
			
		||||
                {isMobile ? (
 | 
			
		||||
                    <Button
 | 
			
		||||
                        className="menu-toggle"
 | 
			
		||||
                        auto
 | 
			
		||||
                        type="abort"
 | 
			
		||||
                        onClick={() => setExpanded(!expanded)}>
 | 
			
		||||
                        <MenuIcon size="1.125rem" />
 | 
			
		||||
                    </Button>
 | 
			
		||||
                ) : (
 | 
			
		||||
                    // <Controls />
 | 
			
		||||
                    <></>
 | 
			
		||||
                )}
 | 
			
		||||
            </div>
 | 
			
		||||
        </Page.Header >
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Header
 | 
			
		||||
export default Header
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// {/* {/* <ButtonGroup>
 | 
			
		||||
//                 <Button onClick={() => {
 | 
			
		||||
 | 
			
		||||
//                 }}><Link href="/signin">Sign out</Link></Button>
 | 
			
		||||
//                 <Button>
 | 
			
		||||
//                     <Link href="/mine">
 | 
			
		||||
//                         Yours
 | 
			
		||||
//                     </Link>
 | 
			
		||||
//                 </Button>
 | 
			
		||||
//                 <Button>
 | 
			
		||||
//                     {/* TODO: Link outside Button, but seems to break ButtonGroup */}
 | 
			
		||||
// <Link href="/new">
 | 
			
		||||
//     New
 | 
			
		||||
// </Link>
 | 
			
		||||
//                 </Button >
 | 
			
		||||
//     <Button onClick={() => changeTheme()}>
 | 
			
		||||
//         <ShiftBy y={6}>{theme.type === 'light' ? <Moon /> : <Sun />}</ShiftBy>
 | 
			
		||||
//     </Button>
 | 
			
		||||
//             </ButtonGroup > * /}
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
import { Page, ButtonGroup, Button } from "@geist-ui/core";
 | 
			
		||||
import { Moon, Sun } from "@geist-ui/icons";
 | 
			
		||||
import { DriftProps } from "../../pages/_app";
 | 
			
		||||
import ShiftBy from "../shift-by";
 | 
			
		||||
import Link from '../Link'
 | 
			
		||||
 | 
			
		||||
const UnauthenticatedHeader = ({ theme, changeTheme }: DriftProps) => {
 | 
			
		||||
    return (
 | 
			
		||||
        <Page.Header height={'40px'} margin={0} paddingBottom={0} paddingTop={"var(--gap)"} >
 | 
			
		||||
            <ButtonGroup>
 | 
			
		||||
                <Button><Link href="/signup">Sign up</Link></Button>
 | 
			
		||||
                <Button><Link href="/signin">Sign in</Link></Button>
 | 
			
		||||
                <Button onClick={() => changeTheme()}>
 | 
			
		||||
                    <ShiftBy y={6}>{theme === 'light' ? <Moon /> : <Sun />}</ShiftBy>
 | 
			
		||||
                </Button>
 | 
			
		||||
            </ButtonGroup>
 | 
			
		||||
        </Page.Header >
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default UnauthenticatedHeader
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
import Head from 'next/head'
 | 
			
		||||
import styles from '../styles/Home.module.css'
 | 
			
		||||
import { Page } from '@geist-ui/core'
 | 
			
		||||
 | 
			
		||||
import Header from '../components/header'
 | 
			
		||||
import { ThemeProps } from './_app'
 | 
			
		||||
import Document from '../components/document'
 | 
			
		||||
const Home = ({ theme, changeTheme }: ThemeProps) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <Page className={styles.container}>
 | 
			
		||||
      <Head>
 | 
			
		||||
        <title>Drift</title>
 | 
			
		||||
        <meta name="description" content="A self-hostable clone of GitHub Gist" />
 | 
			
		||||
        <link rel="icon" href="/favicon.ico" />
 | 
			
		||||
      </Head>
 | 
			
		||||
      <Page.Header>
 | 
			
		||||
        <Header theme={theme} changeTheme={changeTheme} />
 | 
			
		||||
      </Page.Header>
 | 
			
		||||
      <Page.Content width={"var(--main-content-width)"} margin="auto">
 | 
			
		||||
        <Document
 | 
			
		||||
          editable={false}
 | 
			
		||||
          content={
 | 
			
		||||
            `# Welcome to Drift
 | 
			
		||||
### Drift is a self-hostable clone of GitHub Gist.
 | 
			
		||||
#### It is a simple way to share code and text snippets with your friends, with support for the following:
 | 
			
		||||
 | 
			
		||||
- Render GitHub Extended Markdown and LaTeX (including images)
 | 
			
		||||
- User authentication
 | 
			
		||||
- Private, public, and secret posts
 | 
			
		||||
 | 
			
		||||
If you need to signup, you can join at [/signup](/signup). If you're already signed in, you can create a new post by clicking the "New" button in the header.
 | 
			
		||||
`}
 | 
			
		||||
          title={`Welcome to Drift`}
 | 
			
		||||
          initialTab={`preview`}
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
      </Page.Content>
 | 
			
		||||
    </Page >
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Home
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue