-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* build: added progress-bar dependency * feat: added useProgressBar hook * feat: enabled link navigation * build: updated path module * feat: added new logo * build: added required dependency * style: implemented theme system * feat: added poping component utiity * feat: implemented theme switcher * feat: added theme context * style: added dark theme
- Loading branch information
Showing
22 changed files
with
371 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,21 @@ | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import ForkAltIcon from '../icons/fork-alt'; | ||
import GithubAltIcon from '../icons/github-alt'; | ||
|
||
export default function LogoSection() { | ||
const { isDark } = useThemeContext(); | ||
return ( | ||
<section className="relative hidden lg:block"> | ||
<section className="relative hidden text-skin-base lg:block"> | ||
<div className="absolute bottom-4 right-16 "> | ||
<GithubAltIcon className="h-36 w-36" /> | ||
</div> | ||
<ForkAltIcon className="h-96 w-96 rotate-6 fill-transparent stroke-slate-900 stroke-1 " /> | ||
<ForkAltIcon | ||
className={`h-96 w-96 rotate-6 ${ | ||
isDark | ||
? `text-skin-base` | ||
: ` fill-transparent stroke-skin-base stroke-1 ` | ||
}`} | ||
/> | ||
</section> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { ComponentProps } from 'react'; | ||
|
||
type Props = ComponentProps<'svg'>; | ||
|
||
const GitOpenerIcon = (props: Props) => { | ||
return ( | ||
<svg | ||
role="img" | ||
viewBox="0 0 190 218" | ||
{...props} | ||
fill="currentColor" | ||
fillRule="evenodd" | ||
clipRule="evenodd" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<title>GitOpener</title> | ||
<path d="M189.067 54.69 95 .382.934 54.691v108.618L95 217.619l94.067-54.31V54.691ZM80.441 18.025l14.56-8.405 15.438 8.913.002 56.698c-.172 1.977-7.31 6.644-15.002 9.912-7.691-3.262-14.809-7.926-14.994-9.896l-.004-57.222Zm-6.464 3.732L8.934 59.31v99.382L95 208.381l86.067-49.69V59.309l-64.162-37.044.002 52.979c-.003 2.276-1.326 4.467-3.334 6.475-3.917 3.917-10.448 7.159-14.9 9.077v43.877c5.547 1.439 9.657 6.49 9.662 12.48l-.004 29.502c0 3.44-1.34 6.679-3.775 9.113a12.802 12.802 0 0 1-9.113 3.775 12.79 12.79 0 0 1-9.115-3.774 12.798 12.798 0 0 1-3.772-9.117l-.007-29.496c.005-5.781 4.235-10.935 9.658-12.448l.002-43.912c-6.734-2.898-18.23-8.834-18.228-15.55l-.004-53.49ZM95.534 140.73l.042-.001c3.477.073 6.29 2.93 6.294 6.431l-.003 29.496c-.003 3.429-2.997 6.423-6.424 6.423a6.37 6.37 0 0 1-4.543-1.881 6.379 6.379 0 0 1-1.88-4.545l-.008-29.49a6.402 6.402 0 0 1 1.888-4.549 6.398 6.398 0 0 1 4.408-1.885l.132.002.094-.001Z"></path> | ||
</svg> | ||
); | ||
}; | ||
|
||
export default GitOpenerIcon; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,25 @@ | ||
import Image from 'next/image'; | ||
import PBCLifeLogo from '~/images/pbclifelogo.png'; | ||
import Container from '../layouts/container'; | ||
import GitOpenerIcon from '@/components/icons/git-opener'; | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import { MoonIcon, SunIcon } from '@heroicons/react/24/solid'; | ||
import Container from '@layouts/container'; | ||
import Pop from '@utilities/pop'; | ||
import Themes from './theme'; | ||
|
||
export default function Navbar() { | ||
const { isDark } = useThemeContext(); | ||
return ( | ||
<Container> | ||
<Container className="z-10 flex items-center justify-between"> | ||
{/* logo */} | ||
<div className="flex items-center gap-x-2 py-4"> | ||
<Image | ||
src={PBCLifeLogo} | ||
alt="logo" | ||
placeholder="blur" | ||
width={48} | ||
height={48} | ||
className="h-10 w-10 rounded-full object-cover object-center" | ||
/> | ||
<span className="text-2xl font-bold tracking-tight">PBC LIFE</span> | ||
<div className="flex items-center gap-x-2 py-4 text-skin-base"> | ||
<GitOpenerIcon className="h-10 w-10 rotate-90 " /> | ||
<span className="text-2xl font-bold tracking-tight">Git Opener</span> | ||
</div> | ||
{/* social icons */} | ||
<div className=""></div> | ||
<div className=""> | ||
<Pop Icon={isDark ? MoonIcon : SunIcon} className="!z-50"> | ||
<Themes /> | ||
</Pop> | ||
</div> | ||
</Container> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useThemeContext } from '@/context/theme-context'; | ||
import { ComputerDesktopIcon } from '@heroicons/react/24/outline'; | ||
import PopButton from '@utilities/pop-button'; | ||
import { FC } from 'react'; | ||
|
||
const Themes: FC = () => { | ||
const { setIsThemeChanged } = useThemeContext(); | ||
|
||
function setDarkTheme() { | ||
window.localStorage.setItem('prefers-theme', 'dark'); | ||
setIsThemeChanged((cng) => cng + 1); | ||
} | ||
function setLightTheme() { | ||
window.localStorage.setItem('prefers-theme', 'light'); | ||
setIsThemeChanged((cng) => cng + 1); | ||
} | ||
function setSystemTheme() { | ||
window.localStorage.clear(); | ||
setIsThemeChanged((cng) => cng + 1); | ||
} | ||
|
||
return ( | ||
<div className=" w-screen max-w-[16rem] space-y-2 p-4"> | ||
<h2 className="text-2xl font-bold capitalize tracking-tight text-skin-base"> | ||
Choose Theme | ||
</h2> | ||
{/* two buttons */} | ||
<div className="flex w-full flex-wrap items-center justify-between"> | ||
<PopButton | ||
onClick={setLightTheme} | ||
className="w-[48%] rounded-md border border-skin-base bg-white px-6 py-3 capitalize text-neutral-800" | ||
> | ||
light | ||
</PopButton> | ||
<PopButton | ||
onClick={setDarkTheme} | ||
className="w-[48%] rounded-md border border-skin-base bg-neutral-900 px-6 py-3 capitalize text-white" | ||
> | ||
dark | ||
</PopButton> | ||
</div> | ||
{/* sync with system */} | ||
<PopButton | ||
onClick={setSystemTheme} | ||
className="flex items-center justify-center gap-x-2 rounded-full border border-skin-base bg-skin-base px-4 py-3 text-skin-base hover:bg-skin-shine" | ||
> | ||
<ComputerDesktopIcon className="h-5 w-5" /> Sync with System | ||
</PopButton> | ||
</div> | ||
); | ||
}; | ||
|
||
export default Themes; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
export default function Dot() { | ||
return ( | ||
<span className="h-1 w-1 flex-shrink-0 rounded-full bg-slate-800"></span> | ||
); | ||
return <span className="h-1 w-1 flex-shrink-0 rounded-full bg-accent"></span>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Menu } from '@headlessui/react'; | ||
import { FC, ReactNode } from 'react'; | ||
|
||
type Props = { | ||
children: ReactNode; | ||
className: string; | ||
onClick?: () => void; | ||
}; | ||
|
||
const PopButton: FC<Props> = ({ children, onClick, className }) => { | ||
return ( | ||
<Menu.Item | ||
as="button" | ||
onClick={onClick} | ||
className={`font-lexend rounded-full px-6 py-2 font-semibold capitalize outline-none ${ | ||
className || `` | ||
}`} | ||
> | ||
{children} | ||
</Menu.Item> | ||
); | ||
}; | ||
|
||
export default PopButton; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Menu, Transition } from '@headlessui/react'; | ||
import React, { ComponentProps, FC } from 'react'; | ||
|
||
type PopProps = ComponentProps<'div'> & { | ||
Icon: React.FC<React.ComponentProps<'svg'>>; | ||
}; | ||
|
||
const Pop: FC<PopProps> = ({ children, Icon, className }) => { | ||
return ( | ||
<Menu as={`div`} className={`relative z-0 ${className}`}> | ||
{/* icon */} | ||
<Menu.Button | ||
className={`group rounded-full border-none p-1 outline-none `} | ||
> | ||
{<Icon className={`h-8 w-8 text-skin-base group-hover:text-accent`} />} | ||
</Menu.Button> | ||
{/* panel */} | ||
<Transition | ||
enter="transition duration-500 ease-out" | ||
enterFrom="transform scale-95 opacity-0" | ||
enterTo="transform scale-100 opacity-100" | ||
leave="transition duration-300 ease-out" | ||
leaveFrom="transform scale-300 opacity-100" | ||
leaveTo="transform scale-95 opacity-0" | ||
> | ||
<Menu.Items | ||
className={`absolute top-4 -right-4 z-20 rounded-lg border border-skin-base bg-skin-base shadow-md `} | ||
> | ||
<div className="pointer-events-none absolute right-5 h-5 w-5 origin-top-right rotate-45 rounded bg-accent"></div> | ||
{children} | ||
</Menu.Items> | ||
</Transition> | ||
</Menu> | ||
); | ||
}; | ||
|
||
export default Pop; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,14 @@ | ||
import { HTMLAttributes } from 'react'; | ||
import { ComponentProps } from 'react'; | ||
|
||
type TypoCompType = HTMLAttributes<HTMLDivElement> & {}; | ||
type TypoCompType = ComponentProps<'div'>; | ||
|
||
export default function TypoComp({ className, ...props }: TypoCompType) { | ||
// todo: implement theme system | ||
return <div className={` prose max-w-2xl ${className || ``}`} {...props} />; | ||
return ( | ||
<div | ||
className={` prose max-w-2xl prose-headings:text-skin-base prose-p:font-medium prose-p:text-skin-muted ${ | ||
className || `` | ||
}`} | ||
{...props} | ||
/> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { | ||
ComponentProps, | ||
Dispatch, | ||
FC, | ||
SetStateAction, | ||
createContext, | ||
useContext, | ||
useEffect, | ||
useState, | ||
} from 'react'; | ||
|
||
interface ThemeStateType { | ||
setIsThemeChanged: Dispatch<SetStateAction<number>>; | ||
isDark: boolean; | ||
} | ||
|
||
const ThemeContext = createContext<ThemeStateType>({ | ||
isDark: false, | ||
setIsThemeChanged: () => {}, | ||
}); | ||
|
||
type ThemeProps = ComponentProps<'div'>; | ||
type Mode = 'light' | 'dark'; | ||
|
||
const ThemeProvider: FC<ThemeProps> = ({ children, className, ...props }) => { | ||
const [isDark, setIsDark] = useState<boolean>(false); | ||
const [isThemeChanged, setIsThemeChanged] = useState<number>(0); | ||
const [mode, setMode] = useState<Mode>(`light`); | ||
function mediaQueryListener(e: MediaQueryListEvent) { | ||
if (e.matches) { | ||
setMode(`dark`); | ||
setIsDark(true); | ||
} else { | ||
setMode(`light`); | ||
setIsDark(false); | ||
} | ||
} | ||
useEffect(() => { | ||
const darkModeMediaQuery = window.matchMedia(`prefers-color-scheme:dark`); | ||
|
||
const isTokenFound = window.localStorage.getItem('prefers-theme'); | ||
if (isTokenFound) { | ||
if (isTokenFound === 'dark') { | ||
setMode('dark'); | ||
setIsDark(true); | ||
} else { | ||
setMode('light'); | ||
setIsDark(false); | ||
} | ||
} else darkModeMediaQuery.addEventListener('change', mediaQueryListener); | ||
return () => | ||
darkModeMediaQuery.removeEventListener('change', mediaQueryListener); | ||
|
||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [isThemeChanged]); | ||
|
||
const value: ThemeStateType = { | ||
isDark, | ||
setIsThemeChanged, | ||
}; | ||
return ( | ||
<ThemeContext.Provider value={value}> | ||
<div className={`${mode} ${className || ``}`} {...props}> | ||
{children} | ||
</div> | ||
</ThemeContext.Provider> | ||
); | ||
}; | ||
|
||
export default ThemeProvider; | ||
|
||
export const useThemeContext = () => useContext(ThemeContext); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import ProgressBar from '@badrap/bar-of-progress'; | ||
import Router from 'next/router'; | ||
import { useEffect } from 'react'; | ||
|
||
export default function useProgressBar(color: string | undefined) { | ||
useEffect(() => { | ||
const progress = new ProgressBar({ | ||
className: 'bar-of-progress', | ||
color: color ?? `#16A34A`, | ||
delay: 80, | ||
size: 2, | ||
}); | ||
Router.events.on('routeChangeStart', () => progress.start()); | ||
Router.events.on('routeChangeComplete', () => progress.finish()); | ||
Router.events.on('routeChangeError', () => progress.finish()); | ||
}); | ||
} |
Oops, something went wrong.