changed class componenets to functional components and cleaned code

This commit is contained in:
Kim, Jimin 2021-12-14 22:43:30 +09:00
parent c631c16711
commit 49fd2b2900
8 changed files with 200 additions and 219 deletions

View file

@ -1,6 +1,7 @@
import styled from "styled-components"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faGithub } from "@fortawesome/free-brands-svg-icons" import { faGithub } from "@fortawesome/free-brands-svg-icons"
import styled from "styled-components"
import theming from "../theming" import theming from "../theming"

View file

@ -1,17 +1,17 @@
import React from "react" import styled from "styled-components"
import { Link } from "react-router-dom"
import ReactTooltip from "react-tooltip"
import { isMobile } from "react-device-detect"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faSearch } from "@fortawesome/free-solid-svg-icons" import { faSearch } from "@fortawesome/free-solid-svg-icons"
import styled from "styled-components"
import ReactTooltip from "react-tooltip" import ThemeToggleButton from "./ThemeToggleButton"
import { Link } from "react-router-dom" import Sidebar from "./Sidebar"
import { isMobile } from "react-device-detect"
import theming from "../theming" import theming from "../theming"
import NavbarData from "../data/NavbarData" import NavbarData from "../data/NavbarData"
import Sidebar from "./Sidebar"
import ThemeToggleButton from "./ThemeToggleButton"
const StyledNav = styled.nav` const StyledNav = styled.nav`
/* set z index to arbitrarily high value to prevent other components from drawing over the navbar */ /* set z index to arbitrarily high value to prevent other components from drawing over the navbar */
z-index: 9999; z-index: 9999;
@ -65,44 +65,44 @@ const StyledLink = styled(Link)`
margin: 0 0.2rem 0 0.2rem; margin: 0 0.2rem 0 0.2rem;
` `
export default class Navbar extends React.Component { const Navbar = () => {
render() { return (
return ( <StyledNav>
<StyledNav> <StyledContainer>
<StyledContainer> <Link to="/">
<Link to="/"> <StyledImg
<StyledImg src={process.env.PUBLIC_URL + "/icon/icon_circle.svg"}
src={ />
process.env.PUBLIC_URL + "/icon/icon_circle.svg" </Link>
}
/>
</Link>
<StyledNavLinks>
{NavbarData.map((item, index) => (
<StyledLink key={index} to={item.path}>
{item.title}
</StyledLink>
))}
</StyledNavLinks>
<ThemeToggleButton /> <StyledNavLinks>
{NavbarData.map((item, index) => (
<StyledLink key={index} to={item.path}>
{item.title}
</StyledLink>
))}
</StyledNavLinks>
<StyledLink <ThemeToggleButton />
data-tip
data-for="search"
to={`${process.env.PUBLIC_URL}/search`}
>
<FontAwesomeIcon icon={faSearch} />
</StyledLink>
{!isMobile && (
<ReactTooltip id="search" type="dark" effect="solid">
<span>Search</span>
</ReactTooltip>
)}
<Sidebar /> <StyledLink
</StyledContainer> data-tip
</StyledNav> data-for="search"
) to={`${process.env.PUBLIC_URL}/search`}
} >
<FontAwesomeIcon icon={faSearch} />
</StyledLink>
{!isMobile && (
<ReactTooltip id="search" type="dark" effect="solid">
<span>Search</span>
</ReactTooltip>
)}
<Sidebar />
</StyledContainer>
</StyledNav>
)
} }
export default Navbar

View file

@ -1,10 +1,8 @@
import styled from "styled-components" import styled from "styled-components"
import { useNavigate } from "react-router-dom" import { useNavigate } from "react-router-dom"
import theming from "../theming" import { Post } from "../types/typings"
import Tag from "../components/Tag"
import TagList from "../components/TagList"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { import {
faBook, faBook,
@ -12,7 +10,10 @@ import {
faHourglass, faHourglass,
} from "@fortawesome/free-solid-svg-icons" } from "@fortawesome/free-solid-svg-icons"
import { Post } from "../types/typings" import Tag from "../components/Tag"
import TagList from "../components/TagList"
import theming from "../theming"
const StyledPostCard = styled.div` const StyledPostCard = styled.div`
box-shadow: 0 4px 10px rgb(0 0 0 / 10%); box-shadow: 0 4px 10px rgb(0 0 0 / 10%);
@ -60,11 +61,12 @@ const StyledPostCardContent = styled.div`
interface _PostDateBase extends Post { interface _PostDateBase extends Post {
url: string url: string
} }
interface PostCardProps {
interface Props {
postData: _PostDateBase postData: _PostDateBase
} }
export default function PostCard(props: PostCardProps) { const PostCard = (props: Props) => {
const navigate = useNavigate() const navigate = useNavigate()
return ( return (
@ -120,3 +122,5 @@ export default function PostCard(props: PostCardProps) {
</StyledPostCard> </StyledPostCard>
) )
} }
export default PostCard

View file

@ -1,15 +1,16 @@
import React from "react" import { useState } from "react"
import styled, { css } from "styled-components" import styled, { css } from "styled-components"
import ReactTooltip from "react-tooltip" import ReactTooltip from "react-tooltip"
import { isMobile } from "react-device-detect" import { isMobile } from "react-device-detect"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faEllipsisV, faTimes } from "@fortawesome/free-solid-svg-icons" import { faEllipsisV, faTimes } from "@fortawesome/free-solid-svg-icons"
import theming from "../theming"
import NavbarData, { Item } from "../data/NavbarData"
import SubMenu from "./SubMenu" import SubMenu from "./SubMenu"
import NavbarData, { Item } from "../data/NavbarData"
import theming from "../theming"
const CommonSidebarToggleButtonStyle = css` const CommonSidebarToggleButtonStyle = css`
${theming.styles.navbarButtonStyle} ${theming.styles.navbarButtonStyle}
width: 1.5rem; width: 1.5rem;
@ -33,7 +34,7 @@ const StyledToggleSidebarButton2 = styled.div`
font-size: 1.1rem; font-size: 1.1rem;
` `
const StyledOverlay = styled.div<SidebarState>` const StyledOverlay = styled.div<{ isSidebarOpen: boolean }>`
display: ${(props) => (props.isSidebarOpen ? "block" : "none")}; display: ${(props) => (props.isSidebarOpen ? "block" : "none")};
position: fixed; position: fixed;
top: 0; top: 0;
@ -49,7 +50,7 @@ const StyledOverlay = styled.div<SidebarState>`
} }
` `
const SidebarNav = styled.nav<SidebarState>` const SidebarNav = styled.nav<{ isSidebarOpen: boolean }>`
width: 250px; width: 250px;
height: 100vh; height: 100vh;
display: flex; display: flex;
@ -77,63 +78,47 @@ const SidebarWrap = styled.div`
width: 100%; width: 100%;
` `
interface SidebarProps {} const Sidebar = () => {
interface SidebarState { const [isSidebarOpen, setSidebarOpen] = useState(false)
isSidebarOpen: boolean
}
export default class Sidebar extends React.Component<
SidebarProps,
SidebarState
> {
constructor(props: SidebarProps) {
super(props)
this.state = {
isSidebarOpen: false,
}
}
// for some reason this.setState only works if this is an arrow function // for some reason this.setState only works if this is an arrow function
toggleSidebar = () => { const toggleSidebar = () => {
this.setState({ isSidebarOpen: !this.state.isSidebarOpen }) setSidebarOpen((prev) => !prev)
document.body.style.overflow = this.state.isSidebarOpen ? "" : "hidden" document.body.style.overflow = isSidebarOpen ? "" : "hidden"
} }
render() { return (
return ( <>
<> <StyledOverlay
<StyledOverlay isSidebarOpen={isSidebarOpen}
isSidebarOpen={this.state.isSidebarOpen} onClick={toggleSidebar}
onClick={this.toggleSidebar} />
/>
<StyledToggleSidebarButton <StyledToggleSidebarButton
data-tip data-tip
data-for="sidebar" data-for="sidebar"
onClick={this.toggleSidebar} onClick={toggleSidebar}
> >
<FontAwesomeIcon icon={faEllipsisV}></FontAwesomeIcon> <FontAwesomeIcon icon={faEllipsisV}></FontAwesomeIcon>
{!isMobile && ( {!isMobile && (
<ReactTooltip id="sidebar" type="dark" effect="solid"> <ReactTooltip id="sidebar" type="dark" effect="solid">
<span>open sidebar</span> <span>open sidebar</span>
</ReactTooltip> </ReactTooltip>
)} )}
</StyledToggleSidebarButton> </StyledToggleSidebarButton>
<SidebarNav isSidebarOpen={this.state.isSidebarOpen}> <SidebarNav isSidebarOpen={isSidebarOpen}>
<SidebarWrap> <SidebarWrap>
<StyledToggleSidebarButton2 <StyledToggleSidebarButton2 onClick={toggleSidebar}>
onClick={this.toggleSidebar} <FontAwesomeIcon icon={faTimes}></FontAwesomeIcon> Close
> </StyledToggleSidebarButton2>
<FontAwesomeIcon icon={faTimes}></FontAwesomeIcon>{" "} {NavbarData.map((item: Item, index) => {
Close return <SubMenu item={item} key={index} />
</StyledToggleSidebarButton2> })}
{NavbarData.map((item: Item, index) => { </SidebarWrap>
return <SubMenu item={item} key={index} /> </SidebarNav>
})} </>
</SidebarWrap> )
</SidebarNav>
</>
)
}
} }
export default Sidebar

View file

@ -1,9 +1,13 @@
import React from "react" /**
* @file Submenu item for sidebar
*/
import { useState } from "react"
import { Link } from "react-router-dom" import { Link } from "react-router-dom"
import styled from "styled-components" import styled from "styled-components"
import theming from "../theming"
import { Item } from "../data/NavbarData" import { Item } from "../data/NavbarData"
import theming from "../theming"
const SidebarLink = styled(Link)` const SidebarLink = styled(Link)`
${theming.styles.navbarButtonStyle}; ${theming.styles.navbarButtonStyle};
@ -38,60 +42,47 @@ const DropdownLink = styled(Link)`
} }
` `
interface SubMenuProps { interface Props {
item: Item item: Item
} }
interface SubMenuState { const SubMenu = (props: Props) => {
isSubNavOpen: boolean const [isSubNavOpen, setSubNavOpen] = useState(false)
}
export default class SubMenu extends React.Component< const handleSidebarLinkClick = () => {
SubMenuProps, if (props.item.subNav) setSubNavOpen((prev) => !prev)
SubMenuState
> {
constructor(props: SubMenuProps) {
super(props)
this.state = {
isSubNavOpen: false,
}
} }
showSubNav = () => this.setState({ isSubNavOpen: !this.state.isSubNavOpen }) return (
<>
<SidebarLink to={props.item.path} onClick={handleSidebarLinkClick}>
<div>
{props.item.icon}
<SidebarLabel>{props.item.title}</SidebarLabel>
</div>
<div>
{props.item.subNav && isSubNavOpen
? props.item.iconOpened
: props.item.subNav
? props.item.iconClosed
: null}
</div>
</SidebarLink>
render() { {/* not used as of the moment */}
return ( {isSubNavOpen && // check if subNav is open
<> props.item.subNav && // check if subNav exists in that item
<SidebarLink props.item.subNav.map((item, index) => {
to={this.props.item.path} // shows all items in subNav
onClick={this.props.item.subNav && this.showSubNav} return (
> <DropdownLink to={item.path} key={index}>
<div> {item.icon}
{this.props.item.icon} <SidebarLabel>{item.title}</SidebarLabel>
<SidebarLabel>{this.props.item.title}</SidebarLabel> </DropdownLink>
</div> )
<div> })}
{this.props.item.subNav && this.state.isSubNavOpen </>
? this.props.item.iconOpened )
: this.props.item.subNav
? this.props.item.iconClosed
: null}
</div>
</SidebarLink>
{/* not used as of the moment */}
{this.state.isSubNavOpen && // check if subNav is open
this.props.item.subNav && // check if subNav exists in that item
this.props.item.subNav.map((item, index) => {
// shows all items in subNav
return (
<DropdownLink to={item.path} key={index}>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</DropdownLink>
)
})}
</>
)
}
} }
export default SubMenu

View file

@ -1,9 +1,10 @@
import React from "react" import React from "react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import styled from "styled-components" import styled from "styled-components"
import theming from "../theming"
import { faTag } from "@fortawesome/free-solid-svg-icons" import { faTag } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import theming from "../theming"
const StyledTag = styled.div` const StyledTag = styled.div`
text-align: center; text-align: center;
@ -15,17 +16,17 @@ const StyledTag = styled.div`
color: white; color: white;
` `
interface TagProps { interface Props {
text: string text: string
onClick?: (event: React.MouseEvent<never>) => void onClick?: (event: React.MouseEvent<never>) => void
} }
export default class Tag extends React.Component<TagProps> { const Tag = (props: Props) => {
render() { return (
return ( <StyledTag onClick={props.onClick || undefined}>
<StyledTag onClick={this.props.onClick || undefined}> <FontAwesomeIcon icon={faTag} /> &nbsp;{props.text}
<FontAwesomeIcon icon={faTag} /> &nbsp;{this.props.text} </StyledTag>
</StyledTag> )
)
}
} }
export default Tag

View file

@ -1,4 +1,4 @@
import React from "react" import { ReactNode } from "react"
import styled from "styled-components" import styled from "styled-components"
const StyledTagList = styled.div<{ direction: string }>` const StyledTagList = styled.div<{ direction: string }>`
@ -10,16 +10,17 @@ const StyledTagList = styled.div<{ direction: string }>`
justify-content: ${({ direction }) => direction}; justify-content: ${({ direction }) => direction};
` `
interface TagListProps { interface Props {
direction?: string direction?: string
children?: ReactNode | undefined
} }
export default class TagList extends React.Component<TagListProps> { const TagList = (props: Props) => {
render() { return (
return ( <StyledTagList direction={props.direction || "center"}>
<StyledTagList direction={this.props.direction || "center"}> {props.children}
{this.props.children} </StyledTagList>
</StyledTagList> )
)
}
} }
export default TagList

View file

@ -1,9 +1,9 @@
import React from "react" import styled, { ThemeConsumer } from "styled-components"
import { isMobile } from "react-device-detect"
import ReactTooltip from "react-tooltip"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faMoon, faSun } from "@fortawesome/free-solid-svg-icons" import { faMoon, faSun } from "@fortawesome/free-solid-svg-icons"
import styled, { ThemeConsumer } from "styled-components"
import ReactTooltip from "react-tooltip"
import { isMobile } from "react-device-detect"
import theming from "../theming" import theming from "../theming"
@ -16,37 +16,35 @@ const StyledThemeButton = styled.div`
})}; })};
` `
export default class Navbar extends React.Component { const Navbar = () => {
render() { return (
return ( <ThemeConsumer>
<ThemeConsumer> {({ currentTheme, setTheme }) => (
{({ currentTheme, setTheme }) => ( <>
<> <StyledThemeButton
<StyledThemeButton data-tip
data-tip data-for="theme"
data-for="theme" className="right"
className="right" onClick={() =>
onClick={() => setTheme(currentTheme === "dark" ? "light" : "dark")
setTheme( }
currentTheme === "dark" ? "light" : "dark" >
) {currentTheme == "dark" && (
} <FontAwesomeIcon icon={faMoon} />
>
{currentTheme == "dark" && (
<FontAwesomeIcon icon={faMoon} />
)}
{currentTheme == "light" && (
<FontAwesomeIcon icon={faSun} />
)}
</StyledThemeButton>
{!isMobile && (
<ReactTooltip id="theme" type="dark" effect="solid">
<span>Using {currentTheme} theme</span>
</ReactTooltip>
)} )}
</> {currentTheme == "light" && (
)} <FontAwesomeIcon icon={faSun} />
</ThemeConsumer> )}
) </StyledThemeButton>
} {!isMobile && (
<ReactTooltip id="theme" type="dark" effect="solid">
<span>Using {currentTheme} theme</span>
</ReactTooltip>
)}
</>
)}
</ThemeConsumer>
)
} }
export default Navbar