Firist commit

This commit is contained in:
2024-03-29 12:52:08 +00:00
commit 5293669f40
27 changed files with 6143 additions and 0 deletions

6
.env Normal file
View File

@@ -0,0 +1,6 @@
NEXTAUTH_SECRET=v7cl92wK4Qdrdr1Jrr0JVl1qna4rIxFsY+T7X+8w0wM=
NEXTAUTH_URL=https://3000.vscode.home.joemonk.co.uk
NEXT_COGNITO_CLIENT_ID=6lt3p9f2puu583pso84b9b1asu
NEXT_COGNITO_CLIENT_SECRET=7mv13jembkcimd2qavlsqci5kgtihqhcvned5r54b46qpusl8o4
NEXT_COGNITO_ISSUER=https://cognito-idp.eu-west-2.amazonaws.com/eu-west-2_qwrNOlWgg

68
.eslintrc.json Normal file
View File

@@ -0,0 +1,68 @@
{
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": [
"@typescript-eslint"
],
"extends": [
"plugin:import/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@typescript-eslint/recommended-requiring-type-checking",
"next/core-web-vitals"
],
"rules": {
"semi": [
"error",
"always"
],
"arrow-spacing": [
"error",
{
"before": true,
"after": true
}
],
"block-spacing": [
"error"
],
"semi-spacing": [
"error"
],
"computed-property-spacing": [
"error"
],
"comma-spacing": [
"error"
],
"keyword-spacing": [
"error"
],
"func-call-spacing": [
"error"
],
"template-curly-spacing": [
"error"
],
"array-bracket-spacing": [
"error"
],
"@typescript-eslint/explicit-function-return-type": [
"error"
],
"indent": [
"error",
2
],
"@typescript-eslint/no-inferrable-types": [
"off"
],
"@typescript-eslint/no-empty-function": [
"off"
],
"jsx-a11y/alt-text": [
"off"
]
}
}

36
.gitignore vendored Normal file
View File

@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env*.local
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts

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

@@ -0,0 +1,3 @@
{
"editor.tabSize": 2,
}

63
Dockerfile Normal file
View File

@@ -0,0 +1,63 @@
FROM node:18-alpine AS base
# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
else echo "Lockfile not found." && exit 1; \
fi
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED 1
RUN \
if [ -f yarn.lock ]; then yarn run build; \
elif [ -f package-lock.json ]; then npm run build; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
else echo "Lockfile not found." && exit 1; \
fi
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD HOSTNAME="0.0.0.0" node server.js

36
README.md Normal file
View File

@@ -0,0 +1,36 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.

8
next.config.mjs Normal file
View File

@@ -0,0 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
swcMinify: true,
reactStrictMode: true,
output: "standalone"
};
export default nextConfig;

5532
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

37
package.json Normal file
View File

@@ -0,0 +1,37 @@
{
"name": "next-portfolio",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"build:analyse": "ANALYZE=true npm run build",
"start": "next start",
"lint": "next lint",
"lint:fix": "next lint -- --fix"
},
"dependencies": {
"@headlessui/react": "^1.7.18",
"@heroicons/react": "^2.1.3",
"@next/bundle-analyzer": "^14.1.4",
"@tailwindcss/typography": "^0.5.12",
"@types/node": "^20.11.30",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.2.23",
"@typescript-eslint/eslint-plugin": "^7.4.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-next": "14.1.4",
"framer-motion": "^11.0.23",
"next": "14.1.4",
"next-auth": "^4.24.7",
"postcss": "^8.4.38",
"react": "^18.2.0",
"react-datocms": "^5.0.3",
"react-dom": "^18.2.0",
"server-only": "^0.0.1",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.3"
}
}

6
postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

1
public/next.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
public/vercel.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>

After

Width:  |  Height:  |  Size: 629 B

View File

@@ -0,0 +1,7 @@
import NextAuth from "next-auth";
import { authConfig } from "@/lib/auth";
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const handler = NextAuth(authConfig);
export { handler as GET, handler as POST };

View File

@@ -0,0 +1,15 @@
import { auth } from '@/lib/auth';
import { revalidateTag } from 'next/cache';
import { draftMode } from 'next/headers';
import { redirect } from 'next/navigation';
export async function GET(): Promise<Response> {
const session = await auth();
if (session) {
draftMode().enable();
revalidateTag('datocms');
} else if (draftMode().isEnabled) {
draftMode().disable();
}
redirect('/');
}

View File

@@ -0,0 +1,5 @@
import { NextResponse } from 'next/server';
export function GET(): Response {
return NextResponse.json({ status: 200 }, { status: 200 });
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

10
src/app/globals.css Normal file
View File

@@ -0,0 +1,10 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
.text-balance {
text-wrap: balance;
}
}

34
src/app/layout.tsx Normal file
View File

@@ -0,0 +1,34 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import NavBar from '@/components/navbar';
import Footer from '@/components/footer';
const inter = Inter({
subsets: ['latin'],
variable: '--font-inter',
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>): JSX.Element {
return (
<html className={`${inter.variable} font-sans`} lang="en">
<body className="min-h-screen flex flex-col bg-dracula-bg">
<NavBar/>
<main className="px-6 py-4 w-full mx-auto flex-1 align-middle lg:max-w-5xl">
{children}
</main>
<Footer/>
</body>
</html>
);
}

31
src/app/page.tsx Normal file
View File

@@ -0,0 +1,31 @@
export default function Home(): JSX.Element {
const len = Array.from({length: 0});
return (
<div>
{len.map(() =>
<p className='prose prose-invert max-w-none'>
Excepteur aliquip voluptate minim quis velit id. Do quis incididunt tempor deserunt consectetur est velit reprehenderit pariatur aliquip mollit elit magna. Do occaecat ex labore tempor laboris ut. Sit aliquip ex consequat in adipisicing duis tempor. Esse adipisicing aliqua exercitation ullamco do. Do nostrud ullamco tempor amet cillum ex Lorem irure culpa proident.
Consequat dolor officia velit non pariatur ea quis duis tempor. Nisi adipisicing elit exercitation tempor aute deserunt consectetur. Labore proident excepteur enim minim ullamco labore. Ad ea minim in ut.
Minim laborum sit laborum commodo esse sint veniam deserunt. Nisi voluptate cupidatat consequat quis aute ex ut nisi enim aliquip consequat. Culpa dolore labore anim ut. Veniam pariatur velit nulla sit culpa.
Dolor incididunt ut consequat nostrud nostrud sit quis nostrud aliquip. Do officia voluptate qui qui officia quis in in laborum reprehenderit adipisicing. Exercitation ex proident cupidatat ut culpa. Ullamco officia deserunt esse commodo sint est ut labore tempor. Pariatur commodo proident voluptate excepteur ipsum velit consequat officia cillum eu nulla tempor duis. Consequat deserunt tempor nostrud quis officia aliqua mollit ea duis veniam.
Consectetur sint est ad voluptate quis nisi adipisicing cillum in. Non nostrud et proident nisi eu ullamco eiusmod et excepteur esse exercitation adipisicing exercitation ex. Dolore sit esse voluptate aliquip non eiusmod ex proident adipisicing voluptate aute sit culpa. Consequat non labore aute consectetur magna. Irure anim tempor aliquip mollit do nisi reprehenderit nulla cupidatat amet.
Ea sunt aliqua proident sit labore quis eiusmod velit adipisicing cillum aute magna. Incididunt ullamco labore cupidatat do veniam pariatur mollit duis dolor velit ut enim. Occaecat voluptate culpa cupidatat nulla veniam dolore quis consequat ea. Cupidatat non commodo occaecat incididunt nostrud eu aute nostrud pariatur velit ullamco aliqua et. Velit culpa qui ipsum ex. Eu irure veniam excepteur eu. Magna Lorem do elit non.
Ut fugiat eiusmod culpa ipsum enim do. In ipsum aute mollit nostrud incididunt laborum do voluptate amet tempor labore aute anim. Ea eiusmod consequat occaecat qui Lorem non esse.
Officia aute et aliqua laborum reprehenderit. Lorem excepteur deserunt dolor eu pariatur consequat veniam. Labore sint fugiat labore aliquip cupidatat cillum adipisicing ullamco eu amet consequat. Reprehenderit et est magna nostrud.
Amet mollit Lorem enim officia voluptate ipsum reprehenderit commodo aliqua adipisicing id culpa deserunt. Consequat nulla tempor tempor nisi deserunt nulla magna dolor duis id nostrud laborum dolor. Exercitation aute anim in aliqua sunt ea laborum anim dolore veniam pariatur. Voluptate enim tempor officia minim excepteur fugiat ullamco.
Do labore Lorem in officia incididunt velit id laborum ut magna pariatur officia cillum. Voluptate dolor ullamco commodo occaecat ex magna ex esse. Aliqua velit sint eu ipsum dolore in incididunt mollit eiusmod voluptate. Pariatur do voluptate adipisicing voluptate anim ad ipsum. Lorem qui nisi officia ullamco sunt duis enim amet ea cillum deserunt quis. Eu sunt sit enim ipsum.
</p>
)}
</div>
);
}

View File

@@ -0,0 +1,19 @@
import { auth } from "@/lib/auth";
import { LoginButton } from "./login_button";
import { LogoutButton } from "./logout_button";
/**
* This is a server component, then the buttons are client
*/
export default async function LogIn(): Promise<JSX.Element | undefined> {
const session = await auth();
if (session) {
return (
<LogoutButton/>
);
} else {
return (
<LoginButton/>
);
}
}

View File

@@ -0,0 +1,12 @@
"use client";
import { UserCircleIcon } from '@heroicons/react/24/outline';
import { signIn } from "next-auth/react";
export function LoginButton(): JSX.Element {
return (
<button className="p-1 hover:bg-dracula-bglight rounded-3xl transition-colors group" onClick={() => void signIn('cognito')}>
<UserCircleIcon className='stroke-dracula-cyan h-8 w-auto group-hover:stroke-dracula-orange transition-colors'/>
<span className="sr-only">Log in</span>
</button>
);
}

View File

@@ -0,0 +1,12 @@
"use client";
import { UserCircleIcon } from '@heroicons/react/24/outline';
import { signOut } from "next-auth/react";
export function LogoutButton(): JSX.Element {
return (
<button className="p-1 hover:bg-dracula-bglight rounded-3xl transition-colors group" onClick={() => void signOut()}>
<UserCircleIcon className='stroke-dracula-cyan h-8 w-auto group-hover:stroke-dracula-red transition-colors'/>
<span className="sr-only">Log out</span>
</button>
);
}

11
src/components/footer.tsx Normal file
View File

@@ -0,0 +1,11 @@
export default function NavBar(): JSX.Element {
return (
<footer className="bg-dracula-bg-darker border-t-2 border-dracula-purple">
<div className="mx-auto max-w-7xl px-4">
<div className="relative flex flex-row-reverse h-12 items-center justify-between">
<span className='text-white select-none'>© Joe Monk 2024</span>
</div>
</div>
</footer>
);
}

84
src/components/navbar.tsx Normal file
View File

@@ -0,0 +1,84 @@
'use client';
import { useState } from 'react';
import Link from 'next/link';
import { HomeModernIcon, Bars3Icon, XMarkIcon, UserCircleIcon } from '@heroicons/react/24/outline';
import { AnimatePresence, m, LazyMotion, domAnimation } from "framer-motion";
import LogIn from './auth/login';
const navigation = [
{ name: 'Blog', href: '#', current: true },
{ name: 'Projects', href: '#', current: false },
{ name: 'Photos', href: '#', current: false },
{ name: 'CV', href: '#', current: false },
{ name: 'Contact', href: '#', current: false },
];
export default function NavBar(): JSX.Element {
const [open, setOpen] = useState(false);
return (
<nav className="bg-dracula-bg-darker border-b-2 border-dracula-purple">
<LazyMotion features={domAnimation}>
<div className="mx-auto max-w-7xl px-4">
<div className="relative flex h-16 items-center justify-between">
<div className="flex">
<button className='sm:hidden hover:bg-dracula-bglight transition-colors duration-100 rounded-sm p-1' onClick={() => setOpen(!open)}>
{open ? (
<XMarkIcon className='rounded-sm stroke-dracula-cyan h-8 w-auto'/>
) : (
<Bars3Icon className='rounded-sm stroke-dracula-cyan h-8 w-auto'/>
)}
</button>
<Link className='hidden sm:flex items-center p-1 hover:bg-dracula-bglight transition-colors' href='/'>
<HomeModernIcon className='stroke-dracula-cyan rounded-sm h-8 w-auto'/>
</Link>
<div className='space-x-5 hidden sm:flex ml-10'>
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className={`hover:bg-dracula-bglight transition-colors duration-100 text-white rounded-sm px-3 pt-2 pb-1.5 font-normal border-b-2 border-transparent ${
item.current ? 'border-b-dracula-pink' : ''
}`}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</Link>
))}
</div>
</div>
<div>
</div>
<LogIn/>
</div>
</div>
<AnimatePresence>
{ open ? (
<m.div
initial={{ height: 0 }}
animate={{ height: "auto" }}
transition={{ duration: 0.15, ease: 'linear' }}
exit={{ height: 0 }}
className='sm:hidden overflow-hidden'
>
<div className='flex flex-col space-y-1 py-1'>
{navigation.map((item) => (
<Link
key={item.name}
href={item.href}
className={`hover:bg-dracula-bglight transition-colors duration-100 text-white px-2 py-2 font-normal border-l-4 border-transparent ${
item.current ? 'border-l-dracula-pink' : ''
}`}
aria-current={item.current ? 'page' : undefined}
>
{item.name}
</Link>
))}
</div>
</m.div>
) : null}
</AnimatePresence>
</LazyMotion>
</nav>
);
}

26
src/lib/auth.ts Normal file
View File

@@ -0,0 +1,26 @@
import 'server-only';
import { getServerSession } from "next-auth";
import CognitoProvider from "next-auth/providers/cognito";
import type { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from "next";
import type { NextAuthOptions, Session } from "next-auth";
export const authConfig = {
secret: process.env.NEXT_AUTH_SECRET,
providers: [
CognitoProvider({
clientId: process.env.NEXT_COGNITO_CLIENT_ID!,
clientSecret: process.env.NEXT_COGNITO_CLIENT_SECRET!,
issuer: process.env.NEXT_COGNITO_ISSUER,
})
],
callbacks: {
redirect(): string {
return '/api/preview';
}
}
} satisfies NextAuthOptions;
// Use it in server contexts
export function auth(...args: [GetServerSidePropsContext["req"], GetServerSidePropsContext["res"]] | [NextApiRequest, NextApiResponse] | []): Promise<Session | null> {
return getServerSession(...args, authConfig);
}

41
tailwind.config.ts Normal file
View File

@@ -0,0 +1,41 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
extend: {
fontFamily: {
sans: ['var(--font-inter)'],
mono: ['var(--font-roboto-mono)'],
},
colors: {
// Nicked from the vs code version of the theme https://github.com/dracula/visual-studio-code/blob/master/src/dracula.yml
dracula: {
'bglighter': '#424450',
'bglight': '#343746',
'bg': '#282A36',
'bg-dark': '#21222C',
'bg-darker': '#191A21',
'selection': '#44475A',
'comment': '#6272A4',
'cyan': '#8BE9FD',
'green': '#50FA7B',
'orange': '#FFB86C',
'pink': '#FF79C6',
'purple': '#BD93F9',
'red': '#FF5555',
'yellow': '#F1FA8C',
}
}
}
},
plugins: [
require('@tailwindcss/typography'),
require('tailwind-scrollbar')({ nocompatible: true })
],
};
export default config;

39
tsconfig.json Normal file
View File

@@ -0,0 +1,39 @@
{
"compilerOptions": {
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": [
"./src/*"
]
}
},
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}