Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
node_modules
.vscode
.DS_Store
.DS_Store
.nodemon.json
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# GraphQL + React Event Booking API
This code belongs to a tutorial series: [https://github.com/academind/yt-graphql-react-event-booking-api.git](https://github.com/academind/yt-graphql-react-event-booking-api.git)

Learn how to build a GraphQL API (with Node.js) and a React.js frontend from scratch in this series.

# Usage
Choose the right branch in this repository to get the code for the different parts of the series.

Steps if starting from beginning:
- store mongodb credentials in nodemon.json

- npm init
- npm install express --save body-parser
- npm install --save-dev nodemon
- add "start": "nodemon app.js" in scripts package.json
- npm install graphql@15.3.0 express-graphql
- graphql latest not compatible with express-graphql
- express-graphql no longer maintained instead use graphql-http
- install ruru package which bundles ruru module, add code to serve graphiql ide in server.js and restart server
- install: bcryptjs
- install: jsonwebtoken

Install all dependencies
```sh
npm install
```

Run the server
```sh
npm start
```

NOTE:
- #16. CREATE EVENT AFTER SUBMISSION DOES NOT GET UPDATED TO DB
- GraphQL Response: {errors: Array(1), data: null}
Events.jsx:130 TypeError: Cannot read properties of null (reading 'events')
at Events.jsx:127:32
53 changes: 47 additions & 6 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
const express = require('express');
const bodyParser = require('body-parser');
const express = require("express");
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const isAuth = require("./middleware/is-auth");

const { createHandler } = require("graphql-http/lib/use/express");
const { ruruHTML } = require("ruru/server");

const graphQlSchema = require("./graphql/schema/index");
const graphQlResolvers = require("./graphql/resolvers/index");

const app = express();

app.use(bodyParser.json());

app.get('/', (req, res, next) => {
res.send('Hello World!');
})
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
if (req.method === "OPTIONS") {
return res.sendStatus(200);
}
next();
});

app.use(isAuth);

app.use(
"/graphql",
createHandler({
schema: graphQlSchema,
rootValue: graphQlResolvers,
// graphiql: true,
})
);

mongoose
.connect(
`mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@cluster0.mnews.mongodb.net/${process.env.MONGO_DB}?retryWrites=true`
)
.then(() => {
console.log("database connect success");
app.listen(8000);
})
.catch((err) => {
console.log(err);
});

app.listen(3000);
app.get("/", (_req, res) => {
res.type("html");
res.end(ruruHTML({ endpoint: "/graphql" }));
// res.send("hello world");
});
24 changes: 24 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
8 changes: 8 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# React + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
38 changes: 38 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

export default [
{ ignores: ['dist'] },
{
files: ['**/*.{js,jsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parserOptions: {
ecmaVersion: 'latest',
ecmaFeatures: { jsx: true },
sourceType: 'module',
},
},
settings: { react: { version: '18.3' } },
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
...react.configs['jsx-runtime'].rules,
...reactHooks.configs.recommended.rules,
'react/jsx-no-target-blank': 'off',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
},
},
]
13 changes: 13 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
Loading