interface base

This commit is contained in:
Guz
2022-04-08 20:27:29 -03:00
parent 506532f2c1
commit d211b86e19
20 changed files with 3356 additions and 82 deletions

7
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"cSpell.words": [
"heroicons",
"Swipeable"
],
"typescript.tsdk": "node_modules\\typescript\\lib"
}

View File

@@ -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
View File

@@ -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
View 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));
}
})();

File diff suppressed because one or more lines are too long

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

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View 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;

View 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
View 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
View 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 &bull; {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>{' '}
&bull;{' '}
<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;

View 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;

View File

@@ -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
View 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;

View File

@@ -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 &rarr;</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 &rarr;</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 &rarr;</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 &rarr;</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>
);
};

View File

@@ -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;
}
}

View File

@@ -1,4 +1,5 @@
module.exports = {
darkMode: 'class',
content: [
'./src/pages/**/*.{js,ts,jsx,tsx}',
'./src/components/**/*.{js,ts,jsx,tsx}',

View File

@@ -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/*"],