diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..61cd0f4 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,7 @@ +{ + "plugins": ["unused-imports"], + "rules": { + "unused-imports/no-unused-imports": "error" + }, + "extends": ["prettier"] +} diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..058d524 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,3 @@ +git add -A +npm run format:staged +npm run lint \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..17a1cda --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +.prettierignore +public/ +.gitignore +.husky/ +.next/ +./node_modules/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..137871f --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "none", + "tabWidth": 2, + "semi": false, + "singleQuote": true, + "printWidth": 80 +} diff --git a/eslint.config.mjs b/eslint.config.mjs index c85fb67..b0c6f5a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,16 +1,16 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; +import { dirname } from 'path' +import { fileURLToPath } from 'url' +import { FlatCompat } from '@eslint/eslintrc' -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) const compat = new FlatCompat({ - baseDirectory: __dirname, -}); + baseDirectory: __dirname +}) const eslintConfig = [ - ...compat.extends("next/core-web-vitals", "next/typescript"), -]; + ...compat.extends('next/core-web-vitals', 'next/typescript') +] -export default eslintConfig; +export default eslintConfig diff --git a/next.config.ts b/next.config.ts index e9ffa30..7329063 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,7 @@ -import type { NextConfig } from "next"; +import type { NextConfig } from 'next' const nextConfig: NextConfig = { /* config options here */ -}; +} -export default nextConfig; +export default nextConfig diff --git a/package-lock.json b/package-lock.json index 7192135..038f722 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,10 @@ "@types/react-dom": "^19", "eslint": "^9", "eslint-config-next": "15.1.5", + "eslint-config-prettier": "^10.0.1", + "husky": "^9.1.7", "postcss": "^8", + "prettier": "^3.4.2", "tailwindcss": "^3.4.1", "typescript": "^5" } @@ -2133,6 +2136,18 @@ } } }, + "node_modules/eslint-config-prettier": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", + "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", + "dev": true, + "bin": { + "eslint-config-prettier": "build/bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, "node_modules/eslint-import-resolver-node": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", @@ -2931,6 +2946,21 @@ "node": ">= 0.4" } }, + "node_modules/husky": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "dev": true, + "bin": { + "husky": "bin.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4212,6 +4242,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.4.2.tgz", + "integrity": "sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==", + "dev": true, + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", diff --git a/package.json b/package.json index c019129..fe2558e 100644 --- a/package.json +++ b/package.json @@ -6,22 +6,28 @@ "dev": "next dev --turbopack", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "format:all": "prettier --write .", + "format:staged": "prettier --write $(git diff --staged --name-only --diff-filter d | xargs)", + "prepare": "husky" }, "dependencies": { + "next": "15.1.5", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.1.5" + "react-dom": "^19.0.0" }, "devDependencies": { - "typescript": "^5", + "@eslint/eslintrc": "^3", "@types/node": "^20", "@types/react": "^19", "@types/react-dom": "^19", - "postcss": "^8", - "tailwindcss": "^3.4.1", "eslint": "^9", "eslint-config-next": "15.1.5", - "@eslint/eslintrc": "^3" + "eslint-config-prettier": "^10.0.1", + "husky": "^9.1.7", + "postcss": "^8", + "prettier": "^3.4.2", + "tailwindcss": "^3.4.1", + "typescript": "^5" } } diff --git a/postcss.config.mjs b/postcss.config.mjs index 1a69fd2..b1d7bf4 100644 --- a/postcss.config.mjs +++ b/postcss.config.mjs @@ -1,8 +1,8 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - tailwindcss: {}, - }, -}; + tailwindcss: {} + } +} -export default config; +export default config diff --git a/src/app/layout.tsx b/src/app/layout.tsx index f7fa87e..0a57d2c 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,26 +1,26 @@ -import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; -import "./globals.css"; +import type { Metadata } from 'next' +import { Geist, Geist_Mono } from 'next/font/google' +import './globals.css' const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); + variable: '--font-geist-sans', + subsets: ['latin'] +}) const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], -}); + variable: '--font-geist-mono', + subsets: ['latin'] +}) export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", -}; + title: 'Create Next App', + description: 'Generated by create next app' +} export default function RootLayout({ - children, + children }: Readonly<{ - children: React.ReactNode; + children: React.ReactNode }>) { return ( @@ -30,5 +30,5 @@ export default function RootLayout({ {children} - ); + ) } diff --git a/src/app/page.tsx b/src/app/page.tsx index 3eee014..971afc2 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,4 @@ -import Image from "next/image"; +import Image from 'next/image' export default function Home() { return ( @@ -14,7 +14,7 @@ export default function Home() { />
  1. - Get started by editing{" "} + Get started by editing{' '} src/app/page.tsx @@ -97,5 +97,5 @@ export default function Home() { - ); + ) } diff --git a/tailwind.config.ts b/tailwind.config.ts index 109807b..3321185 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,18 +1,18 @@ -import type { Config } from "tailwindcss"; +import type { Config } from 'tailwindcss' export default { content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", + './src/pages/**/*.{js,ts,jsx,tsx,mdx}', + './src/components/**/*.{js,ts,jsx,tsx,mdx}', + './src/app/**/*.{js,ts,jsx,tsx,mdx}' ], theme: { extend: { colors: { - background: "var(--background)", - foreground: "var(--foreground)", - }, - }, + background: 'var(--background)', + foreground: 'var(--foreground)' + } + } }, - plugins: [], -} satisfies Config; + plugins: [] +} satisfies Config