├── LICENSE
├── api
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── Dockerfile
├── README.md
├── nest-cli.json
├── package.json
├── src
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ └── main.ts
├── test
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
├── tsconfig.build.json
├── tsconfig.json
└── yarn.lock
├── client
├── .gitignore
├── Dockerfile
├── README.md
├── package.json
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
├── tsconfig.json
└── yarn.lock
├── docker-compose.yml
├── docker_postgres_init.sql
└── nginx
├── Dockerfile
└── default.conf
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright © 2022 Alex Devero (https://alexdevero.com)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8 |
--------------------------------------------------------------------------------
/api/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: '@typescript-eslint/parser',
3 | parserOptions: {
4 | project: 'tsconfig.json',
5 | tsconfigRootDir : __dirname,
6 | sourceType: 'module',
7 | },
8 | plugins: ['@typescript-eslint/eslint-plugin'],
9 | extends: [
10 | 'plugin:@typescript-eslint/recommended',
11 | 'plugin:prettier/recommended',
12 | ],
13 | root: true,
14 | env: {
15 | node: true,
16 | jest: true,
17 | },
18 | ignorePatterns: ['.eslintrc.js'],
19 | rules: {
20 | '@typescript-eslint/interface-name-prefix': 'off',
21 | '@typescript-eslint/explicit-function-return-type': 'off',
22 | '@typescript-eslint/explicit-module-boundary-types': 'off',
23 | '@typescript-eslint/no-explicit-any': 'off',
24 | },
25 | };
26 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | # compiled output
2 | /dist
3 | /node_modules
4 |
5 | # Logs
6 | logs
7 | *.log
8 | npm-debug.log*
9 | pnpm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 | lerna-debug.log*
13 |
14 | # OS
15 | .DS_Store
16 |
17 | # Tests
18 | /coverage
19 | /.nyc_output
20 |
21 | # IDEs and editors
22 | /.idea
23 | .project
24 | .classpath
25 | .c9/
26 | *.launch
27 | .settings/
28 | *.sublime-workspace
29 |
30 | # IDE - VSCode
31 | .vscode/*
32 | !.vscode/settings.json
33 | !.vscode/tasks.json
34 | !.vscode/launch.json
35 | !.vscode/extensions.json
--------------------------------------------------------------------------------
/api/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/api/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:18.1.0-alpine3.14
2 |
3 | WORKDIR /app
4 |
5 | COPY package.json ./
6 | COPY yarn.lock ./
7 |
8 | COPY ./ ./
9 |
10 | RUN yarn
11 |
12 | CMD ["yarn", "start"]
13 |
--------------------------------------------------------------------------------
/api/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456
6 | [circleci-url]: https://circleci.com/gh/nestjs/nest
7 |
8 | A progressive Node.js framework for building efficient and scalable server-side applications.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
24 |
25 | ## Description
26 |
27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository.
28 |
29 | ## Installation
30 |
31 | ```bash
32 | $ npm install
33 | ```
34 |
35 | ## Running the app
36 |
37 | ```bash
38 | # development
39 | $ npm run start
40 |
41 | # watch mode
42 | $ npm run start:dev
43 |
44 | # production mode
45 | $ npm run start:prod
46 | ```
47 |
48 | ## Test
49 |
50 | ```bash
51 | # unit tests
52 | $ npm run test
53 |
54 | # e2e tests
55 | $ npm run test:e2e
56 |
57 | # test coverage
58 | $ npm run test:cov
59 | ```
60 |
61 | ## Support
62 |
63 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support).
64 |
65 | ## Stay in touch
66 |
67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com)
68 | - Website - [https://nestjs.com](https://nestjs.com/)
69 | - Twitter - [@nestframework](https://twitter.com/nestframework)
70 |
71 | ## License
72 |
73 | Nest is [MIT licensed](LICENSE).
74 |
--------------------------------------------------------------------------------
/api/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/nest-cli",
3 | "collection": "@nestjs/schematics",
4 | "sourceRoot": "src"
5 | }
6 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "0.0.1",
4 | "description": "",
5 | "author": "",
6 | "private": true,
7 | "license": "UNLICENSED",
8 | "scripts": {
9 | "prebuild": "rimraf dist",
10 | "build": "nest build",
11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
12 | "start": "nest start",
13 | "start:dev": "nest start --watch",
14 | "start:debug": "nest start --debug --watch",
15 | "start:prod": "node dist/main",
16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
17 | "test": "jest",
18 | "test:watch": "jest --watch",
19 | "test:cov": "jest --coverage",
20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
21 | "test:e2e": "jest --config ./test/jest-e2e.json"
22 | },
23 | "dependencies": {
24 | "@nestjs/common": "^8.0.0",
25 | "@nestjs/core": "^9.0.5",
26 | "@nestjs/platform-express": "^8.0.0",
27 | "reflect-metadata": "^0.1.13",
28 | "rimraf": "^3.0.2",
29 | "rxjs": "^7.2.0"
30 | },
31 | "devDependencies": {
32 | "@nestjs/cli": "^8.0.0",
33 | "@nestjs/schematics": "^8.0.0",
34 | "@nestjs/testing": "^8.0.0",
35 | "@types/express": "^4.17.13",
36 | "@types/jest": "27.4.1",
37 | "@types/node": "^16.0.0",
38 | "@types/supertest": "^2.0.11",
39 | "@typescript-eslint/eslint-plugin": "^5.0.0",
40 | "@typescript-eslint/parser": "^5.0.0",
41 | "eslint": "^8.0.1",
42 | "eslint-config-prettier": "^8.3.0",
43 | "eslint-plugin-prettier": "^4.0.0",
44 | "jest": "^27.2.5",
45 | "prettier": "^2.3.2",
46 | "source-map-support": "^0.5.20",
47 | "supertest": "^6.1.3",
48 | "ts-jest": "^27.0.3",
49 | "ts-loader": "^9.2.3",
50 | "ts-node": "^10.0.0",
51 | "tsconfig-paths": "^3.10.1",
52 | "typescript": "^4.3.5"
53 | },
54 | "jest": {
55 | "moduleFileExtensions": [
56 | "js",
57 | "json",
58 | "ts"
59 | ],
60 | "rootDir": "src",
61 | "testRegex": ".*\\.spec\\.ts$",
62 | "transform": {
63 | "^.+\\.(t|j)s$": "ts-jest"
64 | },
65 | "collectCoverageFrom": [
66 | "**/*.(t|j)s"
67 | ],
68 | "coverageDirectory": "../coverage",
69 | "testEnvironment": "node"
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/api/src/app.controller.spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { AppController } from './app.controller';
3 | import { AppService } from './app.service';
4 |
5 | describe('AppController', () => {
6 | let appController: AppController;
7 |
8 | beforeEach(async () => {
9 | const app: TestingModule = await Test.createTestingModule({
10 | controllers: [AppController],
11 | providers: [AppService],
12 | }).compile();
13 |
14 | appController = app.get(AppController);
15 | });
16 |
17 | describe('root', () => {
18 | it('should return "Hello World!"', () => {
19 | expect(appController.getHello()).toBe('Hello World!');
20 | });
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/api/src/app.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get } from '@nestjs/common';
2 | import { AppService } from './app.service';
3 |
4 | @Controller()
5 | export class AppController {
6 | constructor(private readonly appService: AppService) {}
7 |
8 | @Get()
9 | getHello(): string {
10 | return this.appService.getHello();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/api/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { AppController } from './app.controller';
3 | import { AppService } from './app.service';
4 |
5 | @Module({
6 | imports: [],
7 | controllers: [AppController],
8 | providers: [AppService],
9 | })
10 | export class AppModule {}
11 |
--------------------------------------------------------------------------------
/api/src/app.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | @Injectable()
4 | export class AppService {
5 | getHello(): string {
6 | return 'Hello World!';
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/api/src/main.ts:
--------------------------------------------------------------------------------
1 | import { NestFactory } from '@nestjs/core';
2 | import { AppModule } from './app.module';
3 |
4 | async function bootstrap() {
5 | const app = await NestFactory.create(AppModule);
6 | await app.listen(3000);
7 | }
8 | bootstrap();
9 |
--------------------------------------------------------------------------------
/api/test/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { Test, TestingModule } from '@nestjs/testing';
2 | import { INestApplication } from '@nestjs/common';
3 | import * as request from 'supertest';
4 | import { AppModule } from './../src/app.module';
5 |
6 | describe('AppController (e2e)', () => {
7 | let app: INestApplication;
8 |
9 | beforeEach(async () => {
10 | const moduleFixture: TestingModule = await Test.createTestingModule({
11 | imports: [AppModule],
12 | }).compile();
13 |
14 | app = moduleFixture.createNestApplication();
15 | await app.init();
16 | });
17 |
18 | it('/ (GET)', () => {
19 | return request(app.getHttpServer())
20 | .get('/')
21 | .expect(200)
22 | .expect('Hello World!');
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/api/test/jest-e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "moduleFileExtensions": ["js", "json", "ts"],
3 | "rootDir": ".",
4 | "testEnvironment": "node",
5 | "testRegex": ".e2e-spec.ts$",
6 | "transform": {
7 | "^.+\\.(t|j)s$": "ts-jest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/api/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/api/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "declaration": true,
5 | "removeComments": true,
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "allowSyntheticDefaultImports": true,
9 | "target": "es2017",
10 | "sourceMap": true,
11 | "outDir": "./dist",
12 | "baseUrl": "./",
13 | "incremental": true,
14 | "skipLibCheck": true,
15 | "strictNullChecks": false,
16 | "noImplicitAny": false,
17 | "strictBindCallApply": false,
18 | "forceConsistentCasingInFileNames": false,
19 | "noFallthroughCasesInSwitch": false
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:18.1.0-alpine3.14
2 |
3 | WORKDIR /app
4 |
5 | COPY package.json ./
6 | COPY yarn.lock ./
7 |
8 | COPY ./ ./
9 |
10 | RUN yarn
11 |
12 | CMD ["yarn", "start"]
13 |
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.14.1",
7 | "@testing-library/react": "^13.0.0",
8 | "@testing-library/user-event": "^13.2.1",
9 | "@types/jest": "^27.0.1",
10 | "@types/node": "^16.7.13",
11 | "@types/react": "^18.0.0",
12 | "@types/react-dom": "^18.0.0",
13 | "react": "^18.1.0",
14 | "react-dom": "^18.1.0",
15 | "react-scripts": "5.0.1",
16 | "typescript": "^4.4.2",
17 | "web-vitals": "^2.1.0"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexdevero/docker-nestjs-react-postgres/54b89000c11f2a971f938cec8b3d36ae8b8d13da/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/client/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexdevero/docker-nestjs-react-postgres/54b89000c11f2a971f938cec8b3d36ae8b8d13da/client/public/logo192.png
--------------------------------------------------------------------------------
/client/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alexdevero/docker-nestjs-react-postgres/54b89000c11f2a971f938cec8b3d36ae8b8d13da/client/public/logo512.png
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/client/src/App.test.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render, screen } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | render();
7 | const linkElement = screen.getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/client/src/App.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import logo from './logo.svg';
3 | import './App.css';
4 |
5 | function App() {
6 | return (
7 |
23 | );
24 | }
25 |
26 | export default App;
27 |
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/client/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | const root = ReactDOM.createRoot(
8 | document.getElementById('root') as HTMLElement
9 | );
10 | root.render(
11 |
12 |
13 |
14 | );
15 |
16 | // If you want to start measuring performance in your app, pass a function
17 | // to log results (for example: reportWebVitals(console.log))
18 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
19 | reportWebVitals();
20 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/client/src/reportWebVitals.ts:
--------------------------------------------------------------------------------
1 | import { ReportHandler } from 'web-vitals';
2 |
3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => {
4 | if (onPerfEntry && onPerfEntry instanceof Function) {
5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
6 | getCLS(onPerfEntry);
7 | getFID(onPerfEntry);
8 | getFCP(onPerfEntry);
9 | getLCP(onPerfEntry);
10 | getTTFB(onPerfEntry);
11 | });
12 | }
13 | };
14 |
15 | export default reportWebVitals;
16 |
--------------------------------------------------------------------------------
/client/src/setupTests.ts:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "module": "esnext",
17 | "moduleResolution": "node",
18 | "resolveJsonModule": true,
19 | "isolatedModules": true,
20 | "noEmit": true,
21 | "jsx": "react-jsx"
22 | },
23 | "include": [
24 | "src"
25 | ]
26 | }
27 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.8'
2 |
3 | services:
4 | postgres:
5 | image: postgres:14.2
6 | restart: always
7 | environment:
8 | POSTGRES_USER: root
9 | POSTGRES_PASSWORD: root
10 | POSTGRES_DB: test_db
11 | ports:
12 | - "5432:5432"
13 | volumes:
14 | - pg_data:/var/lib/postgresql/data/
15 | - ./docker_postgres_init.sql:/docker-entrypoint-initdb.d/docker_postgres_init.sql
16 |
17 | nxginx:
18 | depends_on:
19 | - api
20 | - client
21 | restart: always
22 | build:
23 | dockerfile: Dockerfile
24 | context: "./nginx"
25 | ports:
26 | - "3050:80"
27 |
28 | api:
29 | restart: always
30 | build:
31 | dockerfile: Dockerfile
32 | context: './api'
33 | depends_on:
34 | - postgres
35 | volumes:
36 | - /api/node_modules
37 | - ./api:/api
38 | ports:
39 | - '3001:3000'
40 |
41 | client:
42 | build:
43 | dockerfile: Dockerfile
44 | context: "./client"
45 | depends_on:
46 | - api # todo: might not be necessary
47 | volumes:
48 | - /client/node_modules
49 | - ./client:/app
50 | ports:
51 | - "3000:3000"
52 |
53 | volumes:
54 | pg_data:
55 |
--------------------------------------------------------------------------------
/docker_postgres_init.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE test_db
2 | WITH
3 | OWNER = postgres
4 | ENCODING = 'UTF8'
5 | LC_COLLATE = 'en_US.utf8'
6 | LC_CTYPE = 'en_US.utf8'
7 | TABLESPACE = pg_default
8 | CONNECTION LIMIT = -1;
9 |
10 | DROP TABLE IF EXISTS students;
11 |
12 | CREATE TABLE students (
13 | id SERIAL PRIMARY KEY,
14 | first_name VARCHAR(100) NOT NULL,
15 | last_name VARCHAR(100) NOT NULL,
16 | city VARCHAR(255) NOT NULL,
17 | phone VARCHAR(255) NOT NULL,
18 | gender VARCHAR(255) NOT NULL,
19 | email VARCHAR(255) NOT NULL,
20 | address VARCHAR(255) NOT NULL,
21 | postcode INT NOT NULL,
22 | date_of_birth DATE NOT NULL
23 | );
24 |
25 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Ailn', 'Rathmouth', 'Rathmouth', '05144461974', 'Female', 'mailn0@bravesites.com', '97228 Emmalee Harbors Suite 421 South Emmet, TX 54950', 23031, '2001-12-16');
26 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Hounson', 'Port Lolamouth', 'Port Lolamouth', '1-136-366-9496', 'Female', 'dhounson1@slashdot.org', '62654 Hirthe Lodge Port Zeldafurt, DE 87270', 27108, '1977-01-21');
27 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Tison', 'Lavernastad', 'Lavernastad', '157-283-0337x872', 'Female', 'ctison2@europa.eu', '9107 Blanda Plains Apt. 476 North Burdettechester, NM 91601', 76631, '1984-03-26');
28 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Surmeyers', 'Ethelville', 'Ethelville', '552.496.5910', 'Male', 'msurmeyers3@nytimes.com', '0997 Gleason Rue Apt. 149 East Gretaland, GA 13633-6343', 37965, '2005-03-17');
29 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Bob', 'Schulistland', 'Schulistland', '895-877-0076x197', 'Male', 'scbob@opensource.org', '39405 Nicolas Walk Apt. 041 Kozeychester, AL 20566-8063', 23031, '2019-07-15');
30 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Holdey', 'Kennithside', 'Kennithside', '(055)403-3761', 'Female', 'aholdey5@miibeian.gov.cn', '747 Lucienne Shoal Suite 395 Runolfsdottirberg, NV 65296-7656', 23031, '1971-05-10');
31 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Blewmen', 'Oberbrunnerchester', 'Oberbrunnerchester', '(598)918-4548x480', 'Male', 'rblewmen6@github.com', '34720 Randi Roads Apt. 947 Kossmouth, WV 43552-7336', 24772, '2011-03-26');
32 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Vanacci', 'Marcoport', 'Marcoport', '013-440-6362', 'Female', 'gvanacci7@bbb.org', '044 Gaylord Corner Apt. 486 Larsonchester, MA 59370', 16, '1973-05-17');
33 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Marflitt', 'New Adalineton', 'New Adalineton', '1-113-016-8153x30326', 'Male', 'dmarflitt8@istockphoto.com', '1670 Bogisich Lane Apt. 874 Port Malvina, CT 60714', 89650, '2009-03-23');
34 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Pietesch', 'East Kayla', 'East Kayla', '(177)500-7249', 'Female', 'gpietesch9@forbes.com', '651 Mallory Centers Hoppefort, PA 46020', 45934, '2002-01-06');
35 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Henrique', 'Kevinmouth', 'Kevinmouth', '1-241-311-9984', 'Male', 'ghenriquea@eventbrite.com', '31480 Oscar Wells Kassulkeborough, DC 35274-5250', 7820, '2002-10-24');
36 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Tynan', 'North Deondreland', 'North Deondreland', '(674)474-7300', 'Male', 'dtynanb@yolasite.com', '2729 Lucienne Roads Apt. 317 Theodorafurt, SD 21614-2447', 32292, '1980-12-21');
37 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Pinkard', 'Port Adrianaborough', 'Port Adrianaborough', '02115446108', 'Female', 'jpinkardc@cafepress.com', '73620 Carmela Corners Apt. 609 New Litzy, DE 72732-8030', 55848, '1981-10-08');
38 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Haslock', 'South Hunter', 'South Hunter', '09398525252', 'Male', 'ehaslockd@jalbum.net', '65792 Celine Coves Lempibury, MT 60747', 29257, '1985-04-25');
39 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Rickell', 'East Breanne', 'East Breanne', '692.772.5134x95174', 'Female', 'mrickelle@wikia.com', '51665 Hermina Islands Apt. 724 East Nasirfort, CT 57320-2649', 49701, '1971-01-10');
40 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Bob', 'Port Thoraland', 'Port Thoraland', '1-628-108-7615', 'Male', 'pobob@ycombinator.com', '9256 Price Summit Garrickland, KY 23867', 23031, '2016-02-05');
41 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Boxhill', 'West Jedediahville', 'West Jedediahville', '(725)577-0459', 'Male', 'tboxhillg@forbes.com', '557 Leo Alley Suite 273 Considinestad, AL 94813', 80323, '1995-04-30');
42 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Leeke', 'Franeckiland', 'Franeckiland', '1-889-468-2992x930', 'Female', 'mleekeh@amazonaws.com', '1080 Orn Brook Heidenreichberg, GA 90248', 39741, '1970-01-03');
43 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Whale', 'Lake Clare', 'Lake Clare', '513-793-1124x98433', 'Male', 'wwhalei@creativecommons.org', '605 Rosa Mills Suite 999 West Clarkburgh, MO 74959-5620', 24982, '1978-06-23');
44 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Ori', 'Beattyburgh', 'Beattyburgh', '08253021064', 'Male', 'morij@twitpic.com', '6164 Spencer Meadow Apt. 689 Baumbachtown, PA 23843-5497', 7864, '1982-11-15');
45 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Tagg', 'Oberbrunnerport', 'Oberbrunnerport', '1-725-956-1107x13861', 'Male', 'mtaggk@1688.com', '572 Cyril Parkways Apt. 479 Murazikchester, KY 73127', 36356, '1993-11-18');
46 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Costerd', 'Ricofort', 'Ricofort', '096-776-9198', 'Male', 'fcosterdl@baidu.com', '96564 Cooper Corner Apt. 352 Port Floy, OR 86049', 69978, '2003-07-26');
47 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Corrin', 'East Graycefurt', 'East Graycefurt', '(583)403-4746', 'Male', 'tcorrinm@intel.com', '353 Israel Streets Jedediahport, GA 99481', 49614, '1988-02-29');
48 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Bunford', 'West Joeport', 'West Joeport', '(245)726-8274x48974', 'Female', 'nbunfordn@joomla.org', '9755 Kshlerin Brooks East Roger, ND 23843-8553', 16353, '1979-11-25');
49 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Lumley', 'Oceanestad', 'Oceanestad', '06965723793', 'Female', 'hlumleyo@w3.org', '9877 Kaia Village New angelomouth, KS 82353-9742', 70534, '1985-06-15');
50 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Whiles', 'Creolashire', 'Creolashire', '800.294.1751x13357', 'Male', 'pwhilesp@amazon.co.jp', '229 Derrick Village Gayview, OR 63688-9938', 58634, '1990-09-30');
51 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Presdee', 'North Ernestinaton', 'North Ernestinaton', '556-111-2276x003', 'Female', 'mpresdeeq@sourceforge.net', '4353 Bayer Lights East Bentonville, GA 61468-6552', 90902, '1985-11-01');
52 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Bedberry', 'Jakaylaland', 'Jakaylaland', '1-078-468-7156', 'Female', 'jbedberryr@taobao.com', '51526 Stamm Garden Apt. 560 Hahnview, CA 29074-8976', 10160, '1998-09-04');
53 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Danilchev', 'North Esta', 'North Esta', '1-244-938-3948', 'Female', 'sdanilchevs@addtoany.com', '34989 Kuphal Inlet Suite 190 Gutkowskiville, IA 69417', 40221, '1992-10-04');
54 | INSERT INTO students (first_name, last_name, city, phone, gender, email, address, postcode, date_of_birth) VALUES ( 'Whaplington', 'West Breanabury', 'West Breanabury', '1-045-399-1032x67023', 'Female', 'cwhaplingtont@cloudflare.com', '488 Martine Villages Bernadettetown, AR 39587-0766', 23031, '1998-04-05');
55 |
56 | DROP TABLE IF EXISTS marks;
57 |
58 | CREATE TABLE marks (
59 | id SERIAL PRIMARY KEY,
60 | student_id INT NOT NULL,
61 | mark INT NOT NULL,
62 | subject VARCHAR(255) NOT NULL
63 | );
64 |
65 | INSERT INTO marks (student_id, mark, subject) VALUES ( 3, 23, 'Magic Survival');
66 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 56, 'Planetary Geography');
67 | INSERT INTO marks (student_id, mark, subject) VALUES ( 9, 77, 'Foreign Evolutionary Biology');
68 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 83, 'Intergallactic Relations');
69 | INSERT INTO marks (student_id, mark, subject) VALUES ( 9, 45, 'Grand Strategy');
70 | INSERT INTO marks (student_id, mark, subject) VALUES ( 7, 76, 'Foreign History');
71 | INSERT INTO marks (student_id, mark, subject) VALUES ( 1, 98, 'Alien Dance History');
72 | INSERT INTO marks (student_id, mark, subject) VALUES ( 7, 87, 'Foreign Social Skills');
73 | INSERT INTO marks (student_id, mark, subject) VALUES ( 8, 65, 'Alien Social Skills');
74 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 76, 'Magic Music');
75 | INSERT INTO marks (student_id, mark, subject) VALUES ( 8, 76, 'Alien Genealogy');
76 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 89, 'Magic Rituals');
77 | INSERT INTO marks (student_id, mark, subject) VALUES ( 1, 69, 'Planetary Ecology');
78 | INSERT INTO marks (student_id, mark, subject) VALUES ( 7, 79, 'Military Law');
79 | INSERT INTO marks (student_id, mark, subject) VALUES ( 3, 57, 'Foreign Ethics');
80 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 56, 'Foreign Instrumental Music');
81 | INSERT INTO marks (student_id, mark, subject) VALUES ( 8, 59, 'Foreign Services');
82 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 91, 'Alien Economics');
83 | INSERT INTO marks (student_id, mark, subject) VALUES ( 1, 91, 'Alien Ethics');
84 | INSERT INTO marks (student_id, mark, subject) VALUES ( 9, 23, 'Magic Arts');
85 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 34, 'Alien Social Studies');
86 | INSERT INTO marks (student_id, mark, subject) VALUES ( 7, 54, 'Foreign Political Sciences');
87 | INSERT INTO marks (student_id, mark, subject) VALUES ( 8, 56, 'Terraforming');
88 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 76, 'Transmutation');
89 | INSERT INTO marks (student_id, mark, subject) VALUES ( 1, 98, 'Space Travel');
90 | INSERT INTO marks (student_id, mark, subject) VALUES ( 5, 76, 'Alien Medicine');
91 | INSERT INTO marks (student_id, mark, subject) VALUES ( 3, 98, 'Foreign Statistics');
92 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 100, 'Necromancy');
93 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 00, 'Magic Music');
94 | INSERT INTO marks (student_id, mark, subject) VALUES ( 2, 34, 'Planetary History');
95 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 58, 'Herbalism');
96 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 34, 'Dimensional Manipulation');
97 | INSERT INTO marks (student_id, mark, subject) VALUES ( 4, 67, 'Nutrition Recognition');
98 | INSERT INTO marks (student_id, mark, subject) VALUES ( 3, 56, 'Foreign Pathology');
99 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 88, 'Foreign Arts');
100 | INSERT INTO marks (student_id, mark, subject) VALUES ( 7, 80, 'Alien Bioengineering');
101 | INSERT INTO marks (student_id, mark, subject) VALUES ( 6, 81, 'Alien Physiology');
102 | INSERT INTO marks (student_id, mark, subject) VALUES ( 2, 71, 'Mathematics');
103 | INSERT INTO marks (student_id, mark, subject) VALUES ( 1, 72, 'Foreign Arts');
104 | INSERT INTO marks (student_id, mark, subject) VALUES ( 3, 84, 'Galactic History');
105 | INSERT INTO marks (student_id, mark, subject) VALUES ( 31, 84, 'Galactic History');
106 |
--------------------------------------------------------------------------------
/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM nginx
2 |
3 | COPY ./default.conf /etc/nginx/conf.d/default.conf
4 |
--------------------------------------------------------------------------------
/nginx/default.conf:
--------------------------------------------------------------------------------
1 | upstream client {
2 | server client:3000;
3 | }
4 |
5 | upstream api {
6 | server api:3001;
7 | }
8 |
9 | server {
10 | listen 80;
11 |
12 | location / {
13 | proxy_pass http://client;
14 | }
15 |
16 | location /sockjs-node {
17 | proxy_pass http://client;
18 | proxy_http_version 1.1;
19 | proxy_set_header Upgrade $http_upgrade;
20 | proxy_set_header Connection "Upgrade";
21 | }
22 |
23 | location /api {
24 | rewrite /api/(.*) /$1 break;
25 | proxy_pass http://api;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------