diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5bc1e98 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,39 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +tab_width = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 80 +charset = utf-8 + +[*.yaml] +indent_style = space +indent_size = 2 +tab_width = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 80 +charset = utf-8 + +[*.yml] +indent_style = space +indent_size = 2 +tab_width = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +max_line_length = 80 +charset = utf-8 + +[*.sql] +indent_style = space +indent_size = 2 +tab_width = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true \ No newline at end of file diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml index a55a7f8..dc06f9e 100644 --- a/.github/workflows/github-actions.yml +++ b/.github/workflows/github-actions.yml @@ -26,9 +26,13 @@ jobs: cache-dependency-path: ./gradesa/package-lock.json node-version: 22.6 cache: "npm" + - name: Install dependencies + run: npm install - name: Install client dependencies run: npm install working-directory: ./gradesa + - name: Format + run: npm run format:check - name: Download pgmigrate run: | wget --quiet https://github.com/peterldowns/pgmigrate/releases/download/v0.1.0%2Bcommit.2f6a72b/pgmigrate-linux-amd64 -O pgmigrate diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..a4fc325 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +npm exec lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..540cb9d --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +dist +build +node_modules +.next +.turbo diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b7b77e8 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": false, + "trailingComma": "es5", + "semi": true +} \ No newline at end of file diff --git a/README.md b/README.md index d506ac0..47c8aa8 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ This should be all that's needed: - `wget https://github.com/peterldowns/pgmigrate/releases/download/v0.0.6%2Bcommit.4f90829/pgmigrate-linux-amd64 -O /usr/local/bin/pgmigrate` - `chmod +x /usr/local/bin/pgmigrate` - Docker, either of these installation options work (if you're new to docker, I recommend Docker Desktop): + - `brew install docker` + `brew install colima` (https://github.com/abiosoft/colima) - [Docker Desktop](https://www.docker.com/products/docker-desktop/) - WSL 2: Enabling `systemd` is recommended diff --git a/data/migrations/00002_add_users_table.sql b/data/migrations/00002_add_users_table.sql new file mode 100644 index 0000000..96a7e99 --- /dev/null +++ b/data/migrations/00002_add_users_table.sql @@ -0,0 +1,5 @@ +CREATE TABLE public.users ( + id bigint PRIMARY KEY NOT NULL GENERATED BY DEFAULT AS IDENTITY, + email text UNIQUE NOT NULL, + password_hash text NOT NULL +); \ No newline at end of file diff --git a/data/schema.sql b/data/schema.sql index 9c1458d..ebb06eb 100755 --- a/data/schema.sql +++ b/data/schema.sql @@ -4,3 +4,9 @@ CREATE TABLE public.pgmigrate_migrations ( execution_time_in_millis bigint NOT NULL, applied_at timestamp with time zone NOT NULL ); + +CREATE TABLE public.users ( + id bigint PRIMARY KEY NOT NULL GENERATED BY DEFAULT AS IDENTITY, + email text UNIQUE NOT NULL, + password_hash text NOT NULL +); diff --git a/gradesa/.eslintrc.js b/gradesa/.eslintrc.js new file mode 100644 index 0000000..24206ce --- /dev/null +++ b/gradesa/.eslintrc.js @@ -0,0 +1,20 @@ +module.exports = { + root: true, + extends: ["next", "prettier"], + plugins: ["eslint-plugin-react", "react-refresh", "unused-imports"], + rules: { + "turbo/no-undeclared-env-vars": 0, + "react-hooks/exhaustive-deps": 0, + "react/no-unescaped-entities": 0, + "unused-imports/no-unused-vars": [ + "error", + { + vars: "all", + varsIgnorePattern: "^_", + args: "after-used", + argsIgnorePattern: "^_", + }, + ], + }, + ignorePatterns: ["next.config.js"], +}; diff --git a/gradesa/eslint.config.mjs b/gradesa/eslint.config.mjs deleted file mode 100644 index 348c45a..0000000 --- a/gradesa/eslint.config.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import { dirname } from "path"; -import { fileURLToPath } from "url"; -import { FlatCompat } from "@eslint/eslintrc"; - -const __filename = fileURLToPath(import.meta.url); -const __dirname = dirname(__filename); - -const compat = new FlatCompat({ - baseDirectory: __dirname, -}); - -const eslintConfig = [...compat.extends("next/core-web-vitals")]; - -export default eslintConfig; diff --git a/gradesa/package-lock.json b/gradesa/package-lock.json index 5b429d8..261b2b2 100644 --- a/gradesa/package-lock.json +++ b/gradesa/package-lock.json @@ -23,6 +23,10 @@ "@vitejs/plugin-react": "^4.3.4", "eslint": "^9", "eslint-config-next": "15.1.5", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-refresh": "^0.4.18", + "eslint-plugin-unused-imports": "^4.1.4", "jsdom": "^26.0.0", "ts-node": "^10.9.2", "vitest": "^3.0.4" @@ -3239,6 +3243,7 @@ "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -3609,6 +3614,18 @@ } } }, + "node_modules/eslint-config-prettier": { + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", + "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", + "dev": true, + "bin": { + "eslint-config-prettier": "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", @@ -3842,6 +3859,15 @@ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.18.tgz", + "integrity": "sha512-IRGEoFn3OKalm3hjfolEWGqoF/jPqeEYFp+C8B0WMzwGwBMvlRDQd06kghDhF0C61uJ6WfSDhEZE/sAQjduKgw==", + "dev": true, + "peerDependencies": { + "eslint": ">=8.40" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -3868,6 +3894,21 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-unused-imports": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.1.4.tgz", + "integrity": "sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==", + "dev": true, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", + "eslint": "^9.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz", @@ -7259,6 +7300,20 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/gradesa/package.json b/gradesa/package.json index 05e404e..e914b40 100644 --- a/gradesa/package.json +++ b/gradesa/package.json @@ -26,8 +26,12 @@ "@vitejs/plugin-react": "^4.3.4", "eslint": "^9", "eslint-config-next": "15.1.5", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-unused-imports": "^4.1.4", + "eslint-plugin-react": "^7.37.4", + "eslint-plugin-react-refresh": "^0.4.18", "jsdom": "^26.0.0", "ts-node": "^10.9.2", "vitest": "^3.0.4" } -} +} \ No newline at end of file diff --git a/gradesa/src/app/api/hello/route.js b/gradesa/src/app/api/hello/route.js index 6d8983a..edada29 100644 --- a/gradesa/src/app/api/hello/route.js +++ b/gradesa/src/app/api/hello/route.js @@ -1,12 +1,12 @@ -import { DB } from '../../../backend/db'; +import { DB } from "../../../backend/db"; export async function GET(request) { - const result = await DB.pool('SELECT now()'); + const result = await DB.pool("SELECT now()"); const query = request.nextUrl.searchParams; - const mode = query.get('mode'); - if (mode === 'error') { - return Response.json({ message: 'Error' }, { status: 500 }); + const mode = query.get("mode"); + if (mode === "error") { + return Response.json({ message: "Error" }, { status: 500 }); } const now = result.rows[0].now; - return Response.json({ message: 'Hello!', now, mode }); + return Response.json({ message: "Hello!", now, mode }); } diff --git a/gradesa/src/app/auth/layout.js b/gradesa/src/app/auth/layout.js index 77586dd..5070e78 100644 --- a/gradesa/src/app/auth/layout.js +++ b/gradesa/src/app/auth/layout.js @@ -1,11 +1,9 @@ -import './auth.css' +import "./auth.css"; export default function AuthLayout({ children }) { - return ( -