Skip to content

Commit

Permalink
Mobile top bar
Browse files Browse the repository at this point in the history
  • Loading branch information
nekiro committed Dec 6, 2024
1 parent 1da1d19 commit 35af077
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 23 deletions.
11 changes: 7 additions & 4 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type ButtonType = "button" | "submit" | "reset";
export type ButtonColorType = "danger" | "primary";

export interface ButtonProps extends ChakraButtonProps {
value: string;
value?: string;
size?: string;
type?: ButtonType;
href?: string;
Expand All @@ -21,24 +21,27 @@ export interface ButtonProps extends ChakraButtonProps {
const Button = ({
value,
type = "button",
btnColorType = "primary",
btnColorType,
size = "md",
href,
isLoading = false,
isActive = false,
loadingText,
children,
...props
}: ButtonProps) => {
const btn = (
<ChakraButton
type={type}
colorScheme={btnTypeToColor[btnColorType]}
colorScheme={btnColorType ? btnTypeToColor[btnColorType] : undefined}
size={size}
fontWeight="normal"
isLoading={isLoading}
isActive={isActive}
loadingText={loadingText}
{...props}
>
{value}
{value ?? children}
</ChakraButton>
);

Expand Down
2 changes: 1 addition & 1 deletion src/components/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useColors } from "@hook/useColors";
export interface TextInputProps extends InputProps {}

const TextInput = forwardRef<HTMLInputElement, InputProps>(({ ...props }, ref) => {
const { inputBgColor, textColor } = useColors();
const { inputBgColor } = useColors();

return (
<Input
Expand Down
137 changes: 137 additions & 0 deletions src/layout/TopBar/Mobile.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import {
Text,
Image,
Flex,
IconButton,
useDisclosure,
VStack,
Accordion,
AccordionButton,
AccordionItem,
AccordionPanel,
HStack,
} from "@chakra-ui/react";
import { TopBarItem } from "./TopBarItem";
import Link from "@component/Link";
import { GiHamburgerMenu } from "react-icons/gi";
import { MdOutlineClose } from "react-icons/md";
import { navigationItems } from "./index";
import Button from "@component/Button";
import { IoChevronDown, IoChevronUp } from "react-icons/io5";
import { useRouter } from "next/router";
import { trpc } from "@util/trpc";

export const MobileTopBar = () => {
const user = trpc.me.me.useQuery().data;
const { isOpen, onToggle, onClose } = useDisclosure();
const router = useRouter();

const onButtonClick = (href: string) => {
onClose();
router.push(href);
};

return (
<Flex
justifyContent="space-between"
alignItems="center"
bgColor="blackAlpha.600"
h="50px"
paddingLeft="15px"
paddingRight="15px"
borderBottomWidth="1px"
borderColor="violet.400"
>
<Link href="/" style={{ height: "100%", textDecoration: "none" }}>
<TopBarItem paddingLeft={0} userSelect="none" pointerEvents="none">
<Image height="35px" src="/images/header.png" alt="shibaac" />
<Text fontSize="lg" color="white" ml="10px">
Shibaac
</Text>
</TopBarItem>
</Link>
<IconButton aria-label="Open Menu" icon={isOpen ? <MdOutlineClose /> : <GiHamburgerMenu />} variant="outline" onClick={onToggle} />
{isOpen && (
<Flex flexDir="column" position="fixed" top="0" left="0" h="100%" w="100%" zIndex="popover" bgColor="black">
<VStack w="100vw">
<HStack h="50px" paddingX="1em" justifyContent="space-between" w="100%" margin={0}>
<TopBarItem paddingLeft={0} userSelect="none" pointerEvents="none">
<Image height="35px" src="/images/header.png" alt="shibaac" />
<Text fontSize="lg" color="white" ml="10px">
Shibaac
</Text>
</TopBarItem>
<IconButton aria-label="Open Menu" icon={<MdOutlineClose />} variant="outline" onClick={onClose} />
</HStack>
<Accordion width="100%" allowMultiple>
{navigationItems.map((item) => (
<AccordionItem key={`${item.text}${item.href}`}>
{({ isExpanded }) => (
<>
<AccordionButton
display="flex"
alignItems="center"
justifyContent="space-between"
p={4}
onClick={item.href ? () => onButtonClick(item.href!) : undefined}
>
{item.text}
{item.hasMenu && (isExpanded ? <IoChevronUp fontSize="24px" /> : <IoChevronDown fontSize="24px" />)}
</AccordionButton>
{item.hasMenu && (
<AccordionPanel>
{item.menuItems?.map((item) => (
<Button
key={`sub_${item.text}${item.url}`}
variant="link"
fontSize="sm"
href={item.url}
onClick={() => onButtonClick(item.url)}
w="100%"
rounded="none"
justifyContent="flex-start"
>
{item.text}
</Button>
))}
</AccordionPanel>
)}
</>
)}
</AccordionItem>
))}
{user ? (
<AccordionItem>
<AccordionButton display="flex" alignItems="center" justifyContent="space-between" p={4} onClick={() => onButtonClick("/account")}>
Account
</AccordionButton>
</AccordionItem>
) : (
<AccordionItem>
<AccordionButton
display="flex"
alignItems="center"
justifyContent="space-between"
p={4}
onClick={() => onButtonClick("/account/login")}
>
Login
</AccordionButton>
<AccordionButton
display="flex"
alignItems="center"
justifyContent="space-between"
p={4}
onClick={() => onButtonClick("/account/register")}
>
Register
</AccordionButton>
</AccordionItem>
)}
</Accordion>
</VStack>
</Flex>
)}
</Flex>
);
};
2 changes: 1 addition & 1 deletion src/layout/TopBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export interface NavigationItems {
menuItems?: { text: string; url: string }[];
}

const navigationItems: NavigationItems[] = [
export const navigationItems: NavigationItems[] = [
{ text: "News", href: "/" },
{
hasMenu: true,
Expand Down
24 changes: 7 additions & 17 deletions src/layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
import React, { PropsWithChildren } from "react";
import Head from "./Head";
import SideBar from "./SideBar";
import { Flex, VStack, Text } from "@chakra-ui/react";
import { Flex, Text, useBreakpointValue } from "@chakra-ui/react";
import { TopBar } from "./TopBar";
import { useColors } from "@hook/useColors";
import { MobileTopBar } from "./TopBar/Mobile";

const Layout = ({ children }: PropsWithChildren) => {
const { bgColor } = useColors();
const TopBarComponent = useBreakpointValue({ base: MobileTopBar, lg: TopBar });

return (
<>
<Head title="News" />
<TopBar />
<Flex
w={{ lg: "1050px", base: "100%" }}
bgColor={bgColor}
mt="2em"
marginX={"auto"}
padding="1em"
flexDirection={{ base: "column", md: "row" }}
gap={{ base: "1em", md: 0 }}
>
<VStack flexGrow="1" marginRight={{ base: 0, md: "2em" }} order={{ base: 2, md: 1 }}>
{children}
</VStack>
<SideBar order={{ base: 1, md: 2 }} />
{TopBarComponent && <TopBarComponent />}
<Flex w={{ lg: "1050px", base: "100%" }} bgColor={bgColor} mt="2em" marginX={"auto"} padding="1em">
{children}
</Flex>
<Text userSelect="none" fontSize="sm" position="absolute" color="white" bottom="5" left="50%" transform="translateX(-50%)">
<Text userSelect="none" fontSize="sm" position="fixed" color="white" bottom="5" left="50%" transform="translateX(-50%)">
Copyright © 2021-2025 Shibaac
</Text>
</>
Expand Down

0 comments on commit 35af077

Please sign in to comment.