diff --git a/.eslintrc b/.eslintrc index 249cad4..c5d43a6 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,34 +1,3 @@ { - "settings": { - "react": { - "version": "detect" - } - }, - "root": true, - "env": { - "es2021": true, - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:react/jsx-runtime", - "plugin:@typescript-eslint/recommended", - "prettier" - ], - "overrides": [], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "plugins": ["react", "@typescript-eslint", "prettier"], - "rules": { - "prettier/prettier": [ - "error", - { - "endOfLine": "auto" - } - ] - } + "extends": ["next", "prettier"] } diff --git a/README.md b/README.md index e612117..8e13852 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,70 @@ # chessu -> ❗ This project is currently undergoing a major refactor in the `dev` branch. (see [#4](https://github.com/nizewn/chessu/pull/4)) +> ❗ This project is still in the early stages of development and should be considered unstable. Expect bugs and weird behavior. -Online 2-player chess. Live demo at [ches.su](https://ches.su) +Yet another Chess web app. Live demo at [ches.su](https://ches.su). -- React 18 -- CSS Modules -- [react-chessboard](https://github.com/Clariity/react-chessboard) -- [chess.js](https://github.com/jhlywa/chess.js) -- Express.js -- socket.io -- PostgreSQL +- play against other users in real-time +- spectate and chat in ongoing games with other users +- ~~_optional_ user accounts for tracking stats and game history~~ (wip) +- mobile-friendly (wip) -## Development +Built with Next.js 13, Tailwind CSS + daisyUI, react-chessboard, chess.js, Express.js, socket.io and PostgreSQL. -This repository is used for production deployments. You will need to make changes to the configuration to get this running locally. +## Configuration + +This project is structured as a monorepo using npm workspaces, separated into three packages: + +- `client` - Next.js application for the front-end, deployed to [ches.su](https://ches.su). +- `server` - Node/Express.js application for the back-end, deployed to [api.ches.su](https://api.ches.su). +- `types` - Shared type definitions for the client and server. + +### Scripts ```sh -npm install # install all dependencies +# install all dependencies, including eslint and prettier for development +npm install + +# concurrently run frontend and backend development servers +npm run dev # -w client/server to run only one -npm run dev # concurrently run frontend and backend dev servers -npm run react-dev # run frontend server only +# for separate production deployments +npm install -w client +npm install -w server + +npm run build -w client +npm run build -w server + +npm start -w client +npm start -w server ``` +For separate deployments, you may exclude the `client` or `server` directory. However, you should include the `types` folder as it contains shared type definitions that are required by both packages. + ### Environment variables -Client: `APIURL` (or just change `apiUrl` in `/client/src/config/config.ts`) +You may create a `.env` file in each package directory to set their environment variables. -Server: `PORT`, `SESSION_SECRET`, `PGUSER`, `PGPASSWORD`, `PGHOST`, `PGDATABASE`, `PGPORT` -(also see server cors config and session middleware for local development) +client: + +```env +NEXT_PUBLIC_API_URL=http://localhost:3001 # replace with backend URL +``` + +server: + +```env +CORS_ORIGIN=http://localhost:3000 # replace with frontend URL +PORT=3001 +SESSION_SECRET=randomstring # replace for security + +# PostgreSQL connection info +PGHOST=db.example.com +PGUSER=exampleuser +PGPASSWORD=examplepassword +PGDATABASE=chessu + +# or use a connection string instead +DATABASE_URL=postgres://... +``` diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..a097e18 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,37 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem +.vscode/ + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/client/index.html b/client/index.html deleted file mode 100644 index a546081..0000000 --- a/client/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Chessu - - -
- - - diff --git a/client/next.config.js b/client/next.config.js new file mode 100644 index 0000000..72ccbee --- /dev/null +++ b/client/next.config.js @@ -0,0 +1,9 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + reactStrictMode: true, + experimental: { + appDir: true + } +}; + +module.exports = nextConfig; diff --git a/client/package.json b/client/package.json index 27424d8..f2cd0ea 100644 --- a/client/package.json +++ b/client/package.json @@ -1,28 +1,35 @@ { - "name": "chessu", - "private": true, + "name": "@chessu/client", "version": "0.0.0", - "type": "module", + "private": true, "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "preview": "vite preview" + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" }, "dependencies": { - "@radix-ui/colors": "^0.1.8", - "@radix-ui/react-icons": "^1.1.1", + "@tabler/icons-react": "^2.7.0", "chess.js": "^1.0.0-beta.3", - "react": "^18.2.0", - "react-chessboard": "^2.0.8", - "react-dom": "^18.2.0", - "react-router-dom": "^6.8.1", - "socket.io-client": "^4.6.0" + "next": "13.2.3", + "react": "18.2.0", + "react-chessboard": "^2.1.0", + "react-dom": "18.2.0", + "socket.io-client": "^4.6.1" }, "devDependencies": { - "@types/react": "^18.0.28", - "@types/react-dom": "^18.0.11", - "@vitejs/plugin-react-swc": "^3.1.0", - "typescript": "^4.9.5", - "vite": "^4.1.1" + "@chessu/types": "*", + "@types/node": "18.14.6", + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11", + "autoprefixer": "^10.4.13", + "daisyui": "^2.51.3", + "postcss": "^8.4.21", + "tailwindcss": "^3.2.7", + "typescript": "4.9.5" + }, + "optionalDependencies": { + "bufferutil": "^4.0.7", + "utf-8-validate": "^6.0.3" } } diff --git a/client/postcss.config.js b/client/postcss.config.js new file mode 100644 index 0000000..fe66dd6 --- /dev/null +++ b/client/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/client/public/assets/default_avatar.png b/client/public/assets/default_avatar.png new file mode 100644 index 0000000..0989209 Binary files /dev/null and b/client/public/assets/default_avatar.png differ diff --git a/client/public/chessu.svg b/client/public/chessu.svg deleted file mode 100644 index cabe48a..0000000 --- a/client/public/chessu.svg +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/client/src/App.tsx b/client/src/App.tsx deleted file mode 100644 index 18bbb0c..0000000 --- a/client/src/App.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Route, Routes } from "react-router-dom"; -import ContextProvider from "./context/ContextProvider"; - -import Header from "./components/Header/Header"; -import Footer from "./components/Footer/Footer"; - -import ProtectedRoutes from "./routes/ProtectedRoutes"; -import Home from "./routes/Home/Home"; -import Game from "./routes/Game/Game"; -import NotFound from "./routes/NotFound/NotFound"; - -import "./global.css"; - -const App = (): JSX.Element => { - return ( - -
-
- - } /> - }> - } /> - - } /> - -
-