[
  {
    "path": ".github/FUNDING.yml",
    "content": "custom: ['https://www.buymeacoffee.com/anuraggarg']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. iOS]\n - Browser [e.g. chrome, safari]\n - Version [e.g. 22]\n\n**Smartphone (please complete the following information):**\n - Device: [e.g. iPhone6]\n - OS: [e.g. iOS8.1]\n - Browser [e.g. stock browser, safari]\n - Version [e.g. 22]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/.gitignore",
    "content": "node_modules\nyarn.lock\ndist"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/config/express.ts",
    "content": "/**\n * File containing Express Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { ApolloServer } from 'apollo-server-express';\nimport cors from 'cors';\nimport express from 'express';\nimport * as http from 'http';\nimport schema from '../server/graphql/schema/index';\nimport auth from '../server/middleware/auth';\nimport config from './index';\n\nclass Express {\n  public express: express.Application;\n  public server: ApolloServer = new ApolloServer(schema);\n  public httpServer: http.Server;\n  public init = (): void => {\n    /**\n     * Creating an express application\n     */\n    this.express = express();\n    /**\n     * Middlerware for using CORS\n     */\n    this.express.use(cors({\n      origin(origin, callback) {\n        /**\n         * Allow requests with no origin\n         * Like mobile apps or curl requests\n         */\n        if (!origin) { return callback(null, true); }\n        if (config.allowedOrigins.indexOf(origin) === -1) {\n          const msg = `The CORS policy for this site does not\n          allow access from the specified Origin.`;\n          return callback(new Error(msg), false);\n        }\n        return callback(null, true);\n      }\n    }));\n    /**\n     *  Middlerware for extracting authToken\n     */\n    this.express.use(auth);\n    this.server.applyMiddleware({ app: this.express });\n    this.httpServer = http.createServer(this.express);\n    /**\n     * Installing subscription handlers\n     */\n    this.server.installSubscriptionHandlers(this.httpServer);\n  }\n}\n\nexport default Express;\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/config/index.ts",
    "content": "/**\n * Config file\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport dotenv from 'dotenv';\ndotenv.config();\nexport default {\n    db: process.env.DB,\n    jwtSecret: process.env.JWT_SECRET,\n    port: process.env.PORT,\n    allowedOrigins: ['http://localhost:3000', 'http://yourapp.com', 'http://localhost:4020']\n};\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/index.ts",
    "content": "/**\n * Bootstrap your app\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport Promise from 'bluebird';\nimport mongoose from 'mongoose';\nimport config from './config';\nimport Express from './config/express';\n\n/**\n * Promisify All The Mongoose\n * @param mongoose\n */\nPromise.promisifyAll(mongoose);\n\n/**\n * Connecting Mongoose\n * @param uris\n * @param options\n */\nmongoose.connect(config.db, {\n  bufferMaxEntries: 0,\n  keepAlive: true,\n  reconnectInterval: 500,\n  reconnectTries: 30,\n  socketTimeoutMS: 0,\n  useNewUrlParser: true,\n  useUnifiedTopology: true\n});\n\n/**\n * Throw error when not able to connect to database\n */\nmongoose.connection.on('error', () => {\n  throw new Error(`unable to connect to database: ${config.db}`);\n});\n\n/**\n * Initialize Express\n */\nconst ExpressServer = new Express();\nExpressServer.init();\n\n/**\n * Listen to port\n */\nExpressServer.httpServer.listen(process.env.PORT || config.port, () => {\n  console.log(`🚀  Server ready at ${config.port}`);\n  console.log(\n    `🚀 Server ready at http://localhost:${config.port}${ExpressServer.server.graphqlPath}`\n  );\n  console.log(\n    `🚀 Subscriptions ready at ws://localhost:${config.port}${ExpressServer.server.subscriptionsPath}`\n  );\n});\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/package.json",
    "content": "{\n  \"name\": \"Express_GraphQL_Apollo_Mongodb_Server\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Backend Server for Next.js GraphQL Express Apollo Boilerplate\",\n  \"private\": true,\n  \"main\": \"dist/index.js\",\n  \"scripts\": {\n    \"clean\": \"rm -rf dist\",\n    \"prebuild\": \"tslint -c tslint.json -p tsconfig.json --fix\",\n    \"build\": \"yarn clean && tsc\",\n    \"prestart\": \"yarn build\",\n    \"start\": \"tsc --watch & nodemon dist/index.js\",\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"pre-commit\": \"yarn tslint && yarn build\",\n    \"tslint\": \"tslint --project tsconfig.json\",\n    \"tslint:fix\": \"tslint --project tsconfig.json --fix\"\n  },\n  \"keywords\": [],\n  \"author\": \"Anurag Garg\",\n  \"license\": \"MIT\",\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"yarn pre-commit\"\n    }\n  },\n  \"dependencies\": {\n    \"apollo-server\": \"^2.9.6\",\n    \"apollo-server-express\": \"^2.9.6\",\n    \"bluebird\": \"^3.5.5\",\n    \"dotenv\": \"^8.2.0\",\n    \"express\": \"^4.17.1\",\n    \"jsonwebtoken\": \"^8.5.1\",\n    \"lodash\": \"^4.17.15\",\n    \"mongoose\": \"^5.6.13\"\n  },\n  \"devDependencies\": {\n    \"@types/bluebird\": \"^3.5.29\",\n    \"@types/dotenv\": \"^8.2.0\",\n    \"@types/express\": \"^4.17.2\",\n    \"@types/jsonwebtoken\": \"^8.3.6\",\n    \"@types/lodash\": \"^4.14.149\",\n    \"@types/mongoose\": \"^5.5.41\",\n    \"@types/node\": \"^13.1.7\",\n    \"husky\": \"^4.2.0\",\n    \"nodemon\": \"^1.19.2\",\n    \"tslint\": \"^5.20.1\",\n    \"typescript\": \"^3.7.5\"\n  }\n}\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/graphql/resolvers/index.ts",
    "content": "/**\n * Exporting all resolvers\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { UserMutation, UserQueries, UserSubscription } from './user';\n\nconst rootResolver = {\n  Query: {\n    ...UserQueries\n    // Add other queries here\n  },\n  Mutation: {\n    ...UserMutation\n    // Add other mutations here\n  },\n  Subscription: {\n    ...UserSubscription\n    // Add other subscriptions here\n  }\n};\n\nexport default rootResolver;\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/graphql/resolvers/merge.ts",
    "content": "/**\n * Primary file for extracting proper schema structured objects\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport dateToString from '../../helpers/date';\nimport User from '../../models/user';\n\n/**\n * Get user object with schema typing\n * @param id\n */\nconst getUser = async (id: string) => {\n  try {\n    const user: any = await User.findById(id);\n    return {\n      ...user._doc,\n      _id: user.id,\n      createdAt: dateToString(user._doc.createdAt),\n      updatedAt: dateToString(user._doc.updatedAt)\n    };\n  } catch (err) {\n    throw err;\n  }\n};\n\n/**\n * Get user object with schema typing\n * @param user\n */\nconst transformUser = (user: any) => {\n  return {\n    ...user._doc,\n    _id: user.id,\n    createdAt: dateToString(user._doc.createdAt),\n    updatedAt: dateToString(user._doc.updatedAt)\n  };\n};\n\nexport { getUser, transformUser };\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/graphql/resolvers/user.ts",
    "content": "/**\n * File containing all user queries, mutations and subscriptions\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { PubSub } from 'apollo-server';\nimport jwt from 'jsonwebtoken';\nimport mongoose from 'mongoose';\nimport config from '../../../config';\nimport User from '../../models/user';\nimport { transformUser } from './merge';\nconst pubsub = new PubSub();\n\nconst USER_ADDED = 'USER_ADDED';\n\n/**\n * User Queries\n */\nconst UserQueries = {\n  users: async (parent, args, context) => {\n    try {\n      const users = await User.find();\n      return users.map((user) => {\n        return transformUser(user);\n      });\n    } catch (err) {\n      throw err;\n    }\n  },\n  user: async (parent, { userId }) => {\n    try {\n      const user = await User.findById(userId);\n      return transformUser(user);\n    } catch (err) {\n      throw err;\n    }\n  },\n  login: async (parent, { email, password }) => {\n    try {\n      const user: any = await User.findOne({ email, password });\n      if (!user) {\n        throw new Error('User does not Exists');\n      }\n      const token = jwt.sign({ userId: user.id }, config.jwtSecret, {\n        expiresIn: '1h'\n      });\n      return {\n        userId: user.id,\n        token,\n        tokenExpiration: 1\n      };\n    } catch (err) {\n      throw err;\n    }\n  }\n};\n\n/**\n * User Mutations\n */\nconst UserMutation = {\n  createUser: async (parent: any, { userInput }: any) => {\n    try {\n      const user = await User.findOne({\n        email: userInput.email\n      });\n      if (user) {\n        throw new Error('User already Exists');\n      } else {\n        const newUser = new User({\n          _id: new mongoose.Types.ObjectId(),\n          email: userInput.email,\n          name: userInput.name,\n          password: userInput.password\n        });\n        const savedUser = await newUser.save();\n        pubsub.publish(USER_ADDED, {\n          userAdded: transformUser(savedUser)\n        });\n        const token = jwt.sign({ userId: savedUser.id }, config.jwtSecret, {\n          expiresIn: '1h'\n        });\n        return {\n          userId: savedUser.id,\n          token,\n          tokenExpiration: 1\n        };\n      }\n    } catch (error) {\n      throw error;\n    }\n  },\n  updateUser: async (parent, { userId, updateUser }, context) => {\n    // If not authenticated throw error\n    if (!context.isAuth) {\n      throw new Error('Non Authenticated');\n    }\n    try {\n      const user = await User.findByIdAndUpdate(userId, updateUser, {\n        new: true\n      });\n      return transformUser(user);\n    } catch (error) {\n      throw error;\n    }\n  }\n};\n\n/**\n * User Subscriptions\n */\nconst UserSubscription = {\n  userAdded: {\n    subscribe: () => pubsub.asyncIterator([USER_ADDED])\n  }\n};\n\nexport { UserQueries, UserMutation, UserSubscription };\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/graphql/schema/index.ts",
    "content": "/**\n * Primary file for GraphQL Schema\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { gql } from 'apollo-server-express';\nimport { ApolloServerExpressConfig } from 'apollo-server-express';\nimport resolvers from '../resolvers/index';\n\nconst typeDefs = gql`\n  type Query {\n    users: [User!]!\n    user(userId: ID!): User!\n    login(email: String!, password: String!): AuthData!\n  }\n  type Mutation {\n    createUser(userInput: UserInput): AuthData!\n    updateUser(userId: ID!, updateUser: UpdateUser): User!\n  }\n  type Subscription {\n    userAdded: User\n  }\n  type User {\n    _id: ID!\n    email: String!\n    name: String!\n    password: String\n    createdAt: String!\n    updatedAt: String!\n  }\n  type AuthData {\n    userId: ID!\n    token: String!\n    tokenExpiration: Int!\n  }\n  input UserInput {\n    email: String!\n    name: String!\n    password: String!\n  }\n  input UpdateUser {\n    email: String\n    name: String\n    password: String\n  }\n`;\n\nconst schema: ApolloServerExpressConfig = {\n  typeDefs,\n  resolvers,\n  introspection: true,\n  context: async ({ req, connection, payload }: any) => {\n    if (connection) {\n      return { isAuth: payload.authToken };\n    }\n    return { isAuth: req.isAuth };\n  },\n  playground: true\n};\n\nexport default schema;\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/helpers/date.ts",
    "content": "/**\n * Define nethod for converting date to string\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nconst dateToString = (date: Date) => new Date(date).toISOString();\n\nexport default dateToString;\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/middleware/auth.ts",
    "content": "/**\n * Define middlerware for extracting authToken\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport * as jwt from 'jsonwebtoken';\nimport config from '../../config';\n\nexport default (req: any, res: any, next: any) => {\n  const authHeader = req.get('Authorization');\n  if (!authHeader) {\n    req.isAuth = false;\n    return next();\n  }\n  const token = authHeader.split(' ')[1];\n  if (!token || token === '') {\n    req.isAuth = false;\n    return next();\n  }\n  let decodedToken: any;\n  try {\n    decodedToken = jwt.verify(token, config.jwtSecret);\n  } catch (err) {\n    req.isAuth = false;\n    return next();\n  }\n  if (!decodedToken) {\n    req.isAuth = false;\n    return next();\n  }\n  req.isAuth = true;\n  req.userId = decodedToken.userId;\n  return next();\n};\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/server/models/user.ts",
    "content": "/**\n * Define model for user\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport mongoose from 'mongoose';\n\n/**\n * User Schema\n */\nconst userSchema = new mongoose.Schema(\n  {\n    _id: mongoose.Schema.Types.ObjectId,\n    email: {\n      type: String,\n      required: true\n    },\n    name: {\n      type: String,\n      required: true\n    },\n    password: {\n      type: String\n    }\n  },\n  {\n    timestamps: true\n  }\n);\n\n/**\n * Statics\n */\nuserSchema.statics = {\n  /**\n   * Get User\n   * @param {ObjectId} id - The objectId of user.\n   */\n  get(id: string): mongoose.Document {\n    return this.findById(id)\n      .execAsync()\n      .then((user: any) => {\n        if (user) {\n          return user;\n        }\n      });\n  }\n};\n\nexport default mongoose.model('User', userSchema);\n"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"module\": \"commonjs\",\n    \"pretty\": true,\n    \"sourceMap\": true,\n    \"outDir\": \"dist\",\n    \"importHelpers\": true,\n    \"strict\": true,\n    \"noImplicitAny\": false,\n    \"strictNullChecks\": false,\n    \"noImplicitThis\": true,\n    \"alwaysStrict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": false,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"moduleResolution\": \"node\",\n    \"baseUrl\": \".\",\n    \"allowSyntheticDefaultImports\": true,\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"resolveJsonModule\": true,\n    \"esModuleInterop\": true,\n    \"lib\": [\n      \"es5\",\n      \"es6\",\n      \"dom\",\n      \"es2015.core\",\n      \"es2015.collection\",\n      \"es2015.generator\",\n      \"es2015.iterable\",\n      \"es2015.promise\",\n      \"es2015.proxy\",\n      \"es2015.reflect\",\n      \"es2015.symbol\",\n      \"es2015.symbol.wellknown\",\n      \"esnext.asynciterable\"\n    ]\n  },\n  \"include\": [\"server/**/*\", \"config/**/*\", \"index.ts\"]\n}"
  },
  {
    "path": "Express_GraphQL_Apollo_Mongodb_Server/tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\n    \"tslint:recommended\"\n  ],\n  \"rules\": {\n    \"no-trailing-whitespace\": [true, \"always\"],\n    \"prefer-const\": [true, {\n      \"destructuring\": \"any\"\n    }],\n    \"semicolon\": [true, \"always\"],\n    \"quotemark\": [true, \"single\"],\n    \"trailing-comma\": [\n      true,\n      {\n        \"singleline\": \"never\",\n        \"multiline\": \"never\"\n      }\n    ],\n    \"object-literal-sort-keys\": false,\n    \"no-console\": false\n  },\n  \"linterOptions\": {\n    \"exclude\": [\n      \"node_modules/**\",\n      \"dist/**/*.ts\"\n    ]\n  },\n  \"rulesDirectory\": []\n}"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2020 Anurag Garg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n<a href=\"https://twitter.com/AnuragG94634191\"><img src=\"./Gifs/boilerplate.gif\" title=\"Anurag Garg\"  alt=\"Anurag Garg\"></a>\n</p>\n\n<h1 align=\"center\">Next.js React GraphQL Express Apollo Boilerplate</h1>\n\n<p align=\"center\">Performance oriented Next.js\nand React.js application boilerplate with Typescript, Express.js, GraphQL, Apollo and Sass\n</p>\n\n<p align=\"center\">\n<img src=\"http://img.shields.io/travis/badges/badgerbadgerbadger.svg?style=flat-square\" alt=\"build\"/>\n<img src=\"https://img.shields.io/github/issues/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate\" alt=\"build\"/>\n<img src=\"https://img.shields.io/github/issues-pr/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate\" alt=\"build\"/>\n<img src=\"http://img.shields.io/:license-mit-blue.svg?style=flat-square\" alt=\"build\"/>\n</p>\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Installation](#installation)\n  - [Step 1: Set up the Development Environment](#step-1-set-up-the-development-environment)\n  - [Step 2: Set up Env](#step-2-set-up-env)\n  - [Step 3: Install dependencies](#step-3-install-dependencies)\n  - [Step 4: Running Locally](#step-4-running-locally)\n  - [Step 5: Deployment](#step-5-deployment)\n- [Features](#features)\n  - [GraphQL](#graphql)\n  - [Express](#express)\n  - [Next.js](#nextjs)\n  - [React](#react)\n  - [React Apollo](#react-apollo)\n  - [Typescript](#typescript)\n  - [JsonWebToken](#jsonwebtoken)\n  - [TSLint](#tslint)\n  - [Husky](#husky)\n  - [Bluebird](#bluebird)\n  - [Cors](#cors)\n- [Contributing](#contributing)\n  - [Step 1](#step-1)\n  - [Step 2](#step-2)\n  - [Step 3](#step-3)\n- [Support](#support)\n- [Donations](#donations)\n- [License](#license)\n\n## Installation\n\nClone this repo to your local machine using `https://github.com/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate`\n\n### Step 1: Set up the Development Environment\n\nYou need to set up your development environment before you can do anything.\n\n**Install [Node.js and NPM](https://nodejs.org/en/download/)**\n\n- on OSX use [homebrew](http://brew.sh) `brew install node`\n- on Windows use [chocolatey](https://chocolatey.org/) `choco install nodejs`\n\n**Install yarn globally**\n\n```bash\nyarn global add yarn\n```\n\n> NOTE : If you work with a mac, we recommend to use homebrew for the installation.\n\n**Install MongoDB**\nOnce Brew is installed, it is time to install MongoDB by issuing the following command on the Terminal:\n\n```bash\nbrew install mongodb\n```\n\n### Step 2: Set up Env\n\nOpen .env file in a editor and add your configuration for database and other required fields.\n\n```ts\nNODE_ENV = development;\nJWT_SECRET = \"somesuperkey\";\nDB =\n  \"mongodb://localhost/nextjs_graphql_express_apollo_boilerplate_development\";\nPORT = 4020;\n```\n\n### Step 3: Install dependencies\n\nNavigate to the server, nextjs and react app directories and run the below command:\n\n```bash\n$ yarn\n```\n\n### Step 4: Running Locally\n\nNavigate to the **Express Server** directory and run the below command in your terminal :\n\n```bash\n$ yarn start\n```\n\nNow navigate to **Nextjs App** directory and run the below command in your terminal :\n\n```bash\n$ yarn dev\n```\n\nNow navigate to **React App** directory and run the below command in your terminal :\n\n```bash\n$ yarn start\n```\n\n### Step 5: Deployment\n\nTo deploy with ZEIT Now through your terminal, you will need to install Now CLI, a frequently updated, and open-source, command-line interface.\n\nYou can get Now CLI from either npm or Yarn. Using npm, run the following command from your terminal:\n\n```bash\n$ npm i -g now\n```\n\nTo verify that you have installed Now CLI, try running now help from your terminal.\n\nWith Now CLI installed, you can now login using the following command:\n\n```bash\n$ now login\n```\n\nNavigate to **Nextjs App** directory and run the below commands in order :\n\n```bash\n$ now\n```\n\nOnce deployed, you will get a preview URL that is assigned on each deployment to share the latest changes under the same address.\n\n## Features\n\n### GraphQL\n\nGraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.\n\n### Express\n\nExpress is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.\n\n### Next.js\n\nNext.js extends React to provide a powerful method for loading a page's initial data, no matter where it is coming from. With a single place to prepopulate page context, server-side rendering with Next.js seamlessly integrates with any existing data-fetching strategy.\n\n### React\n\nReact makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes.\n\n### React Apollo\n\nReact Apollo allows you to fetch data from your GraphQL server and use it in building complex and reactive UIs using the React framework. React Apollo may be used in any context that React may be used. In the browser, in React Native, or in Node.js when you want to do server-side rendering.\n\n### Typescript\n\nTypeScript is an open-source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript, and adds optional static typing to the language. TypeScript is designed for development of large applications and transcompiles to JavaScript.\n\n### JsonWebToken\n\nJSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties.\n\n### TSLint\n\nTSLint is an extensible static analysis tool that checks TypeScript code for readability, maintainability, and functionality errors\n\n### Husky\n\nHusky can prevent bad git commit, git push and more 🐶 woof!\n\n### Bluebird\n\nBluebird is a fully featured promise library with focus on innovative features and performance.\n\n### Cors\n\nCross-origin resource sharing is a mechanism that allows restricted resources on a web page to be requested from another domain outside the domain from which the first resource was served\n\n## Contributing\n\n> To get started...\n\n### Step 1\n\n- **Option 1**\n\n  - 🍴 Fork this repo!\n\n- **Option 2**\n  - 👯 Clone this repo to your local machine using `https://github.com/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate`\n\n### Step 2\n\n- **HACK AWAY!** 🔨🔨🔨\n\n### Step 3\n\n- 🔃 Create a new pull request using <a href=\"https://github.com/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate\" target=\"_blank\">`https://github.com/garganurag893/Next.js_GraphQL_Express_Apollo_Boilerplate`</a>.\n\n## Support\n\nReach out to me at one of the following places!\n\n- Twitter at <a href=\"https://twitter.com/AnuragG94634191\" target=\"_blank\">https://twitter.com/AnuragG94634191</a>\n- Medium at <a href=\"https://medium.com/@garganurag893\" target=\"_blank\">https://medium.com/@garganurag893</a>\n- Instagram at <a href=\"https://www.instagram.com/the_only_anurag/\" target=\"_blank\">https://www.instagram.com/the_only_anurag/</a>\n- Email at garganurag893@gmail.com\n\n## Donations\n\nIf this boilerplate help save your valuable time and you feel to help me donate now to help me create more amazing stuff.\n\n[![Support via Paypal](https://www.paypalobjects.com/webstatic/mktg/Logo/pp-logo-200px.png)](https://paypal.me/garganurag893?locale.x=en_GB)\n\n<p>\n<img src=\"https://www.komando.com/wp-content/uploads/2019/05/google-pay-badge.png\" alt=\"Support via GooglePay\" height=\"50\"/>\n</p>\n<h5>+919468026011\n</h5>\n\n## License\n\n[![License](http://img.shields.io/:license-mit-blue.svg?style=flat-square)](http://badges.mit-license.org)\n\n- **[MIT license](http://opensource.org/licenses/mit-license.php)**\n- Copyright 2020 © <a href=\"https://twitter.com/AnuragG94634191\" target=\"_blank\">Anurag Garg</a>.\n"
  },
  {
    "path": "nextjs-app/.eslintrc.js",
    "content": "module.exports = {\n    parser: '@typescript-eslint/parser',\n    extends: [\n        'plugin:@typescript-eslint/recommended',\n        'prettier/@typescript-eslint',\n        'react-app',\n        'plugin:prettier/recommended',\n    ],\n    plugins: ['@typescript-eslint', 'react'],\n    rules: {\n        \"@typescript-eslint/explicit-function-return-type\":0,\n        \"@typescript-eslint/no-explicit-any\":0,\n    },\n  };"
  },
  {
    "path": "nextjs-app/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n.env*\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "nextjs-app/.prettierrc.js",
    "content": "module.exports = {\n  useTabs: false,\n  printWidth: 80,\n  singleQuote: true,\n  trailingComma: 'es5',\n  jsxBracketSameLine: true,\n  noSemi: false\n};"
  },
  {
    "path": "nextjs-app/next-env.d.ts",
    "content": "/// <reference types=\"next\" />\n/// <reference types=\"next/types/global\" />\n"
  },
  {
    "path": "nextjs-app/package.json",
    "content": "{\n  \"name\": \"nextjs-graphql-apollo-client\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\",\n    \"lint\": \"eslint './**/*.{ts,js,tsx}'\"\n  },\n  \"author\": \"Anurag Garg\",\n  \"license\": \"MIT\",\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"./**/*.{js,jsx,ts,tsx,css,scss}\": [\n      \"prettier --write\",\n      \"yarn lint\"\n    ]\n  },\n  \"dependencies\": {\n    \"@apollo/react-components\": \"^3.1.3\",\n    \"@apollo/react-hooks\": \"^3.1.3\",\n    \"apollo-cache-inmemory\": \"^1.6.5\",\n    \"apollo-client\": \"^2.6.8\",\n    \"apollo-link-batch-http\": \"^1.2.13\",\n    \"apollo-link-http\": \"^1.5.16\",\n    \"apollo-link-ws\": \"^1.0.19\",\n    \"graphql\": \"^14.5.8\",\n    \"graphql-tag\": \"^2.10.1\",\n    \"isomorphic-unfetch\": \"^3.0.0\",\n    \"js-cookie\": \"^2.2.1\",\n    \"next\": \"9.2.0\",\n    \"next-cookies\": \"^2.0.3\",\n    \"next-with-apollo\": \"^4.3.0\",\n    \"react\": \"16.12.0\",\n    \"react-apollo\": \"^3.1.3\",\n    \"react-dom\": \"16.12.0\",\n    \"react-toastify\": \"^5.5.0\",\n    \"subscriptions-transport-ws\": \"^0.9.16\"\n  },\n  \"devDependencies\": {\n    \"@types/next\": \"^9.0.0\",\n    \"@types/node\": \"^13.1.8\",\n    \"@types/react\": \"^16.9.17\",\n    \"@typescript-eslint/eslint-plugin\": \"^2.16.0\",\n    \"@typescript-eslint/parser\": \"^2.16.0\",\n    \"babel-eslint\": \"^10.0.3\",\n    \"eslint\": \"^6.8.0\",\n    \"eslint-config-prettier\": \"^6.9.0\",\n    \"eslint-config-react-app\": \"^5.1.0\",\n    \"eslint-plugin-flowtype\": \"^4\",\n    \"eslint-plugin-import\": \"^2.20.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.2.3\",\n    \"eslint-plugin-prettier\": \"^3.1.2\",\n    \"eslint-plugin-react\": \"^7.18.0\",\n    \"eslint-plugin-react-hooks\": \"^2.3.0\",\n    \"husky\": \"^4.2.0\",\n    \"lint-staged\": \"^10.0.2\",\n    \"prettier\": \"^1.19.1\",\n    \"typescript\": \"^3.7.5\"\n  }\n}\n"
  },
  {
    "path": "nextjs-app/pages/_app.tsx",
    "content": "/**\n * App Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport App from 'next/app';\nimport { ApolloProvider } from '@apollo/react-hooks';\nimport { ToastContainer } from 'react-toastify';\nimport 'react-toastify/dist/ReactToastify.css';\nimport withData from '../src/configureClient';\n\nclass MyApp extends App<any> {\n  render() {\n    const { Component, pageProps, apollo } = this.props;\n    return (\n      <ApolloProvider client={apollo}>\n        <Component {...pageProps} />\n        <ToastContainer\n          position=\"top-right\"\n          autoClose={2000}\n          hideProgressBar={false}\n          newestOnTop={false}\n          closeOnClick\n          rtl={false}\n          draggable\n          pauseOnHover\n        />\n      </ApolloProvider>\n    );\n  }\n}\n\n// Wraps all components in the tree with the data provider\nexport default withData(MyApp);\n"
  },
  {
    "path": "nextjs-app/pages/index.tsx",
    "content": "/**\n * Main Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Login from '../src/components/Login';\nimport Footer from '../src/components/Footer';\n\nconst Home: React.SFC = () => {\n  return (\n    <div className=\"mainContainer\">\n      <div className=\"container\">\n        <h1 className=\"heading\">Welcome</h1>\n        <Login />\n      </div>\n      <Footer />\n      <style jsx>\n        {`\n          .mainContainer {\n            height: 100%;\n            min-height: 100vh;\n            width: 100%;\n          }\n          .container {\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            flex-flow: row wrap;\n            padding: 8rem 0rem !important;\n          }\n          .heading {\n            color: white;\n            text-align: center;\n            font-size: 5rem;\n            padding: 2rem;\n          }\n          @media only screen and (max-width: 740px) {\n            .container {\n              padding: 3rem 0rem !important;\n            }\n          }\n        `}\n      </style>\n      <style jsx global>\n        {`\n          h1,\n          h2 {\n            margin: 0;\n            font-family: Candara;\n          }\n          body {\n            margin: 0;\n            padding: 0;\n            height: 100%;\n            min-height: 100vh;\n            font-family: Candara;\n            background: #355c7d;\n            background: -webkit-linear-gradient(\n              to right,\n              #c06c84,\n              #6c5b7b,\n              #355c7d\n            );\n            background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n          }\n        `}\n      </style>\n    </div>\n  );\n};\n\nexport default Home;\n"
  },
  {
    "path": "nextjs-app/pages/signup.tsx",
    "content": "/**\n * SignUp Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Router from 'next/router';\nimport { toast } from 'react-toastify';\nimport Footer from '../src/components/Footer';\nimport Cookies from 'js-cookie';\nimport { Mutation } from '@apollo/react-components';\nimport CREATE_USER from '../src/graphql/mutation/createUser';\nimport { setToken } from '../src/configureClient';\nimport { validateEmail } from '../src/utils/validation';\n\ninterface SignUpState {\n  [key: string]: any;\n  name: string;\n  email: string;\n  password: string;\n}\n\nclass SignUp extends React.PureComponent<any, SignUpState> {\n  constructor(props) {\n    super(props);\n    this.state = {\n      name: '',\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (createUser, event) => {\n    try {\n      event.preventDefault();\n      const { state } = this;\n      if (validateEmail(state.email)) {\n        const data = await createUser({\n          variables: {\n            userInput: { ...state },\n          },\n        });\n        const { token, userId } = data.createUser;\n        setToken(token);\n        Cookies.set('userId', userId, { expires: 7 });\n        Router.replace('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Check your connection');\n    }\n  };\n  render() {\n    const { state } = this;\n    return (\n      <div className=\"container\">\n        <h1 className=\"heading\">Sign Up</h1>\n        <Mutation mutation={CREATE_USER}>\n          {(createUser, { loading, error }) => (\n            <form\n              onSubmit={event => this.handleSubmit(createUser, event)}\n              className=\"signup-form\">\n              <input\n                type=\"text\"\n                placeholder=\"Name\"\n                name=\"name\"\n                value={state.name}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input\n                type=\"text\"\n                placeholder=\"Email\"\n                name=\"email\"\n                value={state.email}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input\n                type=\"password\"\n                placeholder=\"Password\"\n                name=\"password\"\n                value={state.password}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input type=\"submit\" value=\"Submit\" className=\"signup-button\" />\n            </form>\n          )}\n        </Mutation>\n        <Footer />\n        <style jsx>\n          {`\n            .container {\n              height: 100%;\n              min-height: 100vh;\n              width: 100%;\n              display: flex;\n              justify-content: center;\n              align-items: center;\n              flex-flow: column wrap;\n            }\n            .heading {\n              color: white;\n              text-align: center;\n              font-size: 5rem;\n              padding: 5rem 0rem;\n            }\n            form {\n              display: flex;\n              flex-flow: column wrap;\n              justify-content: center;\n              align-items: center;\n            }\n            .signup-input-box {\n              background-color: white;\n              border-radius: 14px 0px 14px 1px;\n              -moz-border-radius: 14px 0px 14px 1px;\n              -webkit-border-radius: 14px 0px 14px 1px;\n              border: 0px solid #000000;\n              box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n              border: 0;\n              width: 15rem;\n              padding: 0.5rem;\n              height: 2rem;\n              margin-bottom: 2rem;\n              font-family: Candara;\n            }\n            .signup-button {\n              background-color: white;\n              border-radius: 14px 0px 14px 1px;\n              -moz-border-radius: 14px 0px 14px 1px;\n              -webkit-border-radius: 14px 0px 14px 1px;\n              border: 0px solid #000000;\n              box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n              width: 15rem;\n              font-size: 0.9rem;\n              padding: 0.5rem;\n              height: 3rem;\n              margin: 2rem;\n              font-family: Candara;\n              transition: transform 0.2s;\n              cursor: pointer;\n            }\n            .signup-button:hover {\n              transform: scale(1.1);\n              background: #355c7d;\n              background: -webkit-linear-gradient(\n                to right,\n                #c06c84,\n                #6c5b7b,\n                #355c7d\n              );\n              background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n              color: white;\n            }\n            input:focus {\n              outline: none;\n            }\n          `}\n        </style>\n        <style jsx global>\n          {`\n            h1,\n            h2 {\n              margin: 0;\n              font-family: Candara;\n            }\n            body {\n              margin: 0;\n              padding: 0;\n              height: 100%;\n              min-height: 100vh;\n              font-family: Candara;\n              background: #355c7d;\n              background: -webkit-linear-gradient(\n                to right,\n                #c06c84,\n                #6c5b7b,\n                #355c7d\n              );\n              background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n            }\n          `}\n        </style>\n      </div>\n    );\n  }\n}\n\nexport default SignUp;\n"
  },
  {
    "path": "nextjs-app/pages/subscription.tsx",
    "content": "/**\n * Subscription Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { useSubscription } from '@apollo/react-hooks';\nimport { UserCard } from '../src/components/Card';\nimport USER_ADDED from '../src/graphql/subscription/users';\nimport { withAuthSync } from '../src/utils/auth';\n\nconst Subscription = () => {\n  const { data, loading, error } = useSubscription(USER_ADDED);\n  let message = 'New User';\n  if (loading) message = 'Listening...';\n  if (error) message = `Error! ${error.message}`;\n  if (data && data.userAdded.length <= 0) message = 'No New User Added';\n  return (\n    <div className=\"container\">\n      <h1 className=\"heading\">{message}</h1>\n      {data && data.userAdded && (\n        <div className=\"listContainer\">\n          <UserCard img=\"./user.png\" user={data.userAdded} />\n        </div>\n      )}\n      <style jsx>\n        {`\n          .container {\n            height: 100%;\n            min-height: 100vh;\n            width: 100%;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            flex-flow: column wrap;\n          }\n          .listContainer {\n            display: flex;\n            flex-flow: wrap row;\n            justify-content: space-evenly;\n            align-items: center;\n          }\n          .heading {\n            color: white;\n            text-align: center;\n            font-size: 5rem;\n            padding: 0rem 0 5rem;\n          }\n        `}\n      </style>\n      <style jsx global>\n        {`\n          h1,\n          h2 {\n            margin: 0;\n            font-family: Candara;\n          }\n          body {\n            margin: 0;\n            padding: 0;\n            height: 100%;\n            min-height: 100vh;\n            font-family: Candara;\n            background: #355c7d;\n            background: -webkit-linear-gradient(\n              to right,\n              #c06c84,\n              #6c5b7b,\n              #355c7d\n            );\n            background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n          }\n        `}\n      </style>\n    </div>\n  );\n};\n\nexport default withAuthSync(Subscription);\n"
  },
  {
    "path": "nextjs-app/pages/update.tsx",
    "content": "/**\n * Update Profile Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Router from 'next/router';\nimport { toast } from 'react-toastify';\nimport Footer from '../src/components/Footer';\nimport { Mutation } from '@apollo/react-components';\nimport { validateEmail } from '../src/utils/validation';\nimport UPDATE_USER from '../src/graphql/mutation/updateUser';\nimport { withAuthSync } from '../src/utils/auth';\n\ninterface UpdateState {\n  [key: string]: any;\n  name: string;\n  email: string;\n  password: string;\n}\n\nclass Update extends React.PureComponent<any, UpdateState> {\n  constructor(props) {\n    super(props);\n    this.state = {\n      name: '',\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (updateUser, event) => {\n    try {\n      event.preventDefault();\n      const { state, props } = this;\n      if (validateEmail(state.email)) {\n        await updateUser({\n          variables: {\n            userId: props.userId,\n            updateUser: { ...state },\n          },\n        });\n        toast.success('Profile Updated');\n        Router.push('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Check your connection');\n    }\n  };\n  render() {\n    const { state } = this;\n    return (\n      <div className=\"container\">\n        <h1 className=\"heading\">Update Profile</h1>\n        <Mutation mutation={UPDATE_USER}>\n          {updateUser => (\n            <form\n              onSubmit={event => this.handleSubmit(updateUser, event)}\n              className=\"update-form\">\n              <input\n                type=\"text\"\n                placeholder=\"Name\"\n                name=\"name\"\n                value={state.name}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input\n                type=\"text\"\n                placeholder=\"Email\"\n                name=\"email\"\n                value={state.email}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input\n                type=\"password\"\n                placeholder=\"Password\"\n                name=\"password\"\n                value={state.password}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input type=\"submit\" value=\"Submit\" className=\"update-button\" />\n            </form>\n          )}\n        </Mutation>\n        <Footer />\n        <style jsx>\n          {`\n            .container {\n              height: 100%;\n              min-height: 100vh;\n              width: 100%;\n              display: flex;\n              justify-content: center;\n              align-items: center;\n              flex-flow: column wrap;\n            }\n            .heading {\n              color: white;\n              text-align: center;\n              font-size: 5rem;\n              padding: 5rem 0rem;\n            }\n            form {\n              display: flex;\n              flex-flow: column wrap;\n              justify-content: center;\n              align-items: center;\n            }\n            .update-input-box {\n              background-color: white;\n              border-radius: 14px 0px 14px 1px;\n              -moz-border-radius: 14px 0px 14px 1px;\n              -webkit-border-radius: 14px 0px 14px 1px;\n              border: 0px solid #000000;\n              box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n              border: 0;\n              width: 15rem;\n              padding: 0.5rem;\n              height: 2rem;\n              margin-bottom: 2rem;\n              font-family: Candara;\n            }\n            .update-button {\n              background-color: white;\n              border-radius: 14px 0px 14px 1px;\n              -moz-border-radius: 14px 0px 14px 1px;\n              -webkit-border-radius: 14px 0px 14px 1px;\n              border: 0px solid #000000;\n              box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n              width: 15rem;\n              font-size: 0.9rem;\n              padding: 0.5rem;\n              height: 3rem;\n              margin: 2rem;\n              font-family: Candara;\n              transition: transform 0.2s;\n              cursor: pointer;\n            }\n            .update-button:hover {\n              transform: scale(1.1);\n              background: #355c7d;\n              background: -webkit-linear-gradient(\n                to right,\n                #c06c84,\n                #6c5b7b,\n                #355c7d\n              );\n              background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n              color: white;\n            }\n            input:focus {\n              outline: none;\n            }\n          `}\n        </style>\n        <style jsx global>\n          {`\n            h1,\n            h2 {\n              margin: 0;\n              font-family: Candara;\n            }\n            body {\n              margin: 0;\n              padding: 0;\n              height: 100%;\n              min-height: 100vh;\n              font-family: Candara;\n              background: #355c7d;\n              background: -webkit-linear-gradient(\n                to right,\n                #c06c84,\n                #6c5b7b,\n                #355c7d\n              );\n              background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n            }\n          `}\n        </style>\n      </div>\n    );\n  }\n}\n\nexport default withAuthSync(Update);\n"
  },
  {
    "path": "nextjs-app/pages/users.tsx",
    "content": "/**\n * User List Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport List from '../src/components/List';\nimport GET_USERS from '../src/graphql/query/user';\nimport { withAuthSync } from '../src/utils/auth';\n\ninterface User {\n  name: string;\n  _id: string;\n  email: string;\n}\n\ninterface Data {\n  users: [User];\n}\n\ninterface UserProps {\n  loading: boolean;\n  data: Data;\n  error: string;\n}\n\nconst Users = (props: UserProps) => {\n  const { loading, error, data } = props;\n  let message = 'Users';\n  if (loading) message = 'Loading...';\n  if (error) message = `Error! ${error}`;\n  if (data && data.users.length <= 0) message = 'No Users';\n  return (\n    <div className=\"container\">\n      <h1 className=\"heading\">{message}</h1>\n      {data && data.users.length > 0 && (\n        <div className=\"listContainer\">\n          <List img=\"./user.png\" data={data.users} />\n        </div>\n      )}\n      <style jsx>\n        {`\n          .container {\n            height: 100%;\n            min-height: 100vh;\n            width: 100%;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            flex-flow: column wrap;\n          }\n          .listContainer {\n            display: flex;\n            flex-flow: wrap row;\n            justify-content: space-evenly;\n            align-items: center;\n          }\n          .heading {\n            color: white;\n            text-align: center;\n            font-size: 5rem;\n            padding: 0rem 0 5rem;\n          }\n        `}\n      </style>\n      <style jsx global>\n        {`\n          h1,\n          h2 {\n            margin: 0;\n            font-family: Candara;\n          }\n          body {\n            margin: 0;\n            padding: 0;\n            height: 100%;\n            min-height: 100vh;\n            font-family: Candara;\n            background: #355c7d;\n            background: -webkit-linear-gradient(\n              to right,\n              #c06c84,\n              #6c5b7b,\n              #355c7d\n            );\n            background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n          }\n        `}\n      </style>\n    </div>\n  );\n};\n\nUsers.getInitialProps = async ctx => {\n  try {\n    const { data, loading } = await ctx.apolloClient.query({\n      query: GET_USERS,\n    });\n    return { data, loading };\n  } catch (error) {\n    return {\n      error: 'Failed to fetch',\n    };\n  }\n};\n\nexport default withAuthSync(Users);\n"
  },
  {
    "path": "nextjs-app/pages/welcome.tsx",
    "content": "/**\n * Welcome Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Card from '../src/components/Card';\nimport Footer from '../src/components/Footer';\nimport { withAuthSync } from '../src/utils/auth';\n\nconst Welcome: React.SFC = () => {\n  return (\n    <div className=\"container\">\n      <h1 className=\"heading\">Welcome</h1>\n      <div className=\"cardContainer\">\n        <Card title=\"Query\" href=\"/users\" />\n        <Card title=\"Mutation\" href=\"/update\" />\n        <Card title=\"Subscription\" href=\"/subscription\" />\n      </div>\n      <Footer />\n      <style jsx>\n        {`\n          .container {\n            height: 100%;\n            min-height: 100vh;\n            width: 100%;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            flex-flow: column wrap;\n          }\n          .cardContainer {\n            display: flex;\n            flex-flow: wrap row;\n            justify-content: center;\n            align-items: center;\n          }\n          .heading {\n            color: white;\n            text-align: center;\n            font-size: 5rem;\n            padding: 6rem 0rem;\n          }\n        `}\n      </style>\n      <style jsx global>\n        {`\n          h1,\n          h2 {\n            margin: 0;\n            font-family: Candara;\n          }\n          body {\n            margin: 0;\n            padding: 0;\n            height: 100%;\n            min-height: 100vh;\n            font-family: Candara;\n            background: #355c7d;\n            background: -webkit-linear-gradient(\n              to right,\n              #c06c84,\n              #6c5b7b,\n              #355c7d\n            );\n            background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n          }\n        `}\n      </style>\n    </div>\n  );\n};\n\nexport default withAuthSync(Welcome);\n"
  },
  {
    "path": "nextjs-app/src/components/Card.tsx",
    "content": "/**\n * Card Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Link from 'next/link';\n\ninterface User {\n  name: string;\n  _id: string;\n  email: string;\n}\n\ninterface CardProps {\n  title: string;\n  href: string;\n}\n\ninterface UserCardProps {\n  user: User;\n  img: string;\n}\n\nconst Card: React.SFC<CardProps> = props => {\n  return (\n    <Link href={props.href}>\n      <div className=\"card\">\n        <h2>{props.title}</h2>\n        <style jsx>\n          {`\n            .card {\n              display: flex;\n              height: 5rem;\n              width: 20rem;\n              justify-content: center;\n              padding: 2rem;\n              align-self: stretch;\n              align-items: center;\n              background-color: white;\n              margin: 2rem;\n              border-radius: 14px 0px 14px 1px;\n              -moz-border-radius: 14px 0px 14px 1px;\n              -webkit-border-radius: 14px 0px 14px 1px;\n              border: 0px solid #000000;\n              box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n              transition: transform 0.2s;\n              cursor: pointer;\n            }\n            .card:hover {\n              transform: scale(1.1);\n            }\n            h2 {\n              font-size: 2rem;\n            }\n          `}\n        </style>\n      </div>\n    </Link>\n  );\n};\n\nexport const UserCard: React.SFC<UserCardProps> = props => {\n  return (\n    <div key={props.user._id} className=\"listCard\">\n      <img src={props.img} alt=\"user\" height=\"90\" />\n      <div className=\"userCardDetails\">\n        <h2>{props.user.name}</h2>\n        <h2>{props.user.email}</h2>\n      </div>\n      <style jsx>\n        {`\n          .listCard {\n            display: flex;\n            flex-flow: wrap row;\n            justify-content: space-between;\n            padding: 2rem;\n            -webkit-align-self: stretch;\n            align-self: stretch;\n            align-items: center;\n            background-color: white;\n            margin: 2rem;\n            width: 20rem;\n            border-radius: 14px 0px 14px 1px;\n            -moz-border-radius: 14px 0px 14px 1px;\n            -webkit-border-radius: 14px 0px 14px 1px;\n            border: 0px solid #000000;\n            box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n            transition: transform 0.2s;\n          }\n          .userCardDetails {\n            display: flex;\n            flex-flow: wrap column;\n            justify-content: space-between;\n            align-items: flex-end;\n            height: 3rem;\n          }\n          h2 {\n            font-size: 1rem;\n            text-align: right;\n          }\n          img {\n            margin-right: 2rem;\n          }\n        `}\n      </style>\n    </div>\n  );\n};\n\nexport default Card;\n"
  },
  {
    "path": "nextjs-app/src/components/Footer.tsx",
    "content": "/**\n * Footer Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\n\nconst Footer: React.SFC<any> = props => {\n  return (\n    <footer className=\"footer\">\n      <div className=\"footer-text-container\">\n        <p>\n          &copy; Copyright 2020{' '}\n          <a href=\"https://twitter.com/AnuragG94634191\">Anurag Garg</a>\n        </p>\n      </div>\n      <style jsx>\n        {`\n          .footer {\n            color: rgba(255, 255, 255, 0.5);\n            margin-top: auto !important;\n          }\n          .footer-text-container {\n            font-size: 1rem;\n            font-weight: 400;\n            line-height: 1.5;\n            text-shadow: 0 0.05rem 0.1rem rgba(0, 0, 0, 0.5);\n            text-align: center !important;\n            color: rgba(255, 255, 255, 0.5);\n          }\n          a {\n            text-decoration: none;\n            color: white;\n          }\n        `}\n      </style>\n    </footer>\n  );\n};\n\nexport default Footer;\n"
  },
  {
    "path": "nextjs-app/src/components/List.tsx",
    "content": "/**\n * List Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { UserCard } from './Card';\n\ninterface User {\n  name: string;\n  _id: string;\n  email: string;\n}\n\ninterface ListProps {\n  data: [User];\n  img: string;\n}\n\nconst List: React.SFC<ListProps> = props => {\n  return (\n    <>\n      {props.data.map((user: User) => (\n        <UserCard key={user._id} user={user} img={props.img} />\n      ))}\n      <style jsx>\n        {`\n          .List:hover {\n            transform: scale(1.1);\n          }\n          h2 {\n            font-size: 1rem;\n            text-align: right;\n          }\n          img {\n            margin-right: 2rem;\n          }\n        `}\n      </style>\n    </>\n  );\n};\n\nexport default List;\n"
  },
  {
    "path": "nextjs-app/src/components/Login.tsx",
    "content": "/**\n * Login Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Router from 'next/router';\nimport { toast } from 'react-toastify';\nimport { ApolloConsumer } from 'react-apollo';\nimport LOGIN_USER from '../graphql/query/login';\nimport { validateEmail } from '../utils/validation';\nimport { setToken } from '../configureClient';\nimport Cookies from 'js-cookie';\n\ninterface LoginState {\n  [key: string]: any;\n  email: string;\n  password: string;\n}\n\nclass Login extends React.PureComponent<any, LoginState> {\n  constructor(props) {\n    super(props);\n    this.state = {\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (event: any, client: any) => {\n    try {\n      event.preventDefault();\n      const { state } = this;\n      if (validateEmail(state.email)) {\n        const { data } = await client.query({\n          query: LOGIN_USER,\n          variables: { ...state },\n        });\n        const { token, userId } = data.login;\n        setToken(token);\n        Cookies.set('userId', userId, { expires: 7 });\n        Router.replace('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Not Authenticated');\n    }\n  };\n\n  render() {\n    const { state } = this;\n    return (\n      <ApolloConsumer>\n        {client => (\n          <form\n            onSubmit={e => this.handleSubmit(e, client)}\n            className=\"login-form\">\n            <input\n              type=\"text\"\n              placeholder=\"Email\"\n              name=\"email\"\n              value={state.email}\n              onChange={this.handleChange}\n              className=\"login-input-box\"\n              required\n            />\n            <input\n              type=\"password\"\n              placeholder=\"Password\"\n              name=\"password\"\n              value={state.password}\n              onChange={this.handleChange}\n              className=\"login-input-box\"\n              required\n            />\n            <input type=\"submit\" value=\"Submit\" className=\"login-button\" />\n            <p onClick={() => Router.push('/signup')}>\n              New user ? <b>Sign Up</b>\n            </p>\n            <style jsx>\n              {`\n                form {\n                  display: flex;\n                  flex-flow: column wrap;\n                  justify-content: center;\n                  align-items: center;\n                  border-left: 1px solid white;\n                  padding: 2rem;\n                }\n                p {\n                  color: white;\n                  cursor: pointer;\n                }\n                .login-input-box {\n                  background-color: white;\n                  border-radius: 14px 0px 14px 1px;\n                  -moz-border-radius: 14px 0px 14px 1px;\n                  -webkit-border-radius: 14px 0px 14px 1px;\n                  border: 0px solid #000000;\n                  box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n                  border: 0;\n                  width: 15rem;\n                  padding: 0.5rem;\n                  height: 2rem;\n                  margin-bottom: 2rem;\n                  font-family: Candara;\n                }\n                .login-button {\n                  background-color: white;\n                  border-radius: 14px 0px 14px 1px;\n                  -moz-border-radius: 14px 0px 14px 1px;\n                  -webkit-border-radius: 14px 0px 14px 1px;\n                  border: 0px solid #000000;\n                  box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n                  width: 15rem;\n                  font-size: 0.9rem;\n                  padding: 0.5rem;\n                  height: 3rem;\n                  margin: 2rem;\n                  font-family: Candara;\n                  transition: transform 0.2s;\n                  cursor: pointer;\n                }\n                .login-button:hover {\n                  transform: scale(1.1);\n                  background: #355c7d;\n                  background: -webkit-linear-gradient(\n                    to right,\n                    #c06c84,\n                    #6c5b7b,\n                    #355c7d\n                  );\n                  background: linear-gradient(\n                    to right,\n                    #c06c84,\n                    #6c5b7b,\n                    #355c7d\n                  );\n                  color: white;\n                }\n                @media only screen and (max-width: 740px) {\n                  form {\n                    border-left: none;\n                    border-top: 1px solid white;\n                  }\n                }\n                input:focus {\n                  outline: none;\n                }\n              `}\n            </style>\n          </form>\n        )}\n      </ApolloConsumer>\n    );\n  }\n}\n\nexport default Login;\n"
  },
  {
    "path": "nextjs-app/src/config/index.ts",
    "content": "/**\n * Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nexport const SERVER = 'http://localhost:4020/graphql';\nexport const WEB_SOCKET_LINK = 'ws://localhost:4020/graphql';\n"
  },
  {
    "path": "nextjs-app/src/configureClient.ts",
    "content": "/**\n * Apollo Client Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { ApolloClient } from 'apollo-client';\nimport { split, ApolloLink, concat } from 'apollo-link';\nimport { InMemoryCache } from 'apollo-cache-inmemory';\nimport { getMainDefinition } from 'apollo-utilities';\nimport withApollo from 'next-with-apollo';\nimport { HttpLink } from 'apollo-link-http';\nimport fetch from 'isomorphic-unfetch';\nimport { WebSocketLink } from 'apollo-link-ws';\nimport Cookies from 'js-cookie';\nimport { SERVER, WEB_SOCKET_LINK } from './config';\n\ninterface Definintion {\n  kind: string;\n  operation?: string;\n}\n\nlet authToken = null;\n\nconst httpLink = new HttpLink({\n  fetch,\n  uri: SERVER,\n});\n\nconst authMiddleware = new ApolloLink((operation, forward) => {\n  operation.setContext({\n    headers: {\n      authorization: authToken || null,\n    },\n  });\n  // Add onto payload for WebSocket authentication\n  (operation as any & { authToken: string | undefined }).authToken = authToken;\n\n  return forward(operation);\n});\n\nconst webSocketLink: any = process.browser\n  ? new WebSocketLink({\n      uri: WEB_SOCKET_LINK,\n      options: {\n        reconnect: true,\n      },\n    })\n  : null;\n\n/**\n * Set Token\n * @param token\n */\nexport const setToken = async (token: string) => {\n  try {\n    authToken = token ? `Bearer ${token}` : null;\n    Cookies.set('token', authToken, { expires: 7 });\n  } catch (error) {\n    console.log(error);\n  }\n};\n\n/**\n * Set Token In Request\n * @param token\n */\nexport const setTokenInRequest = async (token: string) => {\n  try {\n    authToken = token ? token : null;\n    return authToken;\n  } catch (error) {\n    console.log(error);\n  }\n};\n\n/**\n * Destroy Token\n * For logout purpose\n */\nexport const destroyToken = async () => {\n  try {\n    Cookies.remove('token');\n    authToken = null;\n  } catch (error) {\n    console.log(error);\n  }\n};\n\nconst link = process.browser\n  ? split(\n      ({ query }) => {\n        const { kind, operation }: Definintion = getMainDefinition(query);\n        return kind === 'OperationDefinition' && operation === 'subscription';\n      },\n      webSocketLink,\n      httpLink\n    )\n  : httpLink;\n\nexport default withApollo(\n  ({ initialState }) =>\n    new ApolloClient({\n      link: concat(authMiddleware, link),\n      cache: new InMemoryCache().restore(initialState || {}),\n    })\n);\n"
  },
  {
    "path": "nextjs-app/src/graphql/mutation/createUser.ts",
    "content": "/**\n * Create User Mutation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst CREATE_USER = gql`\n  mutation createUser($userInput: UserInput) {\n    createUser(userInput: $userInput) {\n      token\n      userId\n    }\n  }\n`;\n\nexport default CREATE_USER;\n"
  },
  {
    "path": "nextjs-app/src/graphql/mutation/updateUser.ts",
    "content": "/**\n * Update user mutation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst UPDATE_USER = gql`\n  mutation updateUser($userId: ID!, $updateUser: UpdateUser) {\n    updateUser(userId: $userId, updateUser: $updateUser) {\n      _id\n      name\n      email\n    }\n  }\n`;\n\nexport default UPDATE_USER;\n"
  },
  {
    "path": "nextjs-app/src/graphql/query/login.ts",
    "content": "/**\n * Login user query\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst LOGIN_USER = gql`\n  query login($email: String!, $password: String!) {\n    login(email: $email, password: $password) {\n      token\n      userId\n    }\n  }\n`;\n\nexport default LOGIN_USER;\n"
  },
  {
    "path": "nextjs-app/src/graphql/query/user.ts",
    "content": "/**\n * Get all users query\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst GET_USERS = gql`\n  {\n    users {\n      name\n      _id\n      email\n    }\n  }\n`;\n\nexport default GET_USERS;\n"
  },
  {
    "path": "nextjs-app/src/graphql/subscription/users.ts",
    "content": "/**\n * New user added subscription\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst USER_ADDED = gql`\n  subscription {\n    userAdded {\n      name\n      _id\n      email\n    }\n  }\n`;\n\nexport default USER_ADDED;\n"
  },
  {
    "path": "nextjs-app/src/utils/auth.tsx",
    "content": "/**\n * Auth Middlerware Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport * as React from 'react';\nimport Router from 'next/router';\nimport nextCookie from 'next-cookies';\nimport { setTokenInRequest } from '../configureClient';\n\nconst getDisplayName = Component =>\n  Component.displayName || Component.name || 'Component';\n\nexport const auth = ctx => {\n  const { token, userId } = nextCookie(ctx);\n\n  if (ctx.req && !token) {\n    ctx.res.writeHead(302, { Location: '/' });\n    ctx.res.end();\n    return;\n  }\n\n  if (!token) {\n    Router.push('/');\n  }\n\n  return { token, userId };\n};\n\nexport const withAuthSync = WrappedComponent =>\n  class extends React.Component {\n    static displayName = `withAuthSync(${getDisplayName(WrappedComponent)})`;\n\n    static async getInitialProps(ctx) {\n      const { token, userId } = auth(ctx);\n      await setTokenInRequest(token);\n      const componentProps =\n        WrappedComponent.getInitialProps &&\n        (await WrappedComponent.getInitialProps(ctx));\n\n      return { ...componentProps, token, userId };\n    }\n\n    render() {\n      return <WrappedComponent {...this.props} />;\n    }\n  };\n"
  },
  {
    "path": "nextjs-app/src/utils/validation.ts",
    "content": "/**\n * Email Validation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nconst validateEmail = (email: string): boolean => {\n  if (/^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$/.test(email)) {\n    return true;\n  }\n  return false;\n};\n\nexport { validateEmail };\n"
  },
  {
    "path": "nextjs-app/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es6\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": false,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"preserve\"\n  },\n  \"exclude\": [\n    \"node_modules\"\n  ],\n  \"include\": [\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\"\n  ]\n}"
  },
  {
    "path": "react-app/.eslintrc.js",
    "content": "module.exports = {\n  parser: '@typescript-eslint/parser',\n  extends: [\n    'plugin:@typescript-eslint/recommended',\n    'prettier/@typescript-eslint',\n    'react-app',\n    'plugin:prettier/recommended',\n  ],\n  plugins: ['@typescript-eslint', 'react'],\n  rules: {\n    '@typescript-eslint/explicit-function-return-type': 0,\n    '@typescript-eslint/no-explicit-any': 0,\n  },\n};\n"
  },
  {
    "path": "react-app/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "react-app/.prettierrc.js",
    "content": "module.exports = {\n  useTabs: false,\n  printWidth: 80,\n  singleQuote: true,\n  trailingComma: 'es5',\n  jsxBracketSameLine: true,\n  noSemi: false,\n};\n"
  },
  {
    "path": "react-app/package.json",
    "content": "{\n  \"name\": \"react-app\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"author\": \"Anurag Garg\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"@apollo/react-components\": \"^3.1.3\",\n    \"@apollo/react-hooks\": \"^3.1.3\",\n    \"@testing-library/jest-dom\": \"^4.2.4\",\n    \"@testing-library/react\": \"^9.3.2\",\n    \"@testing-library/user-event\": \"^7.1.2\",\n    \"@types/jest\": \"^24.0.0\",\n    \"@types/node\": \"^12.0.0\",\n    \"@types/react\": \"^16.9.0\",\n    \"@types/react-dom\": \"^16.9.0\",\n    \"apollo-cache-inmemory\": \"^1.6.5\",\n    \"apollo-client\": \"^2.6.8\",\n    \"apollo-link-batch-http\": \"^1.2.13\",\n    \"apollo-link-http\": \"^1.5.16\",\n    \"apollo-link-ws\": \"^1.0.19\",\n    \"graphql\": \"^14.5.8\",\n    \"graphql-tag\": \"^2.10.1\",\n    \"isomorphic-unfetch\": \"^3.0.0\",\n    \"js-cookie\": \"^2.2.1\",\n    \"node-sass\": \"^4.13.1\",\n    \"react\": \"^16.12.0\",\n    \"react-apollo\": \"^3.1.3\",\n    \"react-dom\": \"^16.12.0\",\n    \"react-router-dom\": \"^5.1.2\",\n    \"react-scripts\": \"3.3.0\",\n    \"react-toastify\": \"^5.5.0\",\n    \"subscriptions-transport-ws\": \"^0.9.16\",\n    \"typescript\": \"~3.7.2\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test\",\n    \"eject\": \"react-scripts eject\",\n    \"lint\": \"eslint './**/*.{ts,js,tsx}'\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"./**/*.{js,jsx,ts,tsx,css}\": [\n      \"prettier --write\",\n      \"yarn lint\"\n    ]\n  },\n  \"browserslist\": {\n    \"production\": [\n      \">0.2%\",\n      \"not dead\",\n      \"not op_mini all\"\n    ],\n    \"development\": [\n      \"last 1 chrome version\",\n      \"last 1 firefox version\",\n      \"last 1 safari version\"\n    ]\n  },\n  \"devDependencies\": {\n    \"@types/js-cookie\": \"^2.2.4\",\n    \"@types/react-router-dom\": \"^5.1.3\",\n    \"@typescript-eslint/eslint-plugin\": \"^2.16.0\",\n    \"@typescript-eslint/parser\": \"^2.16.0\",\n    \"babel-eslint\": \"^10.0.3\",\n    \"eslint\": \"^6.8.0\",\n    \"eslint-config-prettier\": \"^6.9.0\",\n    \"eslint-config-react-app\": \"^5.1.0\",\n    \"eslint-plugin-flowtype\": \"^4\",\n    \"eslint-plugin-import\": \"^2.20.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.2.3\",\n    \"eslint-plugin-prettier\": \"^3.1.2\",\n    \"eslint-plugin-react\": \"^7.18.0\",\n    \"eslint-plugin-react-hooks\": \"^2.3.0\",\n    \"husky\": \"^4.2.0\",\n    \"lint-staged\": \"^10.0.2\",\n    \"prettier\": \"^1.19.1\"\n  }\n}\n"
  },
  {
    "path": "react-app/public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <link rel=\"icon\" href=\"%PUBLIC_URL%/favicon.ico\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n    <meta name=\"theme-color\" content=\"#000000\" />\n    <meta\n      name=\"description\"\n      content=\"Web site created using create-react-app\"\n    />\n    <link rel=\"apple-touch-icon\" href=\"%PUBLIC_URL%/logo192.png\" />\n    <!--\n      manifest.json provides metadata used when your web app is installed on a\n      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/\n    -->\n    <link rel=\"manifest\" href=\"%PUBLIC_URL%/manifest.json\" />\n    <!--\n      Notice the use of %PUBLIC_URL% in the tags above.\n      It will be replaced with the URL of the `public` folder during the build.\n      Only files inside the `public` folder can be referenced from the HTML.\n\n      Unlike \"/favicon.ico\" or \"favicon.ico\", \"%PUBLIC_URL%/favicon.ico\" will\n      work correctly both with client-side routing and a non-root public URL.\n      Learn how to configure a non-root public URL by running `npm run build`.\n    -->\n    <title>React App</title>\n  </head>\n  <body>\n    <noscript>You need to enable JavaScript to run this app.</noscript>\n    <div id=\"root\"></div>\n    <!--\n      This HTML file is a template.\n      If you open it directly in the browser, you will see an empty page.\n\n      You can add webfonts, meta tags, or analytics to this file.\n      The build step will place the bundled scripts into the <body> tag.\n\n      To begin the development, run `npm start` or `yarn start`.\n      To create a production bundle, use `npm run build` or `yarn build`.\n    -->\n  </body>\n</html>\n"
  },
  {
    "path": "react-app/public/manifest.json",
    "content": "{\n  \"short_name\": \"React GraphQL Boilerplate App\",\n  \"name\": \"React GraphQL Boilerplate App\",\n  \"icons\": [\n    {\n      \"src\": \"favicon.ico\",\n      \"sizes\": \"64x64 32x32 24x24 16x16\",\n      \"type\": \"image/x-icon\"\n    }\n  ],\n  \"start_url\": \".\",\n  \"display\": \"standalone\",\n  \"theme_color\": \"#000000\",\n  \"background_color\": \"#ffffff\"\n}\n"
  },
  {
    "path": "react-app/src/App.test.tsx",
    "content": "/**\n * Test File\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { render } from '@testing-library/react';\nimport App from './App';\n\ntest('renders welcome heading', () => {\n  const { getByText } = render(<App />);\n  const linkElement = getByText(/Welcome/i);\n  expect(linkElement).toBeInTheDocument();\n});\n"
  },
  {
    "path": "react-app/src/App.tsx",
    "content": "/**\n * App Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { BrowserRouter as Router, Switch, Route } from 'react-router-dom';\nimport { ToastContainer } from 'react-toastify';\nimport 'react-toastify/dist/ReactToastify.css';\nimport { ApolloProvider } from '@apollo/react-hooks';\nimport apolloClient from './configureClient';\nimport PrivateRoute from './utils/auth';\nimport Login from './screens/Login';\nimport SignUp from './screens/SignUp';\nimport Welcome from './screens/Welcome';\nimport Users from './screens/Users';\nimport Update from './screens/Update';\nimport NoMatch from './screens/NoMatch';\nimport Subscription from './screens/Subscription';\n\nconst App = () => {\n  return (\n    <ApolloProvider client={apolloClient}>\n      <Router>\n        <Switch>\n          <Route exact path=\"/\" component={Login} />\n          <Route path=\"/signup\" component={SignUp} />\n          <PrivateRoute path=\"/welcome\" component={Welcome} />\n          <PrivateRoute path=\"/users\" component={Users} />\n          <PrivateRoute path=\"/update\" component={Update} />\n          <PrivateRoute path=\"/subscription\" component={Subscription} />\n          <Route path=\"*\" component={NoMatch} />\n        </Switch>\n      </Router>\n      <ToastContainer\n        position=\"top-right\"\n        autoClose={2000}\n        hideProgressBar={false}\n        newestOnTop={false}\n        closeOnClick\n        rtl={false}\n        draggable\n        pauseOnHover\n      />\n    </ApolloProvider>\n  );\n};\n\nexport default App;\n"
  },
  {
    "path": "react-app/src/components/Card/index.tsx",
    "content": "/**\n * Card Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport './styles.scss';\nimport { Link } from 'react-router-dom';\n\ninterface User {\n  name: string;\n  _id: string;\n  email: string;\n}\n\ninterface CardProps {\n  title: string;\n  href: string;\n}\n\ninterface UserCardProps {\n  user: User;\n  img: string;\n}\n\nconst Card: React.SFC<CardProps> = props => {\n  return (\n    <Link to={props.href} className=\"link\">\n      <div className=\"card\">\n        <h2>{props.title}</h2>\n      </div>\n    </Link>\n  );\n};\n\nexport const UserCard: React.SFC<UserCardProps> = props => {\n  return (\n    <div key={props.user._id} className=\"listCard\">\n      <img src={props.img} alt=\"user\" height=\"90\" />\n      <div className=\"userCardDetails\">\n        <h2>{props.user.name}</h2>\n        <h2>{props.user.email}</h2>\n      </div>\n    </div>\n  );\n};\n\nexport default Card;\n"
  },
  {
    "path": "react-app/src/components/Card/styles.scss",
    "content": ".card {\n    display: flex;\n    height: 5rem;\n    width: 20rem;\n    justify-content: center;\n    padding: 2rem;\n    align-self: stretch;\n    align-items: center;\n    background-color: white;\n    margin: 2rem;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    transition: transform 0.2s;\n    cursor: pointer;\n\n    &:hover {\n        transform: scale(1.1);\n    }\n\n    h2 {\n        font-size: 2rem;\n    }\n}\n\n.listCard {\n    display: flex;\n    flex-flow: wrap row;\n    justify-content: space-between;\n    padding: 2rem;\n    -webkit-align-self: stretch;\n    align-self: stretch;\n    align-items: center;\n    background-color: white;\n    margin: 2rem;\n    width: 20rem;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    transition: transform 0.2s;\n\n    .userCardDetails {\n        display: flex;\n        flex-flow: wrap column;\n        justify-content: space-between;\n        align-items: flex-end;\n        height: 3rem;\n    }\n\n    h2 {\n        font-size: 1rem;\n        text-align: right;\n    }\n\n    img {\n        margin-right: 2rem;\n    }\n}\n\n.link {\n    text-decoration: none;\n    color: black;\n}"
  },
  {
    "path": "react-app/src/components/Footer/index.tsx",
    "content": "/**\n * Footer Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport './styles.scss';\n\nconst Footer: React.SFC<any> = props => {\n  return (\n    <footer className=\"footer\">\n      <div className=\"footer-text-container\">\n        <p>\n          &copy; Copyright 2020{' '}\n          <a href=\"https://twitter.com/AnuragG94634191\">Anurag Garg</a>\n        </p>\n      </div>\n    </footer>\n  );\n};\n\nexport default Footer;\n"
  },
  {
    "path": "react-app/src/components/Footer/styles.scss",
    "content": ".footer {\n    color: rgba(255, 255, 255, 0.5);\n    margin-top: auto !important;\n\n\n    .footer-text-container {\n        font-size: 1rem;\n        font-weight: 400;\n        line-height: 1.5;\n        text-shadow: 0 0.05rem 0.1rem rgba(0, 0, 0, 0.5);\n        text-align: center !important;\n        color: rgba(255, 255, 255, 0.5);\n    }\n\n    a {\n        text-decoration: none;\n        color: white;\n    }\n}"
  },
  {
    "path": "react-app/src/components/List/index.tsx",
    "content": "/**\n * List Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { UserCard } from '../Card';\nimport './styles.scss';\n\ninterface User {\n  name: string;\n  _id: string;\n  email: string;\n}\n\ninterface ListProps {\n  data: [User];\n  img: string;\n}\n\nconst List: React.SFC<ListProps> = props => {\n  return (\n    <>\n      {props.data.map((user: User) => (\n        <UserCard key={user._id} user={user} img={props.img} />\n      ))}\n    </>\n  );\n};\n\nexport default List;\n"
  },
  {
    "path": "react-app/src/components/List/styles.scss",
    "content": ".List {\n    &:hove {\n        transform: scale(1.1);\n    }\n\n    h2 {\n        font-size: 1rem;\n        text-align: right;\n    }\n\n    img {\n        margin-right: 2rem;\n    }\n}"
  },
  {
    "path": "react-app/src/components/LoginForm/index.tsx",
    "content": "/**\n * Login Form Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { toast } from 'react-toastify';\nimport { ApolloConsumer } from 'react-apollo';\nimport LOGIN_USER from '../../graphql/query/login';\nimport { validateEmail } from '../../utils/validation';\nimport { setToken } from '../../configureClient';\nimport { Link } from 'react-router-dom';\nimport Cookies from 'js-cookie';\nimport './styles.scss';\n\ninterface LoginFormState {\n  [key: string]: any;\n  email: string;\n  password: string;\n}\n\nclass LoginForm extends React.PureComponent<any, LoginFormState> {\n  constructor(props: any) {\n    super(props);\n    this.state = {\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (event: any, client: any) => {\n    try {\n      event.preventDefault();\n      const { state, props } = this;\n      if (validateEmail(state.email)) {\n        const { data } = await client.query({\n          query: LOGIN_USER,\n          variables: { ...state },\n        });\n        const { token, userId } = data.login;\n        setToken(token);\n        Cookies.set('userId', userId, { expires: 7 });\n        props.history.replace('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Not Authenticated');\n    }\n  };\n\n  render() {\n    const { state } = this;\n    return (\n      <ApolloConsumer>\n        {client => (\n          <form\n            onSubmit={e => this.handleSubmit(e, client)}\n            className=\"login-form\">\n            <input\n              type=\"text\"\n              placeholder=\"Email\"\n              name=\"email\"\n              value={state.email}\n              onChange={this.handleChange}\n              className=\"login-input-box\"\n              required\n            />\n            <input\n              type=\"password\"\n              placeholder=\"Password\"\n              name=\"password\"\n              value={state.password}\n              onChange={this.handleChange}\n              className=\"login-input-box\"\n              required\n            />\n            <input type=\"submit\" value=\"Submit\" className=\"login-button\" />\n            <Link to=\"/signup\" className=\"signup-link\">\n              <p>\n                New user ? <b>Sign Up</b>\n              </p>\n            </Link>\n          </form>\n        )}\n      </ApolloConsumer>\n    );\n  }\n}\n\nexport default LoginForm;\n"
  },
  {
    "path": "react-app/src/components/LoginForm/styles.scss",
    "content": ".login-form {\n    display: flex;\n    flex-flow: column wrap;\n    justify-content: center;\n    align-items: center;\n    border-left: 1px solid white;\n    padding: 2rem;\n\n    p {\n        color: white;\n        cursor: pointer;\n    }\n}\n\n\n.login-input-box {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    border: 0;\n    width: 15rem;\n    padding: 0.5rem;\n    height: 2rem;\n    margin-bottom: 2rem;\n    font-family: Candara;\n}\n\n.login-button {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    width: 15rem;\n    font-size: 0.9rem;\n    padding: 0.5rem;\n    height: 3rem;\n    margin: 2rem;\n    font-family: Candara;\n    transition: transform 0.2s;\n    cursor: pointer;\n}\n\n.login-button:hover {\n    transform: scale(1.1);\n    background: #355c7d;\n    background: -webkit-linear-gradient(to right,\n            #c06c84,\n            #6c5b7b,\n            #355c7d);\n    background: linear-gradient(to right,\n            #c06c84,\n            #6c5b7b,\n            #355c7d);\n    color: white;\n}\n\n.signup-link {\n    text-decoration: none;\n}\n\n@media only screen and (max-width: 740px) {\n    .login-form {\n        border-left: none;\n        border-top: 1px solid white;\n    }\n}\n\ninput:focus {\n    outline: none;\n}"
  },
  {
    "path": "react-app/src/config/index.ts",
    "content": "/**\n * Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nexport const SERVER = 'http://localhost:4020/graphql';\nexport const WEB_SOCKET_LINK = 'ws://localhost:4020/graphql';\n"
  },
  {
    "path": "react-app/src/configureClient.ts",
    "content": "/**\n * Apollo Client Configuration\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport { ApolloClient } from 'apollo-client';\nimport { split, ApolloLink, concat } from 'apollo-link';\nimport { InMemoryCache } from 'apollo-cache-inmemory';\nimport { getMainDefinition } from 'apollo-utilities';\nimport { HttpLink } from 'apollo-link-http';\nimport fetch from 'isomorphic-unfetch';\nimport { WebSocketLink } from 'apollo-link-ws';\nimport Cookies from 'js-cookie';\nimport { SERVER, WEB_SOCKET_LINK } from './config';\n\ninterface Definintion {\n  kind: string;\n  operation?: string;\n}\n\nlet authToken = '';\n\nconst httpLink = new HttpLink({\n  fetch,\n  uri: SERVER,\n});\n\nconst authMiddleware = new ApolloLink((operation, forward) => {\n  operation.setContext({\n    headers: {\n      authorization: authToken || null,\n    },\n  });\n  // Add onto payload for WebSocket authentication\n  (operation as any & { authToken: string | undefined }).authToken = authToken;\n\n  return forward(operation);\n});\n\nconst webSocketLink: WebSocketLink = new WebSocketLink({\n  uri: WEB_SOCKET_LINK,\n  options: {\n    reconnect: true,\n  },\n});\n\n/**\n * Set Token\n * @param token\n */\nexport const setToken = async (token: string | undefined) => {\n  try {\n    authToken = token ? `Bearer ${token}` : '';\n    Cookies.set('token', authToken, { expires: 7 });\n  } catch (error) {\n    console.log(error);\n  }\n};\n\n/**\n * Get Token & Set Token In Request\n */\nexport const getToken = async () => {\n  try {\n    const token = Cookies.get('token');\n    authToken = token ? token : '';\n    return authToken;\n  } catch (error) {\n    console.log(error);\n  }\n};\n\n/**\n * Destroy Token\n * For logout purpose\n */\nexport const destroyToken = async () => {\n  try {\n    Cookies.remove('token');\n    authToken = '';\n  } catch (error) {\n    console.log(error);\n  }\n};\n\nconst link = split(\n  ({ query }) => {\n    const { kind, operation }: Definintion = getMainDefinition(query);\n    return kind === 'OperationDefinition' && operation === 'subscription';\n  },\n  webSocketLink,\n  httpLink\n);\n\nconst client = new ApolloClient({\n  link: concat(authMiddleware, link),\n  cache: new InMemoryCache().restore({}),\n  connectToDevTools: true,\n});\n\nexport default client;\n"
  },
  {
    "path": "react-app/src/graphql/mutation/createUser.ts",
    "content": "/**\n * Create User Mutation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst CREATE_USER = gql`\n  mutation createUser($userInput: UserInput) {\n    createUser(userInput: $userInput) {\n      token\n      userId\n    }\n  }\n`;\n\nexport default CREATE_USER;\n"
  },
  {
    "path": "react-app/src/graphql/mutation/updateUser.ts",
    "content": "/**\n * Update user mutation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst UPDATE_USER = gql`\n  mutation updateUser($userId: ID!, $updateUser: UpdateUser) {\n    updateUser(userId: $userId, updateUser: $updateUser) {\n      _id\n      name\n      email\n    }\n  }\n`;\n\nexport default UPDATE_USER;\n"
  },
  {
    "path": "react-app/src/graphql/query/login.ts",
    "content": "/**\n * Login user query\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst LOGIN_USER = gql`\n  query login($email: String!, $password: String!) {\n    login(email: $email, password: $password) {\n      token\n      userId\n    }\n  }\n`;\n\nexport default LOGIN_USER;\n"
  },
  {
    "path": "react-app/src/graphql/query/user.ts",
    "content": "/**\n * Get all users query\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst GET_USERS = gql`\n  {\n    users {\n      name\n      _id\n      email\n    }\n  }\n`;\n\nexport default GET_USERS;\n"
  },
  {
    "path": "react-app/src/graphql/subscription/users.ts",
    "content": "/**\n * New user added subscription\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport gql from 'graphql-tag';\n\nconst USER_ADDED = gql`\n  subscription {\n    userAdded {\n      name\n      _id\n      email\n    }\n  }\n`;\n\nexport default USER_ADDED;\n"
  },
  {
    "path": "react-app/src/index.css",
    "content": "h1,\nh2 {\n  margin: 0;\n  font-family: Candara;\n}\nbody {\n  margin: 0;\n  padding: 0;\n  height: 100%;\n  min-height: 100vh;\n  font-family: Candara;\n  background: #355c7d;\n  background: -webkit-linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n  background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n}\n"
  },
  {
    "path": "react-app/src/index.tsx",
    "content": "/**\n * Primary file for react\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\n\nReactDOM.render(<App />, document.getElementById('root'));\n"
  },
  {
    "path": "react-app/src/react-app-env.d.ts",
    "content": "/// <reference types=\"react-scripts\" />\n"
  },
  {
    "path": "react-app/src/screens/Login/index.tsx",
    "content": "/**\n * Main Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport LoginForm from '../../components/LoginForm';\nimport Footer from '../../components/Footer';\nimport './styles.scss';\n\nconst Login: React.SFC = (props: any) => {\n  return (\n    <div className=\"loginPage-mainContainer\">\n      <div className=\"loginPage-container\">\n        <h1 className=\"heading\">Welcome</h1>\n        <LoginForm {...props} />\n      </div>\n      <Footer />\n    </div>\n  );\n};\n\nexport default Login;\n"
  },
  {
    "path": "react-app/src/screens/Login/styles.scss",
    "content": ".loginPage-mainContainer {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n\n    .loginPage-container {\n        display: flex;\n        justify-content: center;\n        align-items: center;\n        flex-flow: row wrap;\n        padding: 8rem 0rem !important;\n    }\n\n    .heading {\n        color: white;\n        text-align: center;\n        font-size: 5rem;\n        padding: 2rem;\n    }\n\n    @media only screen and (max-width: 740px) {\n        .loginPage-container {\n            padding: 3rem 0rem !important;\n        }\n    }\n}"
  },
  {
    "path": "react-app/src/screens/NoMatch/index.tsx",
    "content": "/**\n * No Match Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Footer from '../../components/Footer';\nimport './styles.scss';\n\nconst NoMatch: React.SFC = () => {\n  return (\n    <div className=\"nomatch-container\">\n      <h1 className=\"nomatch-heading\">No Match Found | 404</h1>\n      <Footer />\n    </div>\n  );\n};\n\nexport default NoMatch;\n"
  },
  {
    "path": "react-app/src/screens/NoMatch/styles.scss",
    "content": ".nomatch-container {\n  height: 100%;\n  min-height: 100vh;\n  width: 100%;\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  flex-flow: column wrap;\n}\n\n.nomatch-heading {\n  color: white;\n  text-align: center;\n  font-size: 5rem;\n  padding: 5rem 0rem;\n}"
  },
  {
    "path": "react-app/src/screens/SignUp/index.tsx",
    "content": "/**\n * SignUp Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { toast } from 'react-toastify';\nimport Footer from '../../components/Footer';\nimport Cookies from 'js-cookie';\nimport { Mutation } from '@apollo/react-components';\nimport CREATE_USER from '../../graphql/mutation/createUser';\nimport { setToken } from '../../configureClient';\nimport { validateEmail } from '../../utils/validation';\nimport './styles.scss';\n\ninterface SignUpState {\n  [key: string]: any;\n  name: string;\n  email: string;\n  password: string;\n}\n\nclass SignUp extends React.PureComponent<any, SignUpState> {\n  constructor(props: any) {\n    super(props);\n    this.state = {\n      name: '',\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (createUser: any, event: any) => {\n    try {\n      event.preventDefault();\n      const { state, props } = this;\n      if (validateEmail(state.email)) {\n        const data = await createUser({\n          variables: {\n            userInput: { ...state },\n          },\n        });\n        const { token, userId } = data.createUser;\n        setToken(token);\n        Cookies.set('userId', userId, { expires: 7 });\n        props.history.replace('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Check your connection');\n    }\n  };\n  render() {\n    const { state } = this;\n    return (\n      <div className=\"signup-container\">\n        <h1 className=\"signup-heading\">Sign Up</h1>\n        <Mutation mutation={CREATE_USER}>\n          {(createUser: any) => (\n            <form\n              onSubmit={event => this.handleSubmit(createUser, event)}\n              className=\"signup-form\">\n              <input\n                type=\"text\"\n                placeholder=\"Name\"\n                name=\"name\"\n                value={state.name}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input\n                type=\"text\"\n                placeholder=\"Email\"\n                name=\"email\"\n                value={state.email}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input\n                type=\"password\"\n                placeholder=\"Password\"\n                name=\"password\"\n                value={state.password}\n                onChange={this.handleChange}\n                className=\"signup-input-box\"\n                required\n              />\n              <input type=\"submit\" value=\"Submit\" className=\"signup-button\" />\n            </form>\n          )}\n        </Mutation>\n        <Footer />\n      </div>\n    );\n  }\n}\n\nexport default SignUp;\n"
  },
  {
    "path": "react-app/src/screens/SignUp/styles.scss",
    "content": ".signup-container {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-flow: column wrap;\n}\n\n.signup-heading {\n    color: white;\n    text-align: center;\n    font-size: 5rem;\n    padding: 5rem 0rem;\n}\n\n.signup-form {\n    display: flex;\n    flex-flow: column wrap;\n    justify-content: center;\n    align-items: center;\n}\n\n.signup-input-box {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    border: 0;\n    width: 15rem;\n    padding: 0.5rem;\n    height: 2rem;\n    margin-bottom: 2rem;\n    font-family: Candara;\n}\n\n.signup-button {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    width: 15rem;\n    font-size: 0.9rem;\n    padding: 0.5rem;\n    height: 3rem;\n    margin: 2rem;\n    font-family: Candara;\n    transition: transform 0.2s;\n    cursor: pointer;\n\n    &:hover {\n        transform: scale(1.1);\n        background: #355c7d;\n        background: -webkit-linear-gradient(to right,\n                #c06c84,\n                #6c5b7b,\n                #355c7d);\n        background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n        color: white;\n    }\n}\n\ninput:focus {\n    outline: none;\n}"
  },
  {
    "path": "react-app/src/screens/Subscription/index.tsx",
    "content": "/**\n * Subscription Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { useSubscription } from '@apollo/react-hooks';\nimport { UserCard } from '../../components/Card';\nimport USER_ADDED from '../../graphql/subscription/users';\nimport './styles.scss';\n\nconst Subscription = () => {\n  const { data, loading, error } = useSubscription(USER_ADDED);\n  let message = 'New User';\n  if (loading) message = 'Listening...';\n  if (error) message = `Error! ${error.message}`;\n  if (data && data.userAdded.length <= 0) message = 'No New User Added';\n  return (\n    <div className=\"subscription-container\">\n      <h1 className=\"subscription-heading\">{message}</h1>\n      {data && data.userAdded && (\n        <div className=\"subscription-listContainer\">\n          <UserCard img=\"./user.png\" user={data.userAdded} />\n        </div>\n      )}\n    </div>\n  );\n};\n\nexport default Subscription;\n"
  },
  {
    "path": "react-app/src/screens/Subscription/styles.scss",
    "content": ".subscription-container {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-flow: column wrap;\n}\n\n.subscription-listContainer {\n    display: flex;\n    flex-flow: wrap row;\n    justify-content: space-evenly;\n    align-items: center;\n}\n\n.subscription-heading {\n    color: white;\n    text-align: center;\n    font-size: 5rem;\n    padding: 0rem 0 5rem;\n}"
  },
  {
    "path": "react-app/src/screens/Update/index.tsx",
    "content": "/**\n * Update Profile Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport { toast } from 'react-toastify';\nimport Footer from '../../components/Footer';\nimport { Mutation } from '@apollo/react-components';\nimport { validateEmail } from '../../utils/validation';\nimport UPDATE_USER from '../../graphql/mutation/updateUser';\nimport './styles.scss';\n\ninterface UpdateState {\n  [key: string]: any;\n  name: string;\n  email: string;\n  password: string;\n}\n\nclass Update extends React.PureComponent<any, UpdateState> {\n  constructor(props: any) {\n    super(props);\n    this.state = {\n      name: '',\n      email: '',\n      password: '',\n    };\n  }\n\n  handleChange = (event: any) => {\n    this.setState({ [event.target.name]: event.target.value });\n  };\n\n  handleSubmit = async (updateUser: any, event: any) => {\n    try {\n      event.preventDefault();\n      const { state, props } = this;\n      if (validateEmail(state.email)) {\n        await updateUser({\n          variables: {\n            userId: props.userId,\n            updateUser: { ...state },\n          },\n        });\n        toast.success('Profile Updated');\n        props.history.push('/welcome');\n      } else {\n        toast.error('Invalid Email');\n      }\n    } catch (error) {\n      toast.error('Check your connection');\n    }\n  };\n  render() {\n    const { state } = this;\n    return (\n      <div className=\"update-container\">\n        <h1 className=\"update-heading\">Update Profile</h1>\n        <Mutation mutation={UPDATE_USER}>\n          {(updateUser: any) => (\n            <form\n              onSubmit={event => this.handleSubmit(updateUser, event)}\n              className=\"update-form\">\n              <input\n                type=\"text\"\n                placeholder=\"Name\"\n                name=\"name\"\n                value={state.name}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input\n                type=\"text\"\n                placeholder=\"Email\"\n                name=\"email\"\n                value={state.email}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input\n                type=\"password\"\n                placeholder=\"Password\"\n                name=\"password\"\n                value={state.password}\n                onChange={this.handleChange}\n                className=\"update-input-box\"\n                required\n              />\n              <input type=\"submit\" value=\"Submit\" className=\"update-button\" />\n            </form>\n          )}\n        </Mutation>\n        <Footer />\n      </div>\n    );\n  }\n}\n\nexport default Update;\n"
  },
  {
    "path": "react-app/src/screens/Update/styles.scss",
    "content": ".update-container {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-flow: column wrap;\n}\n\n.update-heading {\n    color: white;\n    text-align: center;\n    font-size: 5rem;\n    padding: 5rem 0rem;\n}\n\n.update-form {\n    display: flex;\n    flex-flow: column wrap;\n    justify-content: center;\n    align-items: center;\n}\n\n.update-input-box {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    border: 0;\n    width: 15rem;\n    padding: 0.5rem;\n    height: 2rem;\n    margin-bottom: 2rem;\n    font-family: Candara;\n}\n\n.update-button {\n    background-color: white;\n    border-radius: 14px 0px 14px 1px;\n    -moz-border-radius: 14px 0px 14px 1px;\n    -webkit-border-radius: 14px 0px 14px 1px;\n    border: 0px solid #000000;\n    box-shadow: 0 20px 30px -16px rgba(9, 9, 16, 0.2);\n    width: 15rem;\n    font-size: 0.9rem;\n    padding: 0.5rem;\n    height: 3rem;\n    margin: 2rem;\n    font-family: Candara;\n    transition: transform 0.2s;\n    cursor: pointer;\n}\n\n.update-button:hover {\n    transform: scale(1.1);\n    background: #355c7d;\n    background: -webkit-linear-gradient(to right,\n            #c06c84,\n            #6c5b7b,\n            #355c7d);\n    background: linear-gradient(to right, #c06c84, #6c5b7b, #355c7d);\n    color: white;\n}\n\ninput:focus {\n    outline: none;\n}"
  },
  {
    "path": "react-app/src/screens/Users/index.tsx",
    "content": "/**\n * User List Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport List from '../../components/List';\nimport { useQuery } from '@apollo/react-hooks';\nimport GET_USERS from '../../graphql/query/user';\nimport './styles.scss';\n\nconst Users = () => {\n  const { loading, error, data } = useQuery(GET_USERS);\n  let message = 'Users';\n  if (loading) message = 'Loading...';\n  if (error) message = `Error! ${error}`;\n  if (data && data.users.length <= 0) message = 'No Users';\n  return (\n    <div className=\"users-container\">\n      <h1 className=\"users-heading\">{message}</h1>\n      {data && data.users.length > 0 && (\n        <div className=\"users-listContainer\">\n          <List img=\"./user.png\" data={data.users} />\n        </div>\n      )}\n    </div>\n  );\n};\n\nexport default Users;\n"
  },
  {
    "path": "react-app/src/screens/Users/styles.scss",
    "content": ".users-container {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-flow: column wrap;\n}\n\n.users-listContainer {\n    display: flex;\n    flex-flow: wrap row;\n    justify-content: space-evenly;\n    align-items: center;\n}\n\n.users-heading {\n    color: white;\n    text-align: center;\n    font-size: 5rem;\n    padding: 0rem 0 5rem;\n}"
  },
  {
    "path": "react-app/src/screens/Welcome/index.tsx",
    "content": "/**\n * Welcome Page\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport React from 'react';\nimport Card from '../../components/Card';\nimport Footer from '../../components/Footer';\nimport './styles.scss';\n\nconst Welcome: React.SFC = () => {\n  return (\n    <div className=\"welcome-container\">\n      <h1 className=\"welcome-heading\">Welcome</h1>\n      <div className=\"welcome-cardContainer\">\n        <Card title=\"Query\" href=\"/users\" />\n        <Card title=\"Mutation\" href=\"/update\" />\n        <Card title=\"Subscription\" href=\"/subscription\" />\n      </div>\n      <Footer />\n    </div>\n  );\n};\n\nexport default Welcome;\n"
  },
  {
    "path": "react-app/src/screens/Welcome/styles.scss",
    "content": ".welcome-container {\n    height: 100%;\n    min-height: 100vh;\n    width: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    flex-flow: column wrap;\n}\n\n.welcome-cardContainer {\n    display: flex;\n    flex-flow: wrap row;\n    justify-content: center;\n    align-items: center;\n}\n\n.welcome-heading {\n    color: white;\n    text-align: center;\n    font-size: 5rem;\n    padding: 6rem 0rem;\n}"
  },
  {
    "path": "react-app/src/setupTests.ts",
    "content": "// jest-dom adds custom jest matchers for asserting on DOM nodes.\n// allows you to do things like:\n// expect(element).toHaveTextContent(/react/i)\n// learn more: https://github.com/testing-library/jest-dom\nimport '@testing-library/jest-dom/extend-expect';\n"
  },
  {
    "path": "react-app/src/utils/auth.tsx",
    "content": "/**\n * Auth Middlerware Component\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nimport * as React from 'react';\nimport { setToken } from '../configureClient';\nimport Cookies from 'js-cookie';\nimport { Route, Redirect } from 'react-router-dom';\n\nconst PrivateRoute = ({ children, ...rest }: any) => {\n  const token = Cookies.get('token');\n  setToken(token);\n  if (!token) {\n    return <Redirect to=\"/\" />;\n  }\n  return (\n    <Route\n      {...rest}\n      render={({ location }: any) =>\n        token ? (\n          children\n        ) : (\n          <Redirect\n            to={{\n              pathname: '/',\n              state: { from: location },\n            }}\n          />\n        )\n      }\n    />\n  );\n};\n\nexport default PrivateRoute;\n"
  },
  {
    "path": "react-app/src/utils/validation.ts",
    "content": "/* eslint-disable no-useless-escape */\n/**\n * Email Validation\n * @author Anurag Garg <garganurag893@gmail.com>\n */\n\nconst validateEmail = (email: string): boolean => {\n  if (/^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$/.test(email)) {\n    return true;\n  }\n  return false;\n};\n\nexport { validateEmail };\n"
  },
  {
    "path": "react-app/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react\"\n  },\n  \"include\": [\n    \"src\"\n  ]\n}\n"
  }
]