interface base
This commit is contained in:
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"heroicons",
|
||||
"Swipeable"
|
||||
],
|
||||
"typescript.tsdk": "node_modules\\typescript\\lib"
|
||||
}
|
||||
@@ -20,9 +20,11 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": ">=7.0.0 <8.0.0",
|
||||
"@heroicons/react": "^1.0.6",
|
||||
"@prefresh/babel-plugin": "^0.4.0",
|
||||
"@types/node": "17.0.4",
|
||||
"@types/react": "17.0.38",
|
||||
"@use-gesture/react": "^10.2.11",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"cssnano": "^5.1.7",
|
||||
"eslint": "^8.12.0",
|
||||
@@ -32,6 +34,8 @@
|
||||
"postcss-import": "^14.1.0",
|
||||
"prettier": "^2.6.1",
|
||||
"prettier-plugin-tailwindcss": "^0.1.8",
|
||||
"react-spring": "^9.4.4",
|
||||
"react-swipeable": "^6.2.1",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"typescript": "4.5.4",
|
||||
"webpack": ">=5.9.0 <6.0.0"
|
||||
|
||||
169
pnpm-lock.yaml
generated
169
pnpm-lock.yaml
generated
@@ -2,9 +2,11 @@ lockfileVersion: 5.3
|
||||
|
||||
specifiers:
|
||||
'@babel/core': '>=7.0.0 <8.0.0'
|
||||
'@heroicons/react': ^1.0.6
|
||||
'@prefresh/babel-plugin': ^0.4.0
|
||||
'@types/node': 17.0.4
|
||||
'@types/react': 17.0.38
|
||||
'@use-gesture/react': ^10.2.11
|
||||
autoprefixer: ^10.4.4
|
||||
cssnano: ^5.1.7
|
||||
eslint: ^8.12.0
|
||||
@@ -18,7 +20,9 @@ specifiers:
|
||||
prettier-plugin-tailwindcss: ^0.1.8
|
||||
react: ^18.0.0
|
||||
react-dom: ^18.0.0
|
||||
react-spring: ^9.4.4
|
||||
react-ssr-prepass: ^1.5.0
|
||||
react-swipeable: ^6.2.1
|
||||
tailwindcss: ^3.0.23
|
||||
typescript: 4.5.4
|
||||
use-dark-mode: ^2.3.1
|
||||
@@ -34,9 +38,11 @@ dependencies:
|
||||
|
||||
devDependencies:
|
||||
'@babel/core': 7.17.8
|
||||
'@heroicons/react': 1.0.6_react@18.0.0
|
||||
'@prefresh/babel-plugin': 0.4.3
|
||||
'@types/node': 17.0.4
|
||||
'@types/react': 17.0.38
|
||||
'@use-gesture/react': 10.2.11_react@18.0.0
|
||||
autoprefixer: 10.4.4_postcss@8.4.12
|
||||
cssnano: 5.1.7_postcss@8.4.12
|
||||
eslint: 8.12.0
|
||||
@@ -46,6 +52,8 @@ devDependencies:
|
||||
postcss-import: 14.1.0_postcss@8.4.12
|
||||
prettier: 2.6.1
|
||||
prettier-plugin-tailwindcss: 0.1.8_prettier@2.6.1
|
||||
react-spring: 9.4.4_react-dom@18.0.0+react@18.0.0
|
||||
react-swipeable: 6.2.1_react@18.0.0
|
||||
tailwindcss: 3.0.23_autoprefixer@10.4.4
|
||||
typescript: 4.5.4
|
||||
webpack: 5.71.0
|
||||
@@ -1198,6 +1206,14 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@heroicons/react/1.0.6_react@18.0.0:
|
||||
resolution: {integrity: sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ==}
|
||||
peerDependencies:
|
||||
react: '>= 16'
|
||||
dependencies:
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@humanwhocodes/config-array/0.9.5:
|
||||
resolution: {integrity: sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==}
|
||||
engines: {node: '>=10.10.0'}
|
||||
@@ -1366,6 +1382,117 @@ packages:
|
||||
resolution: {integrity: sha512-fYAWbU1WDSLn108kKY4eDaaeUcnszFqXjgaGKYXNZ5NLulpRTpsrY+Sbfo9q8LDpWrBpqIgzjrwNnvglWI1xNQ==}
|
||||
dev: true
|
||||
|
||||
/@react-spring/animated/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-e9xnuBaUTD+NolKikUmrGWjX8AVCPyj1GcEgjgq9E+0sXKv46UY7cm2EmB6mUDTxWIDVKebARY++xT4nGDraBQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/core/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-llgb0ljFyjMB0JhWsaFHOi9XFT8n1jBMVs1IFY2ipIBerWIRWrgUmIpakLPHTa4c4jwqTaDSwX90s2a0iN7dxQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/rafz': 9.4.4
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/konva/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-ZHwsf4l/W5YzK8TwlvGXL9SYiHxxC6iEOAKStRs8WV6VuBvTFgIoGK5RNOTbsRC2N/spNWnN6JViz1PNbgrB+A==}
|
||||
peerDependencies:
|
||||
konva: '>=2.6'
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
react-konva: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/native/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-p0/JI59JVkgVjnoLvu+cpEgEkE0B3RDvzT1oNaCAx0ePaGQo4ICAS8PyOgPvN5IHUOy59CBLSMNnFyHV+IgaGQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
react-native: '>=0.58'
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/rafz/9.4.4:
|
||||
resolution: {integrity: sha512-5ki/sQ06Mdf8AuFstSt5zbNNicRT4LZogiJttDAww1ozhuvemafNWEHxhzcULgCPCDu2s7HsroaISV7+GQWrhw==}
|
||||
dev: true
|
||||
|
||||
/@react-spring/shared/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-ySVgScDZlhm/+Iy2smY9i/DDrShArY0j6zjTS/Re1lasKnhq8qigoGiAxe8xMPJNlCaj3uczCqHy3TY9bKRtfQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@react-spring/rafz': 9.4.4
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/three/9.4.4_react@18.0.0:
|
||||
resolution: {integrity: sha512-z77ohxg8zG0CcZJojzfoJTTrjSbIyefNz2RlId68/4IypnOs1p8kB2Q1p+wX4KyWORpLg8ivsPcjtwBjGwfDtg==}
|
||||
peerDependencies:
|
||||
'@react-three/fiber': '>=6.0'
|
||||
react: '>=16.11'
|
||||
three: '>=0.126'
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/types/9.4.4:
|
||||
resolution: {integrity: sha512-KpxKt/D//q/t/6FBcde/RE36LKp8PpWu7kFEMLwpzMGl9RpcexunmYOQJWwmJWtkQjgE1YRr7DzBMryz6La1cQ==}
|
||||
dev: true
|
||||
|
||||
/@react-spring/web/9.4.4_react-dom@18.0.0+react@18.0.0:
|
||||
resolution: {integrity: sha512-iJmOLdhcuizriUlu/xqBc5y8KaFts+UI+iC+GxyTwBtzxA9czKiSAZW2ESuhG8stafa3jncwjfTQQp84KN36cw==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
react-dom: 18.0.0_react@18.0.0
|
||||
dev: true
|
||||
|
||||
/@react-spring/zdog/9.4.4_react-dom@18.0.0+react@18.0.0:
|
||||
resolution: {integrity: sha512-qmD8zRcodbQKTAFVMdgW2pYIZP1KttDnz2S2JEc7kx8I8F5ljn9czgRl5c4w9HJ0dpO8VTfPq4sKa4tlUL23yg==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0
|
||||
react-zdog: '>=1.0'
|
||||
zdog: '>=1.0'
|
||||
dependencies:
|
||||
'@react-spring/animated': 9.4.4_react@18.0.0
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/shared': 9.4.4_react@18.0.0
|
||||
'@react-spring/types': 9.4.4
|
||||
react: 18.0.0
|
||||
react-dom: 18.0.0_react@18.0.0
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-babel/5.3.1_@babel+core@7.17.8+rollup@2.70.1:
|
||||
resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
@@ -1573,6 +1700,19 @@ packages:
|
||||
eslint-visitor-keys: 3.3.0
|
||||
dev: true
|
||||
|
||||
/@use-gesture/core/10.2.11:
|
||||
resolution: {integrity: sha512-5YeVrT9prf9UeaAO+2fIuiKdZ01uVBvVsjG79berGZPTHVkz01eFX2ODWJG05uQTqmRw6olz1J80yt6qcGPdvA==}
|
||||
dev: true
|
||||
|
||||
/@use-gesture/react/10.2.11_react@18.0.0:
|
||||
resolution: {integrity: sha512-yATjHv6ZNe9Jar1YtJvcb6KxwpcGGW/X8FEUY6xo2mDxHkP7dCsnhZZm7I+giGlrJKBMvpVBARsbUhwQP6v6nA==}
|
||||
peerDependencies:
|
||||
react: '>= 16.8.0'
|
||||
dependencies:
|
||||
'@use-gesture/core': 10.2.11
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/@use-it/event-listener/0.1.7_react@18.0.0:
|
||||
resolution: {integrity: sha512-hgfExDzUU9uTRTPDCpw2s9jWTxcxmpJya3fK5ADpf5VDpSy8WYwY/kh28XE0tUcbsljeP8wfan48QvAQTSSa3Q==}
|
||||
peerDependencies:
|
||||
@@ -4129,6 +4269,27 @@ packages:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
dev: true
|
||||
|
||||
/react-spring/9.4.4_react-dom@18.0.0+react@18.0.0:
|
||||
resolution: {integrity: sha512-VOqilh9DJBsS6Pf550YLhdReS3j9a2AQVh7NcsNtWoxTYIeuErWi6ym0++6bBhQp4yT5xvVvUDaJ8ez8vrFgaw==}
|
||||
dependencies:
|
||||
'@react-spring/core': 9.4.4_react@18.0.0
|
||||
'@react-spring/konva': 9.4.4_react@18.0.0
|
||||
'@react-spring/native': 9.4.4_react@18.0.0
|
||||
'@react-spring/three': 9.4.4_react@18.0.0
|
||||
'@react-spring/web': 9.4.4_react-dom@18.0.0+react@18.0.0
|
||||
'@react-spring/zdog': 9.4.4_react-dom@18.0.0+react@18.0.0
|
||||
transitivePeerDependencies:
|
||||
- '@react-three/fiber'
|
||||
- konva
|
||||
- react
|
||||
- react-dom
|
||||
- react-konva
|
||||
- react-native
|
||||
- react-zdog
|
||||
- three
|
||||
- zdog
|
||||
dev: true
|
||||
|
||||
/react-ssr-prepass/1.5.0_react@18.0.0:
|
||||
resolution: {integrity: sha512-yFNHrlVEReVYKsLI5lF05tZoHveA5pGzjFbFJY/3pOqqjGOmMmqx83N4hIjN2n6E1AOa+eQEUxs3CgRnPmT0RQ==}
|
||||
peerDependencies:
|
||||
@@ -4137,6 +4298,14 @@ packages:
|
||||
react: 18.0.0
|
||||
dev: false
|
||||
|
||||
/react-swipeable/6.2.1_react@18.0.0:
|
||||
resolution: {integrity: sha512-JpTj+tjJTDcIWtoMkab6zfwWD1T1tBzUyEfXsXnohnNkwA2dTuNS0gtN7HoxU1Qa+e3GDnfNYk2z7vwzfO4SoQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.3 || ^17
|
||||
dependencies:
|
||||
react: 18.0.0
|
||||
dev: true
|
||||
|
||||
/react/18.0.0:
|
||||
resolution: {integrity: sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
42
public/noflash.js
Normal file
42
public/noflash.js
Normal file
@@ -0,0 +1,42 @@
|
||||
// Insert this script in your index.html right after the <body> tag.
|
||||
// This will help to prevent a flash if dark mode is the default.
|
||||
|
||||
// MIT License https://github.com/donavon/use-dark-mode
|
||||
|
||||
(function() {
|
||||
// Change these if you use something different in your hook.
|
||||
var storageKey = 'darkMode';
|
||||
var classNameDark = 'dark-mode';
|
||||
var classNameLight = 'light-mode';
|
||||
|
||||
function setClassOnDocumentBody(darkMode) {
|
||||
document.body.classList.add(darkMode ? classNameDark : classNameLight);
|
||||
document.body.classList.remove(darkMode ? classNameLight : classNameDark);
|
||||
}
|
||||
|
||||
var preferDarkQuery = '(prefers-color-scheme: dark)';
|
||||
var mql = window.matchMedia(preferDarkQuery);
|
||||
var supportsColorSchemeQuery = mql.media === preferDarkQuery;
|
||||
var localStorageTheme = null;
|
||||
try {
|
||||
localStorageTheme = localStorage.getItem(storageKey);
|
||||
} catch (err) {}
|
||||
var localStorageExists = localStorageTheme !== null;
|
||||
if (localStorageExists) {
|
||||
localStorageTheme = JSON.parse(localStorageTheme);
|
||||
}
|
||||
|
||||
// Determine the source of truth
|
||||
if (localStorageExists) {
|
||||
// source of truth from localStorage
|
||||
setClassOnDocumentBody(localStorageTheme);
|
||||
} else if (supportsColorSchemeQuery) {
|
||||
// source of truth from system
|
||||
setClassOnDocumentBody(mql.matches);
|
||||
localStorage.setItem(storageKey, mql.matches);
|
||||
} else {
|
||||
// source of truth from document.body
|
||||
var isDarkMode = document.body.classList.contains(classNameDark);
|
||||
localStorage.setItem(storageKey, JSON.stringify(isDarkMode));
|
||||
}
|
||||
})();
|
||||
115
public/sw.js
115
public/sw.js
File diff suppressed because one or more lines are too long
1
public/sw.js.map
Normal file
1
public/sw.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2744
public/workbox-56d5d59b.js
Normal file
2744
public/workbox-56d5d59b.js
Normal file
File diff suppressed because it is too large
Load Diff
1
public/workbox-56d5d59b.js.map
Normal file
1
public/workbox-56d5d59b.js.map
Normal file
File diff suppressed because one or more lines are too long
23
src/components/button/socialButtons.jsx
Normal file
23
src/components/button/socialButtons.jsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import Head from 'next/head';
|
||||
|
||||
const SocialButtons = () => {
|
||||
|
||||
const socials = [];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<link href='https://unpkg.com/boxicons@2.1.2/css/boxicons.min.css' rel='stylesheet'/>
|
||||
</Head>
|
||||
<div id='socialButtons'>
|
||||
<button><a href=""><i className='bx bx-globe'></i></a></button>
|
||||
<button><a href=""><i className='bx bxl-github'></i></a></button>
|
||||
<button><a href=""><i className='bx bxl-twitter'></i></a></button>
|
||||
<button><a href=""><i className='bx bxl-mastodon'></i></a></button>
|
||||
<button><a href=""><i className='bx bxl-instagram-alt'></i></a></button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SocialButtons;
|
||||
44
src/components/button/themeButton.jsx
Normal file
44
src/components/button/themeButton.jsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import useDarkMode from 'use-dark-mode';
|
||||
import { useSpring, animated } from 'react-spring';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { SunIcon, MoonIcon } from '@heroicons/react/solid';
|
||||
|
||||
const ThemeButton = () => {
|
||||
const darkMode = useDarkMode(false, {
|
||||
classNameDark: 'dark',
|
||||
classNameLight: 'light',
|
||||
});
|
||||
|
||||
const anim = useSpring({
|
||||
from: { rotateZ: 0 },
|
||||
to: { rotateZ: darkMode.value ? 0 : 180 },
|
||||
});
|
||||
|
||||
const { scale } = useSpring({ scale: 0 });
|
||||
useEffect(() => {
|
||||
scale.start({ from: 0.8, to: 1 });
|
||||
});
|
||||
|
||||
return (
|
||||
<animated.button
|
||||
onClick={darkMode.toggle}
|
||||
className='min-h-8 min-w-8 grid place-content-center rounded-lg'
|
||||
style={{scale}}
|
||||
>
|
||||
<animated.div
|
||||
id='icons'
|
||||
className='grid place-content-center'
|
||||
style={anim}
|
||||
>
|
||||
{darkMode.value ? (
|
||||
<MoonIcon className='h-6 w-6 m-0 scale-90 fill-zinc-900 dark:fill-zinc-300' />
|
||||
) : (
|
||||
<SunIcon className='h-6 w-6 m-0 fill-zinc-900 dark:fill-zinc-300' />
|
||||
)}
|
||||
</animated.div>
|
||||
</animated.button>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeButton;
|
||||
11
src/components/footer.jsx
Normal file
11
src/components/footer.jsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import ThemeButton from '@components/button/themeButton';
|
||||
|
||||
const Si = () => {
|
||||
return (
|
||||
<footer className='fixed bottom-0 left-0 right-0 z-50 bg-zinc-100 dark:bg-zinc-900 w-screen h-max p-2'>
|
||||
<ThemeButton />
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
127
src/components/sideBar.jsx
Normal file
127
src/components/sideBar.jsx
Normal file
@@ -0,0 +1,127 @@
|
||||
import {
|
||||
MenuIcon,
|
||||
ArrowSmLeftIcon,
|
||||
CodeIcon,
|
||||
DocumentTextIcon,
|
||||
} from '@heroicons/react/solid';
|
||||
import { useSpring, animated } from 'react-spring';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useSwipeable } from 'react-swipeable';
|
||||
import useWinSize from '@hooks/useWinSize';
|
||||
|
||||
import ThemeButton from '@components/button/themeButton';
|
||||
import SocialButtons from '@components/button/socialButtons';
|
||||
|
||||
const SideBar = () => {
|
||||
const [opened, setOpen] = useState(false);
|
||||
|
||||
const { width } = useWinSize();
|
||||
|
||||
const [animSideBar, animButton, animBg, { scale }] = [
|
||||
useSpring({
|
||||
from: { x: 0 },
|
||||
to: { x: opened ? 0 : -360 },
|
||||
}),
|
||||
useSpring({
|
||||
from: { x: 0, rotateZ: 0 },
|
||||
to: {
|
||||
x: opened ? 0 : width < 640 ? -320 : -380,
|
||||
rotateZ: opened ? 0 : 180,
|
||||
},
|
||||
}),
|
||||
useSpring({
|
||||
from: { opacity: 0 },
|
||||
to: { opacity: opened ? 0.25 : 0 },
|
||||
}),
|
||||
useSpring({ scale: 0 }),
|
||||
];
|
||||
useEffect(() => {
|
||||
scale.start({ from: 0.8, to: 1 });
|
||||
});
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwipedRight: () => setOpen(true),
|
||||
onSwipedLeft: () => setOpen(false),
|
||||
});
|
||||
|
||||
return (
|
||||
<div className='fixed' {...handlers} style={{ touchAction: 'pan-y' }}>
|
||||
<section id='sidebar' className='flex'>
|
||||
<animated.footer
|
||||
style={animSideBar}
|
||||
className='w-80 sm:w-96 h-screen pl-2 rounded-r-3xl sm:rounded-none z-50 bg-zinc-100 dark:bg-zinc-900'
|
||||
>
|
||||
<div id='sidebar-main' className='pt-1'>
|
||||
<ThemeButton />
|
||||
</div>
|
||||
|
||||
<div id='side-bar-bottom' className='font-mono bottom-2 absolute'>
|
||||
|
||||
<SocialButtons />
|
||||
<p>By Guz013 • {new Date().getFullYear()}</p>
|
||||
|
||||
<div
|
||||
id='licenses'
|
||||
className='text-zinc-400 dark:text-zinc-600 text-xs'
|
||||
>
|
||||
<a
|
||||
className='hover:text-emerald-500 group'
|
||||
href='https://github.com/Guz013/Homework.app/blob/main/LICENSE'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
<CodeIcon className='w-4 h-4 mr-1 inline-block' />
|
||||
MIT License
|
||||
{/* <ExternalLinkIcon className='w-3 h-3 ml-0.5 inline-block opacity-40 transition-opacity group-hover:opacity-100' /> */}
|
||||
</a>{' '}
|
||||
•{' '}
|
||||
<a
|
||||
className='hover:text-violet-500 group'
|
||||
href='http://creativecommons.org/licenses/by-sa/4.0/'
|
||||
target='_blank'
|
||||
rel='noreferrer'
|
||||
>
|
||||
<DocumentTextIcon className='w-4 h-4 mr-1 inline-block' />
|
||||
CC-BY-SA 4.0
|
||||
{/* <ExternalLinkIcon className='w-3 h-3 ml-0.5 inline-block opacity-40 transition-opacity group-hover:opacity-100' /> */}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</animated.footer>
|
||||
|
||||
<animated.button
|
||||
id='side-bar-button'
|
||||
onClick={() => setOpen(!opened)}
|
||||
className='left-0 z-50 h-6 w-6 m-2'
|
||||
style={{ scale }}
|
||||
>
|
||||
<animated.div
|
||||
id='icons'
|
||||
className='grid place-content-center'
|
||||
style={animButton}
|
||||
>
|
||||
{opened ? (
|
||||
<ArrowSmLeftIcon className='h-6 w-6 m-0 fill-zinc-200 dark:fill-zinc-800' />
|
||||
) : (
|
||||
<>
|
||||
<MenuIcon className='h-6 w-6 m-0 fill-zinc-300 dark:fill-zinc-700 hidden sm:block' />
|
||||
<ArrowSmLeftIcon className='h-6 w-6 m-0 fill-zinc-300 dark:fill-zinc-700 block sm:hidden' />
|
||||
</>
|
||||
)}
|
||||
</animated.div>
|
||||
</animated.button>
|
||||
</section>
|
||||
|
||||
<animated.div
|
||||
onClick={() => {
|
||||
if (opened) setOpen(!opened);
|
||||
}}
|
||||
id='side-bar-background'
|
||||
className='fixed top-0 bg-[#000000] w-screen h-screen'
|
||||
style={animBg}
|
||||
></animated.div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SideBar;
|
||||
22
src/libs/hooks/useWinSize.ts
Normal file
22
src/libs/hooks/useWinSize.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
|
||||
const getSize = () => {
|
||||
const { innerWidth: width, innerHeight: height } = typeof window !== 'undefined' ? window : { innerWidth: 0, innerHeight: 0 };
|
||||
return { width, height };
|
||||
};
|
||||
|
||||
const useWinSize = () => {
|
||||
const [winSize, setWinSize] = useState(getSize());
|
||||
|
||||
useEffect(() => {
|
||||
function resizeHandler() {
|
||||
setWinSize(getSize());
|
||||
}
|
||||
window.addEventListener('resize', resizeHandler);
|
||||
return () => window.removeEventListener('resize', resizeHandler);
|
||||
}, [])
|
||||
|
||||
return winSize;
|
||||
}
|
||||
|
||||
export default useWinSize;
|
||||
@@ -1,7 +1,9 @@
|
||||
import Head from 'next/head';
|
||||
import '../styles/globals.css';
|
||||
import { AppProps } from 'next/app';
|
||||
|
||||
import Head from 'next/head';
|
||||
import SideBar from '@components/sideBar';
|
||||
|
||||
export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<>
|
||||
@@ -14,7 +16,7 @@ export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
/>
|
||||
<meta name='description' content='Description' />
|
||||
<meta name='keywords' content='Keywords' />
|
||||
<title>Next.js PWA Example</title>
|
||||
<title>Homework.app</title>
|
||||
|
||||
<link rel='manifest' href='/manifest.json' />
|
||||
<link
|
||||
@@ -32,7 +34,12 @@ export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
<link rel='apple-touch-icon' href='/apple-icon.png'></link>
|
||||
<meta name='theme-color' content='#317EFB' />
|
||||
</Head>
|
||||
<Component {...pageProps} />
|
||||
<div className='bg-zinc-100 text-zinc-900 dark:bg-zinc-900 dark:text-zinc-100 w-full h-full'>
|
||||
<SideBar/>
|
||||
<main className='z-10'>
|
||||
<Component {...pageProps} />
|
||||
</main>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
19
src/pages/_document.tsx
Normal file
19
src/pages/_document.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import Document, { Html, Head, Main, NextScript } from 'next/document';
|
||||
|
||||
class MyDocument extends Document {
|
||||
render() {
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
<body>
|
||||
{/* eslint-disable-next-line @next/next/no-sync-scripts */}
|
||||
<script src="noflash.js" />
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MyDocument;
|
||||
@@ -1,84 +1,9 @@
|
||||
import type { NextPage } from 'next';
|
||||
import Head from 'next/head';
|
||||
import Image from 'next/image';
|
||||
|
||||
const Home: NextPage = () => {
|
||||
return (
|
||||
<div className='flex min-h-screen flex-col items-center justify-center py-2'>
|
||||
<Head>
|
||||
<title>Create Next App</title>
|
||||
<link rel='icon' href='/favicon.ico' />
|
||||
</Head>
|
||||
|
||||
<main className='flex w-full flex-1 flex-col items-center justify-center px-20 text-center'>
|
||||
<h1 className='text-6xl font-bold'>
|
||||
Welcome to{' '}
|
||||
<a className='text-blue-600' href='https://nextjs.org'>
|
||||
Next.js!
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
<p className='mt-3 text-2xl'>
|
||||
Get started by editing{' '}
|
||||
<code className='rounded-md bg-gray-100 p-3 font-mono text-lg'>
|
||||
pages/index.tsx
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<div className='mt-6 flex max-w-4xl flex-wrap items-center justify-around sm:w-full'>
|
||||
<a
|
||||
href='https://nextjs.org/docs'
|
||||
className='mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600'
|
||||
>
|
||||
<h3 className='text-2xl font-bold'>Documentation →</h3>
|
||||
<p className='mt-4 text-xl'>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href='https://nextjs.org/learn'
|
||||
className='mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600'
|
||||
>
|
||||
<h3 className='text-2xl font-bold'>Learn →</h3>
|
||||
<p className='mt-4 text-xl'>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href='https://github.com/vercel/next.js/tree/canary/examples'
|
||||
className='mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600'
|
||||
>
|
||||
<h3 className='text-2xl font-bold'>Examples →</h3>
|
||||
<p className='mt-4 text-xl'>
|
||||
Discover and deploy boilerplate example Next.js projects.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href='https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app'
|
||||
className='mt-6 w-96 rounded-xl border p-6 text-left hover:text-blue-600 focus:text-blue-600'
|
||||
>
|
||||
<h3 className='text-2xl font-bold'>Deploy →</h3>
|
||||
<p className='mt-4 text-xl'>
|
||||
Instantly deploy your Next.js site to a public URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer className='flex h-24 w-full items-center justify-center border-t'>
|
||||
<a
|
||||
className='flex items-center justify-center gap-2'
|
||||
href='https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app'
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
>
|
||||
Powered by{' '}
|
||||
<Image src='/vercel.svg' alt='Vercel Logo' width={72} height={16} />
|
||||
</a>
|
||||
</footer>
|
||||
<h1>Hello World</h1>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
@import 'tailwindcss/base';
|
||||
@import 'tailwindcss/components';
|
||||
@import 'tailwindcss/utilities';
|
||||
|
||||
input,
|
||||
textarea,
|
||||
button,
|
||||
select,
|
||||
a {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
@layer components {
|
||||
a {
|
||||
@apply transition-colors ease-in-out duration-150;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
darkMode: 'class',
|
||||
content: [
|
||||
'./src/pages/**/*.{js,ts,jsx,tsx}',
|
||||
'./src/components/**/*.{js,ts,jsx,tsx}',
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@components": ["./src/components/*"],
|
||||
"@components/*": ["./src/components/*"],
|
||||
"@content/*": ["./src/content/*"],
|
||||
"@libs/*": ["./src/libs/*"],
|
||||
"@hooks/*": ["./src/libs/hooks/*"],
|
||||
|
||||
Reference in New Issue
Block a user