⚒️ Create header & layout config.

This commit is contained in:
pheralb 2022-06-21 15:19:13 +01:00
parent 457a6c64f7
commit 4d366f8c25
11 changed files with 188 additions and 137 deletions

24
src/animations/show.tsx Normal file
View File

@ -0,0 +1,24 @@
import React, { FC } from "react";
import { motion } from "framer-motion";
type ShowProps = {
children: React.ReactNode;
delay?: number;
};
const Show = ({ children, delay }: ShowProps) => {
return (
<motion.div
initial={{ y: 10, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{
duration: 0.4,
delay: delay,
}}
>
{children}
</motion.div>
);
};
export default Show;

View File

@ -2,7 +2,7 @@ import React from "react";
import useSWR from "swr";
import { getCategorySvgs } from "@/services";
import CustomLink from "@/common/link";
import { Text } from "@chakra-ui/react";
import { Box, Text } from "@chakra-ui/react";
const Categories = () => {
const { data, error } = useSWR(getCategorySvgs);
@ -11,13 +11,13 @@ const Categories = () => {
if (!data) return <div>loading...</div>;
return (
<div>
<>
{data.map((category: string) => (
<CustomLink key={category} href={`/category/${category}`}>
<Text mb="2">{category}</Text>
</CustomLink>
<Box key={category} p="4" borderRadius="5px" borderWidth="1px">
<CustomLink href={`/category/${category}`}>{category}</CustomLink>
</Box>
))}
</div>
</>
);
};

View File

@ -0,0 +1,73 @@
import React from "react";
import {
Box,
Flex,
useColorModeValue,
HStack,
Button,
Container,
Heading,
} from "@chakra-ui/react";
import { Sticker } from "phosphor-react";
import Theme from "./theme";
import Tap from "@/animations/tap";
import Mobile from "./mobile";
import { Links } from "./links";
import CustomLink from "@/common/link";
import Categories from "./categories";
const Header = () => {
const bg = useColorModeValue("bg.light", "bg.dark");
return (
<>
<Box
position="sticky"
top="0"
bg={bg}
borderBottomWidth="1px"
w="full"
py={6}
shadow="sm"
>
<Container maxW={{ base: "full", md: "70%" }}>
<Flex alignItems="center" justifyContent="space-between" mx="auto">
<CustomLink href="/">
<Tap>
<HStack spacing={3} cursor="pointer">
<Sticker size={32} color="#4343e5" weight="bold" />
<Heading fontSize="19px">svgl</Heading>
</HStack>
</Tap>
</CustomLink>
<HStack display="flex" alignItems="center" spacing={1}>
<HStack
spacing={1}
mr={1}
display={{ base: "none", md: "inline-flex" }}
>
{Links.map((link) => (
<CustomLink
key={link.title}
href={link.slug}
external={link.external}
>
<Button variant="ghost">{link.title}</Button>
</CustomLink>
))}
<Theme />
</HStack>
<Box display={{ base: "inline-flex", md: "none" }}>
<Mobile />
</Box>
</HStack>
</Flex>
</Container>
</Box>
<HStack p="4" spacing={4} overflowY="hidden" bg={bg} borderBottomWidth="1px">
<Categories />
</HStack>
</>
);
};
export default Header;

View File

@ -0,0 +1,12 @@
export const Links = [
{
title: "Github",
slug: "https://github.com/pheralb/svgl",
external: true,
},
{
title: "Twitter",
slug: "https://twitter.com/pheralb_",
external: true,
},
];

View File

@ -0,0 +1,56 @@
import CustomLink from "@/common/link";
import {
Button,
CloseButton,
IconButton,
useColorModeValue,
useDisclosure,
VStack,
} from "@chakra-ui/react";
import { List } from "phosphor-react";
import { Links } from "./links";
const Mobile = () => {
const bg = useColorModeValue("bg.light", "bg.dark");
const mobileNav = useDisclosure();
return (
<>
<IconButton
display={{ base: "flex", md: "none" }}
aria-label="Open menu navbar"
variant="ghost"
icon={<List size={22} />}
onClick={mobileNav.onOpen}
/>
<VStack
pos="absolute"
top={0}
left={0}
right={0}
display={mobileNav.isOpen ? "flex" : "none"}
flexDirection="column"
p={2}
pb={4}
m={2}
bg={bg}
spacing={3}
rounded="sm"
shadow="sm"
>
<CloseButton aria-label="Close menu" onClick={mobileNav.onClose} />
{Links.map((link) => (
<CustomLink
key={link.title}
href={link.slug}
external={link.external}
>
<Button variant="ghost">{link.title}</Button>
</CustomLink>
))}
</VStack>
</>
);
};
export default Mobile;

View File

@ -2,19 +2,18 @@ import React from "react";
import { AnimatePresence, motion } from "framer-motion";
import { useColorMode, useColorModeValue } from "@chakra-ui/react";
import CustomIconBtn from "@/common/iconBtn";
import { IoMoonOutline, IoSunnyOutline } from "react-icons/io5";
import { Moon, Sun } from "phosphor-react";
const Theme = () => {
const { toggleColorMode } = useColorMode();
const key = useColorModeValue("light", "dark");
const icon = useColorModeValue(
<IoMoonOutline size={20} />,
<IoSunnyOutline size={20} />
<Moon size={22} />,
<Sun size={22} />
);
return (
<AnimatePresence exitBeforeEnter initial={false}>
<motion.div
style={{ display: "inline-block" }}
key={key}
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}

View File

@ -1,9 +1,15 @@
import React from "react";
import { LayoutProps } from "@/interfaces/components";
import Sidebar from "@/layout/sidebar";
import { Container } from "@chakra-ui/react";
import Header from "./header";
const Index = ({ children }: LayoutProps) => {
return <Sidebar>{children}</Sidebar>;
return (
<>
<Header />
<Container maxW="70%">{children}</Container>
</>
);
};
export default Index;

View File

@ -1,53 +0,0 @@
import React from "react";
import { SidebarContentProps } from "@/interfaces/components";
import {
Box,
Divider,
Flex,
Heading,
useColorModeValue,
} from "@chakra-ui/react";
import { HandGrabbing } from "phosphor-react";
import CustomLink from "@/common/link";
import Categories from "./categories";
const Content = (props: SidebarContentProps) => {
const bg = useColorModeValue("bg.light", "bg.dark");
return (
<Box
as="nav"
pos="fixed"
left="0"
zIndex="sticky"
h="full"
pb="10"
overflowX="hidden"
overflowY="auto"
w="240px"
bg={bg}
{...props}
>
<Flex
as="nav"
mt="5"
ml="7"
mr="6"
direction="column"
aria-label="Main Sidenav"
>
<CustomLink href="/">
<HandGrabbing size={50} />
</CustomLink>
<Box mt="6" ml="1">
<Divider mb="4" />
<Heading fontSize="16px" mt="3" mb="3">
Categories
</Heading>
<Categories />
</Box>
</Flex>
</Box>
);
};
export default Content;

View File

@ -1,59 +0,0 @@
import { SidebarContentProps } from "@/interfaces/components";
import {
Box,
Drawer,
DrawerContent,
DrawerOverlay,
Flex,
IconButton,
useColorModeValue,
useDisclosure,
} from "@chakra-ui/react";
import React from "react";
import { IoApps } from "react-icons/io5";
import Content from "./content";
const Index = ({ children }: SidebarContentProps) => {
const sidebar = useDisclosure();
return (
<Box as="section">
<Content display={{ base: "none", md: "unset" }} />
<Drawer
isOpen={sidebar.isOpen}
onClose={sidebar.onClose}
placement="left"
>
<DrawerOverlay />
<DrawerContent>
<Content w="full" borderRight="none" />
</DrawerContent>
</Drawer>
<Box ml={{ base: 0, md: "90px" }} transition=".3s ease">
<Flex
as="header"
display={{ base: "inline-flex", md: "none" }}
align="center"
justify="space-between"
w="full"
px="4"
borderBottomWidth="1px"
borderColor="blackAlpha.300"
h="14"
>
<IconButton
aria-label="Menu"
onClick={sidebar.onOpen}
icon={<IoApps />}
size="sm"
/>
</Flex>
<Box as="main" p="4">
{children}
</Box>
</Box>
</Box>
);
};
export default Index;

View File

@ -1,5 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next";
import db from "data/svgs";
import type { NextApiRequest, NextApiResponse } from "next";
import { SvgData } from "@/interfaces/svgData";
export default function handler(

View File

@ -13,18 +13,11 @@ const Home: NextPage = () => {
if (!data) return <div>loading...</div>;
return (
<Container maxW="85%">
<Grid>
{data.map((svg: SvgData) => (
<SVGCard
key={svg.id}
title={svg.title}
url={svg.href}
svg={svg.href}
/>
))}
</Grid>
</Container>
<Grid>
{data.map((svg: SvgData) => (
<SVGCard key={svg.id} title={svg.title} url={svg.href} svg={svg.href} />
))}
</Grid>
);
};