GitFOSS
.ts
TypeScript
(application/typescript)
// 3rd-party
import React, { useMemo, VFC } from "react";
import styled, { css } from "styled-components";
// app
import type { CommonProps, WithThemeSchemeProp } from "../types";
import { Const } from "../const";
import { NamedColors } from "../utils/style";

interface PageHeaderProps extends CommonProps {}

const SIDE_MENU_WIDTH = 320;

export const PageHeader: VFC<PageHeaderProps & WithThemeSchemeProp> = ({
  commonProps,
  themeScheme,
}) => {
  const invertThemeScheme = themeScheme === "light" ? "dark" : "light";

  const pageHeaderActions = useMemo(() => {
    if (commonProps.authenticated) {
      return (
        <>
          <a aria-label={"Log off your account"} href={"/auth/logout"}>
            Logout
          </a>
        </>
      );
    }

    return (
      <>
        <a aria-label={"Register a new account"} href={"/auth/register"}>
          Register
        </a>
        <a aria-label={"Login to your account"} href={"/auth/login"}>
          Login
        </a>
      </>
    );
  }, [commonProps.authenticated]);

  return (
    <StyledPageHeader themeScheme={themeScheme}>
      <StyledLogoArea themeScheme={themeScheme}>
        <a href={"/"}>
          <h1 style={{ margin: 0, marginLeft: 20 }}>{Const.APP_NAME}</h1>
        </a>
      </StyledLogoArea>
      <StyledPageHeaderNav>
        <a aria-label={"Explore Repositories"} href={"/repo/explore"}>
          Explore Repositories
        </a>
      </StyledPageHeaderNav>
      <StyledActionsArea>
        {commonProps.authenticated && (
          <a aria-label={"Create a new Repository"} href={"/repo/new"}>
            New Repository
          </a>
        )}
        <a
          href={`/theme/${invertThemeScheme}`}
          style={{ color: NamedColors.TEXT_MUTED[themeScheme] }}
          title={`Click to enable ${
            themeScheme === "light" ? "dark" : "light"
          } mode`}
        >
          {`${themeScheme === "light" ? "Dark" : "Light"} mode`}
        </a>
        {pageHeaderActions}
      </StyledActionsArea>
    </StyledPageHeader>
  );
};

const StyledPageHeader = styled.header<WithThemeSchemeProp>`
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-start;
  align-items: center;

  height: 100%;
  width: 100%;

  gap: 16px;

  & a {
    transition: color 140ms ease-in-out 0s;
    text-decoration: none;

    ${({ themeScheme }) => css`
      color: ${NamedColors.TEXT_MUTED[themeScheme]};
    `};

    &:hover {
      ${({ themeScheme }) => css`
        color: ${NamedColors.TEXT_DEFAULT[themeScheme]};
      `};
      text-decoration: underline;
    }
  }
`;

const StyledLogoArea = styled.div<WithThemeSchemeProp>`
  max-width: ${SIDE_MENU_WIDTH}px;
  width: 100%;

  & > a {
    display: flex;
    flex-flow: row nowrap;
    justify-content: flex-start;
    align-items: center;

    ${({ themeScheme }) => css`
      color: ${NamedColors.TEXT_DEFAULT[themeScheme]};
    `};
  }
`;

const StyledPageHeaderNav = styled.nav`
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-start;
  align-items: center;

  flex: 1;
  height: 100%;
  width: 100%;

  gap: 24px;
  margin-left: 4px;
`;

const StyledActionsArea = styled.div`
  display: flex;
  flex-flow: row nowrap;
  justify-content: flex-end;
  align-items: center;

  padding-right: 12px;

  & > a {
    margin-left: 12px;
  }
`;