- Introduction
- Features
- Getting Started
- Environment variables
- Project Structure
- Authentication
- Testing
- API Routes
- Contributing
- Contributors
- License
The dmsp_frontend_app is a web application built using NextJS React framework and TypeScript. The app serves up all the pages for the DMP Tool, and uses Apollo GraphQL Client to make requests to the backend server.
The app is a hybrid framework using both frontend and backend logic. The app includes some API endpoints for dealing with authentication - namely for creating an http-only auth cookie, and for checking auth state, and deleting the auth cookie. It also uses middleware to control access to pages based on authentication and roles.
This app is using graphql-codegen to generate types from graphql queries and mutations. Please place your queries in the graphql
directory and name the file like graphql/<name>.<query|mutation>.graphql
per the codegen.ts
config file.
This will generate the generated/graphql.tsx
file, and you can use the generated functions or documents to make the graphql requests.
Once the schema has been added, you will need to run npm run generate
this kicks off a script that builds out Typescript Types for the new schema and queries. The schema is dependent on the graphql server running at dmsp_backend_prototype
in order to successfully generate.
This app was bootstrapped with create-next-app
.
- App Router: Leverages the new App Router for improved routing and page structure.
- API Routes: Custom API routes for handling authentication using JWT tokens.
- Apollo Client: Uses Apollo Client to make GraphQL requests to the backend
- SCSS/CSS Modules: Uses Sass along with CSS Modules for styling.
- Unit Testing: Uses Jest with React Testing Library
- Accessibility Testing: Uses jest-axe package
- UI Components: React Aria Components library used with custom components
- Authentication: Auth tokens from backend stored in cookie. Token is passed via headers in requests to backend
- Node.js v20.9.0 or higher
- npm v10.7.0 or higher
- Docker Desktop -- Docker Desktop gives you Docker Engine, Docker CLI client, and Docker Compose
- Clone the repository
git clone git@github.com:CDLUC3/dmsp_frontend_prototype.git
cd dmsp_frontend_prototype
npm install
- Install dependencies
npm install
For the development environment, the environment variables are stored at .env.local
. This is set as the default env file in jest.setup.ts.
These variables must be set in order for the app to work.
NEXT_PUBLIC_BASE_URL
- Base url for this app (e.g., "http://localhost:3000")NEXT_PUBLIC_SERVER_ENDPOINT
- Base url for backend server (e.g., "http://localhost:4000")NEXT_PUBLIC_GRAPHQL_SERVER_ENDPOINT
- Graphql server schema endpoint (e.g., "http://localhost:4000/graphql")JWT_SECRET
- Secret key for JWT authentication
npm run dev
npm run build
npm run start
This project users Docker for both development and production environments. The setup is managed with docker-compose.yml
files that build off Dockerfile.dev
for development and Dockerfile.prod
for production. Additionally, the project includes a buildspec.yaml
file for AWS CodeBuild, which also references these Dockerfiles.
- Build and run the development Docker containers
docker-compose build
docker-compose up
- To stop the docker container, run
docker-compose down
- Run the following to check that your container is up
docker container ls -a
- Access the site at http://localhost:3000
- Build and run the production Docker container
docker build -f Dockerfile.prod -t dmsp_frontend_prototype:dmsp_frontend_prod .
docker run -p 3000:3000 dmsp_frontend_prototype:dmsp_frontend_prod
- Access the Next.js app at http://localhost:3000
|-- app/
| |-- api
| |-- setCookie
| |-- __tests__
| |-- route.ts
| |-- login
| |-- __tests__
| |-- login.module.scss
| |-- page.tsx
| |-- layout.tsx
| |-- page.tsx
| |-- not-found.tsx
|-- components/
| |-- Header
| |-- __tests__
| |-- header.module.scss
| |-- index.tsx
| |-- context
| |-- AuthContext.tsx
| |-- CsrfContext.tsx
|-- cypress
| |-- e2e
| |-- spec.cy.ts
|-- generated
| |-- graphql.tsx
|-- graphql
| |-- affiliations.query.graphql
|-- lib
| |-- graphql
| |-- client
| |-- apollo-client.ts
|-- public
| |-- images
| |-- dmptool_logo_u166.svg
|-- styles
| |-- globals.scss
| |-- elements.scss
|-- utils
| |-- logger.ts
| |-- authHelper.ts
| |-- authLink.ts
| |-- errorHandler.ts
|-- buildspec.yaml
|-- codegen.ts
|-- docker-compose.yml
|-- DockerFile.dev
|-- Dockerfile.prod
|-- middleware.ts
|-- next.config.mjs
|-- package.json
|-- tsconfig.json
There are currently two context files, AuthContext.tsx and CsrfContext.tsx, that help manage the auth state and the csrf token state.
All forms submitted to the backend need to include the CSRF token in the header of the request. GraphQL queries have inherent handling of csrf protection as long as we remember to include the CONTENT-TYPE
as application/json
in the header, which is currently added by the utils/authLink
used in the apollo client instance.
The endpoint to refresh the csrf token is called when getting a 403 returned from the backend server.
When new components or functions are added, corresponding unit tests should ideally be added. We want to shoot for above 70% coverage. React components are tested using jest and React Testing Library.
Unit tests should generally be placed in a __tests__
folder adjacent to the component or file being tested.
Functional tests are conducted using Cypress. These tests can be run in headless mode using the command npm run cypress:run
or in headed mode is npm run cypress:open
. Functional tests should be placed in the cypress
directory.
GET /api/check-auth
: returns whether user is authenticated based on presence of auth token in cookie
- Clone the repo from github (
git clone git@github.com:CDLUC3/dmsp_frontend_prototype.git
) - Create a new branch prefixing branch with
bug
orfeature
based on type of update (git checkout -b feature/your-feature
) - Add your changes and add commit message (
git add .
;git commit -m "added new feature
)- A pre-commit is run with the
commit
which checks to make sure linting and coverage pass before a commit goes through
- A pre-commit is run with the
- Push to the branch (
git push --set-upstream origin feature/your-feature
) - Open a Pull Request in github
This project is licensed under the MIT License - see the LICENSE for for details.